From 57eec94c42745492389490482520d0c093b725f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Su=C3=A1rez?= Date: Fri, 28 Jul 2023 09:32:30 -0600 Subject: [PATCH 001/157] Add OS, server and interval. --- pandora_server/util/pandora_manage.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 71fd0db43e..2b0f20f244 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -4508,7 +4508,9 @@ sub cli_create_event() { # exist_check($id_agent,'agent',$agent_name); if($id_agent == -1){ if($force_create_agent == 1){ - pandora_create_agent ($conf, '', $agent_name, '', $id_group, '', '', 'Created by cli_create_event', '', $dbh); + my $target_os = pandora_get_os($dbh, 'other'); + my $target_server = $conf{'servername'}; + pandora_create_agent ($conf, $target_server, $agent_name, '', $id_group, '', $target_os, 'Created by cli_create_event', '300', $dbh); print_log "[INFO] Adding agent '$agent_name' \n\n"; $id_agent = get_agent_id($dbh,$agent_name); } From a0b02670fb4028a5a6752463a5aceb4fa37b23ee Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Thu, 31 Aug 2023 10:45:27 +0200 Subject: [PATCH 002/157] #11954 Fix pagination --- pandora_console/godmode/agentes/fields_manager.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/fields_manager.php b/pandora_console/godmode/agentes/fields_manager.php index 25b06e2f5a..53b4995d20 100644 --- a/pandora_console/godmode/agentes/fields_manager.php +++ b/pandora_console/godmode/agentes/fields_manager.php @@ -217,6 +217,7 @@ foreach ($fields as $field) { array_push($table->data, $data); } +$tablePagination = ''; if ($fields) { html_print_table($table); $tablePagination = ui_pagination($count_fields, false, $offset, 0, true, 'offset', false); @@ -231,6 +232,9 @@ html_print_action_buttons( [ 'icon' => 'next' ], true ), - ['type' => 'form_action'] + [ + 'type' => 'form_action', + 'right_content' => $tablePagination, + ], ); echo ''; From eab6a00300d97a1ef5ab8da2097f14af712c90c4 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Thu, 31 Aug 2023 10:49:59 +0200 Subject: [PATCH 003/157] #11945 Amend changes --- pandora_console/godmode/agentes/fields_manager.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pandora_console/godmode/agentes/fields_manager.php b/pandora_console/godmode/agentes/fields_manager.php index 53b4995d20..25b06e2f5a 100644 --- a/pandora_console/godmode/agentes/fields_manager.php +++ b/pandora_console/godmode/agentes/fields_manager.php @@ -217,7 +217,6 @@ foreach ($fields as $field) { array_push($table->data, $data); } -$tablePagination = ''; if ($fields) { html_print_table($table); $tablePagination = ui_pagination($count_fields, false, $offset, 0, true, 'offset', false); @@ -232,9 +231,6 @@ html_print_action_buttons( [ 'icon' => 'next' ], true ), - [ - 'type' => 'form_action', - 'right_content' => $tablePagination, - ], + ['type' => 'form_action'] ); echo ''; From 9ae34fae404fa1bc7c324448cd67fc275cd92020 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Thu, 31 Aug 2023 12:35:32 +0200 Subject: [PATCH 004/157] #11954 Fix delete alerts action in bulk --- .../godmode/massive/massive_delete_action_alerts.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/massive/massive_delete_action_alerts.php b/pandora_console/godmode/massive/massive_delete_action_alerts.php index cad37a3a29..0cd712e124 100644 --- a/pandora_console/godmode/massive/massive_delete_action_alerts.php +++ b/pandora_console/godmode/massive/massive_delete_action_alerts.php @@ -111,7 +111,8 @@ if ($delete) { $alerts_agent_modules = []; foreach ($agent_alerts['simple'] as $agent_alert) { if ((in_array($agent_alert['id_alert_template'], $id_alert_templates)) && (in_array($agent_alert['id_agent_module'], $modules_id))) { - $alerts_agent_modules = array_merge($alerts_agent_modules, alerts_get_alerts_agent_module($agent_alert['id_agent_module'], true, false, 'id')); + // $alerts_agent_modules = array_merge($alerts_agent_modules, alerts_get_alerts_agent_module($agent_alert['id_agent_module'], true, false, 'id')); + $alerts_agent_modules[] = $agent_alert['id']; } } @@ -126,7 +127,7 @@ if ($delete) { $agent_module_actions = []; foreach ($alerts_agent_modules as $alert_agent_module) { - $agent_module_actions = alerts_get_alert_agent_module_actions($alert_agent_module['id'], ['id', 'id_alert_action']); + $agent_module_actions = alerts_get_alert_agent_module_actions($alert_agent_module, ['id', 'id_alert_action']); foreach ($agent_module_actions as $agent_module_action) { foreach ($actions as $action) { From dac99b7a30be4960df2832e3cb420792a886fd62 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Fri, 1 Sep 2023 08:55:18 +0200 Subject: [PATCH 005/157] #11886 Fix minimun misprint --- pandora_console/include/functions_reporting_html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index eb7c555fb9..60e6e41a0c 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -4091,7 +4091,7 @@ function reporting_html_value( $table2->head = [ __('Agent'), __('Module'), - __('Minimun'), + __('Minimum'), ]; break; @@ -4162,7 +4162,7 @@ function reporting_html_value( case 'min_value': $table1->head = [ __('Lapse'), - __('Minimun'), + __('Minimum'), ]; break; From 94315147cfeb8d88daeeb53c1c062f9babd7b052 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 1 Sep 2023 10:12:03 +0200 Subject: [PATCH 006/157] #11750 module_data name file add module id --- pandora_console/include/functions_api.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 7e22befbee..95e3e47919 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -10299,8 +10299,7 @@ function api_set_module_data($id, $thrash2, $other, $trash1) modules_get_type_name($agentModule['id_tipo_modulo']), $data ); - - if (false === @file_put_contents($config['remote_config'].'/'.io_safe_output($agent['nombre']).'.'.$time.'.data', $xml)) { + if (false === @file_put_contents($config['remote_config'].'/'.io_safe_output($agent['nombre']).'.'.$idAgentModule.'.'.$time.'.data', $xml)) { returnError(sprintf('XML file could not be generated in path: %s', $config['remote_config'])); } else { echo __('XML file was generated successfully in path: ').$config['remote_config']; From 5a31621abfc33c93ee1c772f5b7e20d6c734c163 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Fri, 1 Sep 2023 13:15:42 +0200 Subject: [PATCH 007/157] #11903 Fix gis maps --- .../godmode/gis_maps/configure_gis_map.php | 14 +++++++++----- pandora_console/include/functions_gis.php | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pandora_console/godmode/gis_maps/configure_gis_map.php b/pandora_console/godmode/gis_maps/configure_gis_map.php index a6f282d2cf..fee2b9d723 100644 --- a/pandora_console/godmode/gis_maps/configure_gis_map.php +++ b/pandora_console/godmode/gis_maps/configure_gis_map.php @@ -243,10 +243,15 @@ switch ($action) { $map_default_altitude = get_parameter('map_default_altitude'); $map_group_id = get_parameter('map_group_id'); $map_levels_zoom = get_parameter('map_levels_zoom', 16); - $map_connection_list_temp = explode(',', get_parameter('map_connection_list')); + $map_connection_list_temp_string = implode(',', $map_connection_list_temp); + if (strlen($map_connection_list_temp_string) > 0) { + $where_map_connection = ' WHERE id_tmap_connection IN('.$map_connection_list_temp_string.')'; + } else { + $where_map_connection = ''; + } - $listConnectionTemp = db_get_all_rows_sql('SELECT id_tmap_connection, conection_name, group_id FROM tgis_map_connection'); + $listConnectionTemp = db_get_all_rows_sql('SELECT id_tmap_connection, conection_name, group_id FROM tgis_map_connection'.$where_map_connection); foreach ($map_connection_list_temp as $index => $value) { $cleanValue = trim($value); @@ -256,7 +261,6 @@ switch ($action) { } $map_connection_default = get_parameter('map_connection_default'); - $map_connection_list = []; foreach ($listConnectionTemp as $idMapConnection) { $default = 0; @@ -345,7 +349,7 @@ function deleteConnectionMap(idConnectionMap) { checked = $("#radiobtn0001", $("#map_connection_" + idConnectionMap)).attr('checked'); $("#map_connection_" + idConnectionMap).remove(); - + if (checked) { //Checked first, but not is index = 0 maybe. @@ -485,7 +489,7 @@ foreach ($listConnectionTemp as $connectionTemp) { $table->data[1][0] = __('Add Map connection').$iconError; $table->data[1][1] = " - - + diff --git a/pandora_console/godmode/reporting/visual_console_builder.php b/pandora_console/godmode/reporting/visual_console_builder.php index 986dcb423b..fc043228ed 100755 --- a/pandora_console/godmode/reporting/visual_console_builder.php +++ b/pandora_console/godmode/reporting/visual_console_builder.php @@ -78,6 +78,7 @@ $action = get_parameterBetweenListValues( 'update', 'delete', 'multiple_delete', + 'update_json', ], 'new' ); @@ -523,6 +524,110 @@ switch ($activeTab) { } break; + case 'update_json': + // Update background. + $background = get_parameter('background'); + $width = get_parameter('background_width'); + $height = get_parameter('background_height'); + + if ($width == 0 && $height == 0) { + $sizeBackground = getimagesize( + $config['homedir'].'/images/console/background/'.$background + ); + $width = $sizeBackground[0]; + $height = $sizeBackground[1]; + } + + db_process_sql_update( + 'tlayout', + [ + 'background' => $background, + 'width' => $width, + 'height' => $height, + ], + ['id' => $idVisualConsole] + ); + + // Return the updated visual console. + $visualConsole = db_get_row_filter( + 'tlayout', + ['id' => $idVisualConsole] + ); + + // Update elements in visual map. + $idsElements = db_get_all_rows_filter( + 'tlayout_data', + ['id_layout' => $idVisualConsole], + [ + 'id', + 'type', + ] + ); + + $array_update = json_decode(io_safe_output(get_parameter('array_update')), true); + + if (count($array_update)) { + foreach ($array_update as $row) { + $id = $row['id']; + $values = []; + $values['label'] = $row['label']; + $values['image'] = $row['image']; + $values['width'] = $row['width']; + $values['height'] = $row['height']; + $values['pos_x'] = $row['pos_x']; + $values['pos_y'] = $row['pos_y']; + + switch ($row['rowtype']) { + case NETWORK_LINK: + case LINE_ITEM: + continue 2; + + break; + + case SIMPLE_VALUE_MAX: + case SIMPLE_VALUE_MIN: + case SIMPLE_VALUE_AVG: + $values['period'] = $row['period']; + break; + + case MODULE_GRAPH: + $values['period'] = $row['period']; + unset($values['image']); + break; + + case GROUP_ITEM: + $values['id_group'] = $row['group']; + break; + + case CIRCULAR_PROGRESS_BAR: + case CIRCULAR_INTERIOR_PROGRESS_BAR: + case PERCENTILE_BUBBLE: + case PERCENTILE_BAR: + unset($values['height']); + break; + } + + if (defined('METACONSOLE')) { + $values['id_metaconsole'] = $row['id_server']; + } + + $values['id_agent'] = $row['agent']; + $values['id_agente_modulo'] = $row['module']; + $values['id_custom_graph'] = $row['custom_graph']; + $values['parent_item'] = $row['parent']; + $values['id_layout_linked'] = $row['map_linked']; + + if (enterprise_installed()) { + enterprise_visual_map_update_action_from_list_elements($row['rowtype'], $values, $id); + } + + db_process_sql_update('tlayout_data', $values, ['id' => $id]); + } + + return true; + } + break; + case 'delete': $id_element = get_parameter('id_element'); $result = db_process_sql_delete('tlayout_data', ['id' => $id_element]); From 08bccce67367b92acc1250d72d7d28e9279da755 Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Tue, 17 Oct 2023 08:28:38 -0600 Subject: [PATCH 038/157] Remove root validation --- pandora_agents/pc/pandora_agent | 11 +---------- pandora_agents/unix/pandora_agent | 9 +-------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/pandora_agents/pc/pandora_agent b/pandora_agents/pc/pandora_agent index aa8208f5d0..04b7de51a5 100644 --- a/pandora_agents/pc/pandora_agent +++ b/pandora_agents/pc/pandora_agent @@ -2185,16 +2185,7 @@ sub configure ($) { #Launch tentacle server in proxy mode if configured if ($Conf{'proxy_mode'}) { - - #Check if user is root - if ($> != 0) { - if (launch_tentacle_proxy() != 0) { - return 1; - } - } else { - error ('Proxy mode can not be launched as root'); - return 1; - } + return 1 if (launch_tentacle_proxy() != 0); } # Add the plugins directory to the PATH diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index de7a2e6946..d0b7c22ede 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -4183,14 +4183,7 @@ my $PID = $$; #Launch tentacle server in proxy mode if configured if ($Conf{'proxy_mode'}) { - - #Check if user is root - if ($> != 0) { - launch_tentacle_proxy(); - } else { - log_message ('error', 'Proxy mode can not be launched as root'); - exit 1; - } + launch_tentacle_proxy(); } # Advice if YAML::Tiny is allowed in this system From ec8fed69b3f2ea9319bb554ccd01f12f655b22b5 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Thu, 19 Oct 2023 15:04:49 +0200 Subject: [PATCH 039/157] #12168 tree hierarchical filtering --- .../include/class/TreeService.class.php | 1 + .../include/javascript/tree/TreeController.js | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php index d45ce50573..b218468de3 100644 --- a/pandora_console/include/class/TreeService.class.php +++ b/pandora_console/include/class/TreeService.class.php @@ -627,6 +627,7 @@ class TreeService extends Tree $tmp['type'] = 'services'; $tmp['rootType'] = 'services'; $tmp['children'] = []; + $tmp['servicesChildren'] = services_get_services_children($item->service()->id()); $tmp['serviceDetail'] = ui_get_full_url( 'index.php?sec=network&sec2=enterprise/operation/services/services&tab=service_map&id_service='.$item->service()->id() ); diff --git a/pandora_console/include/javascript/tree/TreeController.js b/pandora_console/include/javascript/tree/TreeController.js index 9d28ec9641..d2aa9347a4 100644 --- a/pandora_console/include/javascript/tree/TreeController.js +++ b/pandora_console/include/javascript/tree/TreeController.js @@ -1486,6 +1486,11 @@ var TreeController = { return 0; }); + //Search service criterion + const searchFilter = controller.filter.searchService; + if (searchFilter && controller.finded !== 1) { + rawTree = _filterItems(rawTree, searchFilter); + } _.each(rawTree, function(element) { element.jqObject = _processNode($group, element); }); @@ -1551,6 +1556,63 @@ var TreeController = { // Add again the hover event to the 'force_callback' elements forced_title_callback(); + + /** + * Filter the tree based on a search criterion + */ + function _filterItems(rawTree, searched) { + const ancestors = []; + const father = []; + const newTree = []; + rawTree.map((raw, index) => { + if (raw.servicesChildren.length !== 0) { + // search at parent level + let findedPadre = raw.description.indexOf(searched); + if (findedPadre === -1) { + // search for children + raw.servicesChildren.map(child => { + let finded = child.description.indexOf(searched); + if (finded === 0) { + //we keep the father of the child that contains it + ancestors.push(child.ancestor); + } else if (findedPadre === -1 && finded === -1) { + //we save the father + father.push(raw.id); + } + }); + } else { + //we mark the father as found + controller.finded = 1; + } + } else { + let finded = raw.description.indexOf(searched); + if (finded === -1) { + delete rawTree[index]; + } + } + }); + + if (ancestors.length >= 1) { + ancestors.map(ancestor => { + newTree.push( + rawTree.filter(item => item.id === parseInt(ancestor)) + ); + }); + + return newTree[0]; + } + + if (father.length >= 1) { + let filterfather = [...new Set(father)]; + const newTree = rawTree.filter( + item => !filterfather.includes(item.id) + ); + + return newTree; + } + + return rawTree.filter(item => item); + } }, load: function() { this.reload(); From 13ba9aff39492865cb7704dbd40f168967b64253 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Fri, 20 Oct 2023 10:49:08 +0200 Subject: [PATCH 040/157] #12168 filtered only for services --- .../include/javascript/tree/TreeController.js | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/pandora_console/include/javascript/tree/TreeController.js b/pandora_console/include/javascript/tree/TreeController.js index d2aa9347a4..d8a6daf468 100644 --- a/pandora_console/include/javascript/tree/TreeController.js +++ b/pandora_console/include/javascript/tree/TreeController.js @@ -1565,29 +1565,31 @@ var TreeController = { const father = []; const newTree = []; rawTree.map((raw, index) => { - if (raw.servicesChildren.length !== 0) { - // search at parent level - let findedPadre = raw.description.indexOf(searched); - if (findedPadre === -1) { - // search for children - raw.servicesChildren.map(child => { - let finded = child.description.indexOf(searched); - if (finded === 0) { - //we keep the father of the child that contains it - ancestors.push(child.ancestor); - } else if (findedPadre === -1 && finded === -1) { - //we save the father - father.push(raw.id); - } - }); + if (raw.type === "services") { + if (raw.servicesChildren.length !== 0) { + // search at parent level + let findedPadre = raw.description.indexOf(searched); + if (findedPadre === -1) { + // search for children + raw.servicesChildren.map(child => { + let finded = child.description.indexOf(searched); + if (finded === 0) { + //we keep the father of the child that contains it + ancestors.push(child.ancestor); + } else if (findedPadre === -1 && finded === -1) { + //we save the father + father.push(raw.id); + } + }); + } else { + //we mark the father as found + controller.finded = 1; + } } else { - //we mark the father as found - controller.finded = 1; - } - } else { - let finded = raw.description.indexOf(searched); - if (finded === -1) { - delete rawTree[index]; + let finded = raw.description.indexOf(searched); + if (finded === -1) { + delete rawTree[index]; + } } } }); From fdb800c712b44901bbf0a57c28542be998b7faf7 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 20 Oct 2023 13:43:28 +0200 Subject: [PATCH 041/157] Fix upload file function filter by extension. Fix mib uploader only upload .mib file --- .../include/functions_filemanager.php | 61 +++++++++++-------- .../snmpconsole/snmp_mib_uploader.php | 2 +- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/pandora_console/include/functions_filemanager.php b/pandora_console/include/functions_filemanager.php index aee3d88730..a390ee2c1a 100644 --- a/pandora_console/include/functions_filemanager.php +++ b/pandora_console/include/functions_filemanager.php @@ -128,19 +128,18 @@ function upload_file($upload_file_or_zip, $default_real_directory, $destination_ $extension = pathinfo($filename, PATHINFO_EXTENSION); $umask = io_safe_output((string) get_parameter('umask')); - $parse_all_queries = explode('&', parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY)); - $parse_sec2_query = explode('=', $parse_all_queries[1]); - $check_extension = true; - if ($parse_sec2_query[1] === 'operation/snmpconsole/snmp_mib_uploader') { - if ((strtolower($extension) !== 'mib' && strtolower($extension) !== 'zip')) { - $check_extension = false; - } else { - $check_extension = true; - } - } - + // $parse_all_queries = explode('&', parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY)); + // $parse_sec2_query = explode('=', $parse_all_queries[1]); + // $check_extension = true; + // if ($parse_sec2_query[1] === 'operation/snmpconsole/snmp_mib_uploader') { + // if ((strtolower($extension) !== 'mib' && strtolower($extension) !== 'zip')) { + // $check_extension = false; + // } else { + // $check_extension = true; + // } + // } // (strtolower($extension) !== 'mib' && strtolower($extension) !== 'zip') - if (strpos($real_directory, $default_real_directory) !== 0 || $check_extension === false) { + if (strpos($real_directory, $default_real_directory) !== 0) { // Perform security check to determine whether received upload // directory is part of the default path for caller uploader and // user is not trying to access an external path (avoid @@ -152,12 +151,12 @@ function upload_file($upload_file_or_zip, $default_real_directory, $destination_ // Copy file to directory and change name. $nombre_archivo = sprintf('%s/%s', $real_directory, $filename); try { - $mimeContentType = mime_content_type($_FILES['file']['tmp_name']); - - if (empty($filterFilesType) === true || in_array($mimeContentType, $filterFilesType) === true) { + $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); + if (empty($filterFilesType) === true || in_array($ext, $filterFilesType) === true) { $result = copy($_FILES['file']['tmp_name'], $nombre_archivo); } else { - $error_message = 'The uploaded file is not allowed. Only gif, png or jpg files can be uploaded.'; + $types_allowed = implode(', ', $filterFilesType); + $error_message = 'The uploaded file is not allowed. Only '.$types_allowed.' files can be uploaded.'; throw new Exception(__($error_message)); } } catch (Exception $ex) { @@ -199,19 +198,29 @@ function upload_file($upload_file_or_zip, $default_real_directory, $destination_ $filepath = $_FILES['file']['tmp_name']; $real_directory = filemanager_safe_directory($destination_directory); $secure = true; - if ($parse_sec2_query[1] === 'operation/snmpconsole/snmp_mib_uploader') { - // Security control structure. - $zip = new \ZipArchive; - if ($zip->open($filepath) === true) { - for ($i = 0; $i < $zip->numFiles; $i++) { - $unzip_filename = $zip->getNameIndex($i); - $extension = pathinfo($unzip_filename, PATHINFO_EXTENSION); - if (strtolower($extension) !== 'mib') { - $secure = false; - break; + try { + $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); + if (empty($filterFilesType) === true || in_array($ext, $filterFilesType) === true) { + // Security control structure. + $zip = new \ZipArchive; + if ($zip->open($filepath) === true) { + for ($i = 0; $i < $zip->numFiles; $i++) { + $unzip_filename = $zip->getNameIndex($i); + $extension = pathinfo($unzip_filename, PATHINFO_EXTENSION); + if (in_array(strtolower($extension), $filterFilesType) === false) { + $error_message = 'The uploaded file is not allowed. Only '.$types_allowed.' files can be uploaded.'; + $secure = false; + throw new Exception(__($error_message)); + } } } } + } catch (Exception $ex) { + db_pandora_audit( + AUDIT_LOG_FILE_MANAGER, + 'Error Uploading files: '.$ex->getMessage() + ); + $config['filemanager']['message'] = ui_print_error_message(__('Upload error').': '.$ex->getMessage()); } if (strpos($real_directory, $default_real_directory) !== 0 || $secure === false) { diff --git a/pandora_console/operation/snmpconsole/snmp_mib_uploader.php b/pandora_console/operation/snmpconsole/snmp_mib_uploader.php index 32db1d6b1b..2523e32b13 100644 --- a/pandora_console/operation/snmpconsole/snmp_mib_uploader.php +++ b/pandora_console/operation/snmpconsole/snmp_mib_uploader.php @@ -91,7 +91,7 @@ $create_text_file = (bool) get_parameter('create_text_file'); $default_real_directory = realpath($config['homedir'].'/'.$fallback_directory); if ($upload_file_or_zip === true) { - upload_file($upload_file_or_zip, $default_real_directory, $real_directory); + upload_file($upload_file_or_zip, $default_real_directory, $real_directory, ['mib', 'zip']); } if ($create_text_file === true) { From 202ad6f4f82eeba583b206184fbc87d682f51ae8 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 23 Oct 2023 10:54:06 +0200 Subject: [PATCH 042/157] #12270 widget min height --- pandora_console/include/styles/dashboards.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/styles/dashboards.css b/pandora_console/include/styles/dashboards.css index 2cda2de6f4..af3c2a7868 100644 --- a/pandora_console/include/styles/dashboards.css +++ b/pandora_console/include/styles/dashboards.css @@ -148,7 +148,7 @@ h1 { cursor: pointer; } #modal-add-widget { - min-height: 566px !important; + min-height: 625px !important; } #modal-add-widget .container-list-widgets { display: flex; From 76c6567432848e33ee91ebf1f106d6053c4ae6cb Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 25 Oct 2023 11:10:55 +0200 Subject: [PATCH 043/157] #8635 massive ncm add --- pandora_console/include/styles/ncm.css | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pandora_console/include/styles/ncm.css b/pandora_console/include/styles/ncm.css index 332d891431..2ed71d3338 100644 --- a/pandora_console/include/styles/ncm.css +++ b/pandora_console/include/styles/ncm.css @@ -1,10 +1,3 @@ -span.select2.select2-container.select2-container--default { - max-width: 175px !important; - width: 175px !important; -} - -.edit_discovery_input b { - display: flex; - flex-direction: row; - align-items: center; +.select2-selection__rendered { + max-width: 600px; } From f00ac9ea896a7a9eb8fc0e0a51f3042c4cb112a6 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Thu, 26 Oct 2023 12:19:42 +0200 Subject: [PATCH 044/157] #8365 added donut icon in svg --- pandora_console/images/donut.svg | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 pandora_console/images/donut.svg diff --git a/pandora_console/images/donut.svg b/pandora_console/images/donut.svg new file mode 100644 index 0000000000..67c8733d33 --- /dev/null +++ b/pandora_console/images/donut.svg @@ -0,0 +1,7 @@ + + + donut + + + + \ No newline at end of file From 90249d463116db8014ce1dc78e5b202699ffec9f Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 26 Oct 2023 12:49:30 +0200 Subject: [PATCH 045/157] #8365 NCM add backup id to ncm queue --- pandora_console/extras/mr/67.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 pandora_console/extras/mr/67.sql diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql new file mode 100644 index 0000000000..aa44ceea56 --- /dev/null +++ b/pandora_console/extras/mr/67.sql @@ -0,0 +1,7 @@ +START TRANSACTION; + +ALTER TABLE `tncm_queue` +ADD COLUMN `id_agent_data` INT NOT NULL DEFAULT 0 AFTER `id_script`; + + +COMMIT; \ No newline at end of file From 407a505a3e2f20bf185364cc89c90fae6a4e60d3 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Fri, 27 Oct 2023 14:32:48 +0200 Subject: [PATCH 046/157] #8365 Added reports for ncm backups. --- .../reporting_builder.item_editor.php | 111 ++++++++++++++++++ .../godmode/reporting/reporting_builder.php | 31 ++++- pandora_console/include/functions_reports.php | 5 + .../operation/agentes/ver_agente.php | 26 ++++ 4 files changed, 169 insertions(+), 4 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index e6032de2f6..d13071c60a 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -1039,6 +1039,11 @@ switch ($action) { $idAgent = $item['id_agent']; break; + case 'ncm_backups': + $id_agent_ncm = $item['id_agent']; + $ncm_group = $item['id_group']; + break; + case 'top_n_agents_sh': $group = $item['id_group']; $recursion = $item['recursion']; @@ -1928,6 +1933,71 @@ if (is_metaconsole() === true) { ?> + + + + + + + +
".html_print_select($listConnection, 'map_connection_list', '', '', '', '0', true)." + ".html_print_select($listConnection, 'select-map_connection_list', '', '', '', '0', true)." ".html_print_image( diff --git a/pandora_console/include/functions_gis.php b/pandora_console/include/functions_gis.php index ba9116759b..b57ec9e9ff 100644 --- a/pandora_console/include/functions_gis.php +++ b/pandora_console/include/functions_gis.php @@ -1585,7 +1585,7 @@ function gis_add_conection_maps_in_form($map_connection_list)
'.html_print_input_text('map_connection_name_'.$mapConnection['id_conection'], $mapConnectionRowDB['conection_name'], '', 20, 40, true, true).' '.$radioButton.''.html_print_image('images/delete.svg', true, ['alt' => '', 'class' => 'invert_filter']).''.html_print_image('images/delete.svg', true, ['alt' => '', 'class' => 'invert_filter main_menu_icon']).'
+ '; + $url = ui_get_full_url('ajax.php'); + html_print_input_hidden('url_ajax', $url, false, false, false, 'url_ajax'); + if (check_acl($config['id_user'], 0, 'RW')) { + html_print_select_groups( + $config['id_user'], + 'RW', + true, + 'ncm_group', + $ncm_group, + 'filterNcmAgentChange()', + ); + } else if (check_acl($config['id_user'], 0, 'RM')) { + html_print_select_groups( + $config['id_user'], + 'RM', + true, + 'ncm_group', + $ncm_group, + 'filterNcmAgentChange()', + ); + } + + echo ''; + ?> +
+ '; + $all_agents = agents_get_agents_selected($ncm_group); + html_print_select( + $all_agents, + 'agent_ncm', + $id_agent_ncm, + '', + __('Any'), + 0, + false, + true, + true, + '', + false, + 'width: 100%;', + false, + false, + false, + '', + false, + false, + false, + false, + true, + true, + ); + echo ''; + ?> +
@@ -6915,6 +6985,10 @@ function chooseType() { $('#agent_autocomplete_events').show(); + // NCM fields. + $("#row_ncm_group").hide(); + $("#row_ncm_agent").hide(); + switch (type) { case 'event_report_group': $("#row_description").show(); @@ -7764,6 +7838,11 @@ function chooseType() { $("#row_agent").show(); break; + case 'ncm_backups': + $("#row_ncm_group").show(); + $("#row_ncm_agent").show(); + break; + case 'top_n_agents_sh': $("#row_group").show(); $("#row_max_items").show(); @@ -8046,4 +8125,36 @@ $(document).ready(function () { }); }); +// Ncm agent filter by group. +function filterNcmAgentChange() { + var idGroup = $("#ncm_group").val(); + const url_ajax = $("#url_ajax").val(); + + $.ajax({ + url: url_ajax, + type: "POST", + dataType: "json", + async: false, + data: { + page: "operation/agentes/ver_agente", + get_ncm_agents: 1, + id_group: idGroup, + privilege: "AW", + keys_prefix: "_" + }, + success: function(data) { + $("#agent_ncm").empty(); + data.map(item => { + var option = $("") + .attr("value", item.id_agent) + .html(item.alias); + $("#agent_ncm").append(option); + }); + }, + error: function(err) { + console.error(err); + } + }); +} + diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index 095f79b14a..349bad535e 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -2045,6 +2045,12 @@ switch ($action) { $good_format = true; break; + case 'ncm_backups': + $values['id_agent'] = get_parameter('agent_ncm'); + $values['id_group'] = get_parameter('ncm_group'); + $good_format = true; + break; + default: $values['period'] = get_parameter('period'); $values['top_n'] = get_parameter( @@ -2065,7 +2071,10 @@ switch ($action) { break; } - $values['id_agent'] = get_parameter('id_agent'); + if (isset($values['id_agent']) === false) { + $values['id_agent'] = get_parameter('id_agent'); + } + $values['id_gs'] = get_parameter('id_custom_graph'); $values['id_agent_module'] = ''; @@ -2181,7 +2190,10 @@ switch ($action) { $values['id_module_group'] = get_parameter( 'combo_modulegroup' ); - $values['id_group'] = get_parameter('combo_group'); + + if (isset($values['id_group']) === false) { + $values['id_group'] = get_parameter('combo_group'); + } if ($values['server_name'] == '') { $values['server_name'] = get_parameter( @@ -2977,6 +2989,12 @@ switch ($action) { $good_format = true; break; + case 'ncm_backups': + $values['id_agent'] = get_parameter('agent_ncm'); + $values['id_group'] = get_parameter('ncm_group'); + $good_format = true; + break; + default: $values['period'] = get_parameter('period'); $values['top_n'] = get_parameter( @@ -3003,7 +3021,10 @@ switch ($action) { ); } - $values['id_agent'] = get_parameter('id_agent'); + if (isset($values['id_agent']) === false) { + $values['id_agent'] = get_parameter('id_agent'); + } + $values['id_gs'] = get_parameter('id_custom_graph'); if (($values['type'] == 'alert_report_agent') || ($values['type'] == 'event_report_agent') @@ -3117,7 +3138,9 @@ switch ($action) { $values['id_module_group'] = get_parameter( 'combo_modulegroup' ); - $values['id_group'] = get_parameter('combo_group'); + if (isset($values['id_group']) === false) { + $values['id_group'] = get_parameter('combo_group'); + } if ((($values['type'] == 'custom_graph') diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index 3da9993933..8956e3adc9 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -968,6 +968,11 @@ function reports_get_report_types($template=false, $not_editor=false) 'name' => __('Network configuration changes'), ]; + $types['ncm_backups'] = [ + 'optgroup' => __('NCM'), + 'name' => __('Network backups'), + ]; + if (enterprise_installed() === true) { $types['top_n_agents_sh'] = [ 'optgroup' => __('Security hardening'), diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 383a3b40d5..b050ba3b31 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -28,6 +28,7 @@ use PandoraFMS\Enterprise\Metaconsole\Node; use PandoraFMS\ITSM\ITSM; +use PandoraFMS\Enterprise\NetworkManager; global $config; @@ -72,6 +73,7 @@ if (is_ajax()) { $get_node_agent = (bool) get_parameter('get_node_agent', false); $get_agent_inventory_modules = (bool) get_parameter('get_agent_inventory_modules', false); $get_agent_inventory_dates = (bool) get_parameter('get_agent_inventory_dates', false); + $get_ncm_agents = (bool) get_parameter('get_ncm_agents', false); $refresh_contact = get_parameter('refresh_contact', 0); @@ -213,6 +215,30 @@ if (is_ajax()) { return; } + + // Get ncm Agent. + if ($get_ncm_agents === true) { + $fields = [ + '`tncm_agent`.id_agent', + '`tagente`.alias', + ]; + $id_group = (int) get_parameter('id_group'); + + $filter['filter_id_group'] = $id_group; + // Retrieve data. + $ncm_data = NetworkManager::agents( + // Fields. + $fields, + // Filter. + $filter, + ); + + echo json_encode($ncm_data); + return; + } + + + if ($get_modules_group_json === true) { $id_group = (int) get_parameter('id_module_group', 0); $id_agents = get_parameter('id_agents', null); From e062db2439ca1499f6ab6e93dd6fd5a456fec88d Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 30 Oct 2023 08:39:20 +0100 Subject: [PATCH 047/157] #8365 NCM add backup id to ncm queue --- pandora_console/pandoradb.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 1d7374bc03..8a4fca2917 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4226,6 +4226,7 @@ CREATE TABLE IF NOT EXISTS `tncm_agent_data` ( `id` SERIAL, `id_agent` INT UNSIGNED NOT NULL, `script_type` INT UNSIGNED NOT NULL, + `id_agent_data` INT NOT NULL DEFAULT 0, `data` LONGBLOB, `status` INT NOT NULL DEFAULT 5, `updated_at` BIGINT NOT NULL DEFAULT 0, From 63c74e2aa958355b0471de1b38ebd608dc4f38dc Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 30 Oct 2023 08:55:21 +0100 Subject: [PATCH 048/157] #8365 recovery after vscode revert error --- pandora_console/extras/mr/67.sql | 6 +-- pandora_console/pandoradb.sql | 4 +- pandora_server/lib/PandoraFMS/Tools.pm | 61 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index aa44ceea56..d15e49cf38 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -1,7 +1,7 @@ START TRANSACTION; ALTER TABLE `tncm_queue` -ADD COLUMN `id_agent_data` INT NOT NULL DEFAULT 0 AFTER `id_script`; +ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`, +ADD CONSTRAINT `fk_tncm_queue_tncm_agent_data` FOREIGN KEY (`id_agent_data`) REFERENCES `tncm_agent_data`(`id`) ON UPDATE CASCADE ON DELETE SET NULL; - -COMMIT; \ No newline at end of file +COMMIT; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 8a4fca2917..de34968f68 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4240,10 +4240,12 @@ CREATE TABLE IF NOT EXISTS `tncm_queue` ( `id` SERIAL, `id_agent` INT UNSIGNED NOT NULL, `id_script` BIGINT UNSIGNED NOT NULL, + `id_agent_data` bigint unsigned, `utimestamp` INT UNSIGNED NOT NULL, `scheduled` INT UNSIGNED DEFAULT NULL, FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, - FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE + FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_agent_data`) REFERENCES `tncm_agent_data`(`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- ---------------------------------------------------------------------- diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 70d697dab4..a0cc1c15ac 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -30,6 +30,9 @@ use Scalar::Util qw(looks_like_number); use LWP::UserAgent; use threads; use threads::shared; +use MIME::Base64; +use Crypt::CBC; +use Digest::SHA qw(hmac_sha256_base64); use JSON; use Encode qw/decode_utf8 encode_utf8/; @@ -181,6 +184,7 @@ our @EXPORT = qw( check_cron_value check_cron_element cron_check + decrypt_AES ); # ID of the different servers @@ -2983,6 +2987,63 @@ sub get_server_name { return "UNKNOWN"; } +############################################################################### +# Encrypt with AES cypher +############################################################################### +sub encrypt_AES { + my ($str_to_encrypt, $password) = @_; + + if (!defined($password)) { + $password = "default_salt"; + } + my $cipher = _get_cipher($password); + + my $cipher_text = $cipher->encrypt($str_to_encrypt); + my $b64str = encode_base64($cipher_text, ''); + + return $b64str; +} + +############################################################################### +# Decrypt with AES cypher +############################################################################### +sub decrypt_AES { + my ($str_to_decrypt, $password) = @_; + + if (!defined($password)) { + $password = "default_salt"; + } + my $cipher = _get_cipher($password); + + my $cipher_text = decode_base64($str_to_decrypt); + my $decrypted_str = $cipher->decrypt($cipher_text); + + return $decrypted_str; +} + +############################################################################### +# Get cipher for AES encrypt and decrypt +############################################################################### +sub _get_cipher { + my ($password) = @_; + + my $hash_base64 = substr(Digest::SHA::hmac_sha256_base64($password,''), 0, 16); + + my $iv = '0000000000000000'; + + my $cipher = Crypt::CBC->new( + -key => $hash_base64, + -cipher => 'Cipher::AES', + -iv => $iv, + -header => 'none', + -padding => 'standard', # PKCS7 padding + -keysize => 16, + -literal_key => 1 + ); + + return $cipher; +} + 1; __END__ From 84b9ac14fb66f5942637c819aef09475a598df00 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Mon, 30 Oct 2023 10:18:29 +0100 Subject: [PATCH 049/157] #8365Added viewer report for ncm backups --- pandora_console/include/functions_reporting.php | 8 ++++++++ pandora_console/operation/reporting/reporting_viewer.php | 1 + 2 files changed, 9 insertions(+) diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index 39f1642fa0..19c3f80b10 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -972,6 +972,14 @@ function reporting_make_reporting_data( ); break; + case 'ncm_backups': + $report['contents'][] = reporting_ncm_backups( + $report, + $content, + $pdf + ); + break; + case 'top_n_agents_sh': $report['contents'][] = reporting_top_n_agents_sh( $report, diff --git a/pandora_console/operation/reporting/reporting_viewer.php b/pandora_console/operation/reporting/reporting_viewer.php index cc42d7e6ac..4bc5a05b61 100755 --- a/pandora_console/operation/reporting/reporting_viewer.php +++ b/pandora_console/operation/reporting/reporting_viewer.php @@ -335,6 +335,7 @@ $table2->data[0][3] = $html_menu_export; $searchForm = '
'; $searchForm .= html_print_table($table2, true); $searchForm .= html_print_input_hidden('id_report', $id_report, true); +$Actionbuttons = ''; if ((bool) is_metaconsole() === true) { $Actionbuttons .= html_print_submit_button( From 307fd7b8cb66e0c2cd35821ccbc9c25a8062e04e Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 30 Oct 2023 10:52:13 +0100 Subject: [PATCH 050/157] #8365 remove fk tncm_queue --- pandora_console/extras/mr/67.sql | 3 +-- pandora_console/pandoradb.sql | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index d15e49cf38..2f6824f1f2 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -1,7 +1,6 @@ START TRANSACTION; ALTER TABLE `tncm_queue` -ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`, -ADD CONSTRAINT `fk_tncm_queue_tncm_agent_data` FOREIGN KEY (`id_agent_data`) REFERENCES `tncm_agent_data`(`id`) ON UPDATE CASCADE ON DELETE SET NULL; +ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`; COMMIT; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index de34968f68..65e2459bdb 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4244,8 +4244,7 @@ CREATE TABLE IF NOT EXISTS `tncm_queue` ( `utimestamp` INT UNSIGNED NOT NULL, `scheduled` INT UNSIGNED DEFAULT NULL, FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, - FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, - FOREIGN KEY (`id_agent_data`) REFERENCES `tncm_agent_data`(`id`) ON UPDATE CASCADE ON DELETE SET NULL + FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- ---------------------------------------------------------------------- From 7db3e3bb2b52c03290523778e550416ddb761d8e Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Mon, 30 Oct 2023 17:20:58 +0100 Subject: [PATCH 051/157] #8365 Added html report for ncm backups --- .../include/functions_reporting_html.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 99f3af63ad..8fc6f3cf79 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -480,6 +480,10 @@ function reporting_html_print_report($report, $mini=false, $report_info=1, $cust reporting_html_ncm_config($table, $item); break; + case 'ncm_backups': + reporting_html_ncm_backups($table, $item); + break; + case 'top_n_agents_sh': reporting_html_top_n_agents_sh($table, $item); break; @@ -7380,3 +7384,49 @@ function reporting_html_ncm_config($table, $item, $pdf=0) return $content; } } + + +/** + * HTML content for ncm backup report. + * + * @param array $item Content generated by reporting_ncm_config. + * + * @return string HTML code. + */ +function reporting_html_ncm_backups($table, $item, $pdf=0) +{ + ui_require_javascript_file('diff2html-ui.min'); + ui_require_css_file('diff2html.min'); + ui_require_css_file('highlight.min'); + ui_require_css_file('highlight/vs.min'); + ui_require_javascript_file('highlight.min'); + ui_require_javascript_file('highlightjs-line-numbers.min'); + ui_require_javascript_file('languages/plaintext.min'); + ui_require_javascript_file('functions_ncm', ENTERPRISE_DIR.'/include/javascript/'); + + // Create table info. + $table_ncm = new stdClass(); + $table_ncm->width = '100%'; + $table_ncm->class = 'info_table'; + $table_ncm->styleTable = 'table-layout: fixed;'; + $table_ncm->rowstyle['title'] = 'text-align: center; font-weight: bolder'; + $table_ncm->head = []; + $table_ncm->head[0] = __('Date'); + $table_ncm->head[1] = __('Diff'); + + $table_ncm->data = []; + foreach ($item['data'] as $key => $row) { + $table_ncm->data[] = [ + $row['updated_at'], + $row['diff'], + ]; + } + + if ($pdf === 0) { + return $table->data[] = html_print_table( + $table_ncm, + true + ); + } + +} From b327c824da86c620a3aa383dff7e7c5be9d43ca4 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 31 Oct 2023 13:45:26 +0100 Subject: [PATCH 052/157] #8365 NCM new special templates --- pandora_console/extras/mr/67.sql | 27 +++++++++++++++++++++++++++ pandora_console/pandoradb.sql | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 2f6824f1f2..9da40c6829 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -3,4 +3,31 @@ START TRANSACTION; ALTER TABLE `tncm_queue` ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`; +CREATE TABLE IF NOT EXISTS `tncm_special_template` ( + `id` SERIAL, + `name` TEXT, + `vendors` TEXT, + `models` TEXT, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + +ALTER TABLE `tncm_agent` +ADD COLUMN `id_special_template` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `id_template`; + +CREATE TABLE IF NOT EXISTS `tncm_special_template_scripts` ( + `id` SERIAL, + `id_special_template` BIGINT UNSIGNED NOT NULL, + `id_script` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`id_special_template`) REFERENCES `tncm_special_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + +ALTER TABLE `tncm_agent` +ADD COLUMN `special_cron_interval` VARCHAR(100) NULL DEFAULT '' AFTER `cron_interval`; + +ALTER TABLE `tncm_agent` +ADD COLUMN `special_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `event_on_change`; + + COMMIT; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 65e2459bdb..24020ffb0f 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4191,6 +4191,29 @@ CREATE TABLE IF NOT EXISTS `tncm_template_scripts` ( FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; +-- ---------------------------------------------------------------------- +-- Table `tncm_special_template` +-- ---------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tncm_special_template` ( + `id` SERIAL, + `name` TEXT, + `vendors` TEXT, + `models` TEXT, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + +-- ---------------------------------------------------------------------- +-- Table `tncm_special_template_scripts` +-- ---------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tncm_special_template_scripts` ( + `id` SERIAL, + `id_special_template` BIGINT UNSIGNED NOT NULL, + `id_script` BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`id_special_template`) REFERENCES `tncm_special_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + -- ---------------------------------------------------------------------- -- Table `tncm_agent` -- ---------------------------------------------------------------------- @@ -4206,10 +4229,13 @@ CREATE TABLE IF NOT EXISTS `tncm_agent` ( `updated_at` BIGINT NOT NULL DEFAULT 0, `config_backup_id` BIGINT UNSIGNED DEFAULT NULL, `id_template` BIGINT UNSIGNED, + `id_special_template` BIGINT UNSIGNED, `execute_type` INT UNSIGNED NOT NULL DEFAULT 0, `execute` INT UNSIGNED NOT NULL DEFAULT 0, `cron_interval` VARCHAR(100) DEFAULT '', + `special_cron_interval` VARCHAR(100) DEFAULT '', `event_on_change` INT UNSIGNED DEFAULT null, + `special_event_on_change` INT UNSIGNED DEFAULT null, `last_error` TEXT, PRIMARY KEY (`id_agent`), FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, From 98332d728e9e84c80639e1f7cd989c7195ec1eac Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 31 Oct 2023 16:55:35 +0100 Subject: [PATCH 053/157] #8365 change name ncm agent data --- pandora_console/extras/mr/67.sql | 14 +++++++------- pandora_console/pandoradb.sql | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 9da40c6829..b2b34e5ce4 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -3,7 +3,7 @@ START TRANSACTION; ALTER TABLE `tncm_queue` ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`; -CREATE TABLE IF NOT EXISTS `tncm_special_template` ( +CREATE TABLE IF NOT EXISTS `tncm_agent_data_template` ( `id` SERIAL, `name` TEXT, `vendors` TEXT, @@ -12,22 +12,22 @@ CREATE TABLE IF NOT EXISTS `tncm_special_template` ( ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; ALTER TABLE `tncm_agent` -ADD COLUMN `id_special_template` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `id_template`; +ADD COLUMN `id_agent_data_template` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `id_template`; -CREATE TABLE IF NOT EXISTS `tncm_special_template_scripts` ( +CREATE TABLE IF NOT EXISTS `tncm_agent_data_template_scripts` ( `id` SERIAL, - `id_special_template` BIGINT UNSIGNED NOT NULL, + `id_agent_data_template` BIGINT UNSIGNED NOT NULL, `id_script` BIGINT UNSIGNED NOT NULL, PRIMARY KEY (`id`), - FOREIGN KEY (`id_special_template`) REFERENCES `tncm_special_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_agent_data_template`) REFERENCES `tncm_agent_data_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; ALTER TABLE `tncm_agent` -ADD COLUMN `special_cron_interval` VARCHAR(100) NULL DEFAULT '' AFTER `cron_interval`; +ADD COLUMN `agent_data_cron_interval` VARCHAR(100) NULL DEFAULT '' AFTER `cron_interval`; ALTER TABLE `tncm_agent` -ADD COLUMN `special_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `event_on_change`; +ADD COLUMN `agent_data_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `event_on_change`; COMMIT; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 24020ffb0f..8b83b26011 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4192,9 +4192,9 @@ CREATE TABLE IF NOT EXISTS `tncm_template_scripts` ( ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- ---------------------------------------------------------------------- --- Table `tncm_special_template` +-- Table `tncm_agent_data_template` -- ---------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tncm_special_template` ( +CREATE TABLE IF NOT EXISTS `tncm_agent_data_template` ( `id` SERIAL, `name` TEXT, `vendors` TEXT, @@ -4203,14 +4203,14 @@ CREATE TABLE IF NOT EXISTS `tncm_special_template` ( ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- ---------------------------------------------------------------------- --- Table `tncm_special_template_scripts` +-- Table `tncm_agent_data_template_scripts` -- ---------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tncm_special_template_scripts` ( +CREATE TABLE IF NOT EXISTS `tncm_agent_data_template_scripts` ( `id` SERIAL, - `id_special_template` BIGINT UNSIGNED NOT NULL, + `id_agent_data_template` BIGINT UNSIGNED NOT NULL, `id_script` BIGINT UNSIGNED NOT NULL, PRIMARY KEY (`id`), - FOREIGN KEY (`id_special_template`) REFERENCES `tncm_special_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, + FOREIGN KEY (`id_agent_data_template`) REFERENCES `tncm_agent_data_template`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; @@ -4229,13 +4229,13 @@ CREATE TABLE IF NOT EXISTS `tncm_agent` ( `updated_at` BIGINT NOT NULL DEFAULT 0, `config_backup_id` BIGINT UNSIGNED DEFAULT NULL, `id_template` BIGINT UNSIGNED, - `id_special_template` BIGINT UNSIGNED, + `id_agent_data_template` BIGINT UNSIGNED, `execute_type` INT UNSIGNED NOT NULL DEFAULT 0, `execute` INT UNSIGNED NOT NULL DEFAULT 0, `cron_interval` VARCHAR(100) DEFAULT '', - `special_cron_interval` VARCHAR(100) DEFAULT '', + `agent_data_cron_interval` VARCHAR(100) DEFAULT '', `event_on_change` INT UNSIGNED DEFAULT null, - `special_event_on_change` INT UNSIGNED DEFAULT null, + `agent_data_event_on_change` INT UNSIGNED DEFAULT null, `last_error` TEXT, PRIMARY KEY (`id_agent`), FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, From f5e7ac8d4af9a6aa6ac39b44f1e1313748f8a225 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Tue, 31 Oct 2023 17:27:28 +0100 Subject: [PATCH 054/157] #8365 PDF report added for ncm backups --- .../include/functions_reporting_html.php | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 8fc6f3cf79..76f0920e34 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -7389,44 +7389,57 @@ function reporting_html_ncm_config($table, $item, $pdf=0) /** * HTML content for ncm backup report. * - * @param array $item Content generated by reporting_ncm_config. + * @param array $item Content generated by reporting_ncm_backups. * * @return string HTML code. */ function reporting_html_ncm_backups($table, $item, $pdf=0) { - ui_require_javascript_file('diff2html-ui.min'); ui_require_css_file('diff2html.min'); ui_require_css_file('highlight.min'); ui_require_css_file('highlight/vs.min'); + ui_require_javascript_file('diff2html-ui.min'); ui_require_javascript_file('highlight.min'); ui_require_javascript_file('highlightjs-line-numbers.min'); ui_require_javascript_file('languages/plaintext.min'); ui_require_javascript_file('functions_ncm', ENTERPRISE_DIR.'/include/javascript/'); - // Create table info. + // Create table diff. $table_ncm = new stdClass(); $table_ncm->width = '100%'; $table_ncm->class = 'info_table'; $table_ncm->styleTable = 'table-layout: fixed;'; - $table_ncm->rowstyle['title'] = 'text-align: center; font-weight: bolder'; + $table_ncm->headstyle[0] = 'width: 250px'; $table_ncm->head = []; $table_ncm->head[0] = __('Date'); $table_ncm->head[1] = __('Diff'); $table_ncm->data = []; - foreach ($item['data'] as $key => $row) { - $table_ncm->data[] = [ - $row['updated_at'], - $row['diff'], - ]; - } if ($pdf === 0) { + foreach ($item['data'] as $key => $row) { + $table_ncm->data[] = [ + $row['updated_at'], + $row['diff'], + ]; + } + return $table->data[] = html_print_table( $table_ncm, true ); + } else { + foreach ($item['data'] as $key => $row) { + $table_ncm->data[] = [ + $row['updated_at'], + ($row['diffstr'] === '') ? $row['diff'] : str_replace("\n", '
', $row['diffstr']), + ]; + } + + return html_print_table( + $table_ncm, + true + ); } } From 3031e7ddbddb52a6a7aea8381904bd4cf92825b5 Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Wed, 1 Nov 2023 10:13:44 -0600 Subject: [PATCH 055/157] Add export Encrypt AES to tools --- pandora_server/lib/PandoraFMS/Tools.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index a0cc1c15ac..48a46ea740 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -185,6 +185,7 @@ our @EXPORT = qw( check_cron_element cron_check decrypt_AES + encrypt_AES ); # ID of the different servers From 1a021c96899c1cd6af25eb09421445d0baa490c1 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Thu, 2 Nov 2023 11:24:50 +0100 Subject: [PATCH 056/157] Added Rijndael encryption for python pandoraPlugintools and PandoraFMS::Tools --- .../extras/pandoraPlugintools/encryption.py | 89 +++++++++++++++++- pandora_server/lib/PandoraFMS/Tools.pm | 92 +++++++++---------- 2 files changed, 132 insertions(+), 49 deletions(-) diff --git a/pandora_server/extras/pandoraPlugintools/encryption.py b/pandora_server/extras/pandoraPlugintools/encryption.py index b1ec3c9315..576ae31ae3 100644 --- a/pandora_server/extras/pandoraPlugintools/encryption.py +++ b/pandora_server/extras/pandoraPlugintools/encryption.py @@ -39,7 +39,7 @@ def _print_debug( #### # Internal use only: Get AES cipher ######################################################################################### -def _get_cipher( +def _get_cipher_AES( password: str = _PASSWORD ) -> AES: ''' @@ -78,7 +78,7 @@ def encrypt_AES( Returns: str: The encrypted string in base64 encoding. ''' - cipher = _get_cipher(password) + cipher = _get_cipher_AES(password) try: msg_padded = pad(str_to_encrypt.encode(), AES.block_size, style='pkcs7') @@ -106,11 +106,94 @@ def decrypt_AES( Returns: str: The decrypted string. ''' - cipher = _get_cipher(password) + cipher = _get_cipher_AES(password) try: decrypted_str = unpad(cipher.decrypt(base64.b64decode(str_to_decrypt)), AES.block_size, style='pkcs7').decode().strip() except: decrypted_str = '' + return decrypted_str + +#### +# Internal use only: Get Rijndael cipher +######################################################################################### +def _get_cipher_Rijndael( + password: str = _PASSWORD + ) -> AES: + ''' + Internal use only: Get Rijndael cipher for encryption and decryption. + + Args: + password (str): The password used to derive the encryption key. + + Returns: + AES: An AES cipher instance for encryption and decryption. + ''' + key = b'' + msg = password.encode('utf-8') + hash_obj = hmac.new(key, msg, hashlib.sha256) + hash_result = hash_obj.digest() + hash_base64 = base64.b64encode(hash_result)[:16].decode() + + iv = b'0000000000000000' + + return AES.new(hash_base64.encode(), AES.MODE_CBC, iv) + +#### +# Return encrypted string +######################################################################################### +def encrypt_Rijndael( + str_to_encrypt: str = "", + password: str = _PASSWORD + ) -> str: + ''' + Encrypt a string using Rijndael encryption. + + Args: + str_to_encrypt (str): The string to be encrypted. + password (str): The password used to derive the encryption key. + + Returns: + str: The encrypted string in base64 encoding. + ''' + cipher = _get_cipher_Rijndael(password) + + block_size = 16 # Rijndael block size is 16 bytes + padding_length = block_size - (len(str_to_encrypt) % block_size) + padded_data = str_to_encrypt + chr(padding_length) * padding_length + + try: + b64str = base64.b64encode(cipher.encrypt(padded_data.encode())).decode() + except Exception as e: + b64str = '' + + return b64str + +#### +# Return decrypted string +######################################################################################### +def decrypt_Rijndael( + str_to_decrypt: str = "", + password: str = _PASSWORD + ) -> str: + ''' + Decrypt an encrypted string using Rijndael decryption. + + Args: + str_to_decrypt (str): The encrypted string to be decrypted. + password (str): The password used to derive the encryption key. + + Returns: + str: The decrypted string. + ''' + cipher = _get_cipher_Rijndael(password) + + try: + decrypted_data = cipher.decrypt(base64.b64decode(str_to_decrypt)).decode().strip() + padding_length = ord(decrypted_data[-1]) + decrypted_str = decrypted_data[:-padding_length] + except: + decrypted_str = '' + return decrypted_str \ No newline at end of file diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 48a46ea740..cb9ca7c86e 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -31,7 +31,7 @@ use LWP::UserAgent; use threads; use threads::shared; use MIME::Base64; -use Crypt::CBC; +use Crypt::Rijndael; use Digest::SHA qw(hmac_sha256_base64); use JSON; @@ -2989,62 +2989,62 @@ sub get_server_name { } ############################################################################### -# Encrypt with AES cypher +# Get cipher for Rijndael encrypt and decrypt ############################################################################### -sub encrypt_AES { - my ($str_to_encrypt, $password) = @_; - - if (!defined($password)) { - $password = "default_salt"; - } - my $cipher = _get_cipher($password); - - my $cipher_text = $cipher->encrypt($str_to_encrypt); - my $b64str = encode_base64($cipher_text, ''); - - return $b64str; -} - -############################################################################### -# Decrypt with AES cypher -############################################################################### -sub decrypt_AES { - my ($str_to_decrypt, $password) = @_; - - if (!defined($password)) { - $password = "default_salt"; - } - my $cipher = _get_cipher($password); - - my $cipher_text = decode_base64($str_to_decrypt); - my $decrypted_str = $cipher->decrypt($cipher_text); - - return $decrypted_str; -} - -############################################################################### -# Get cipher for AES encrypt and decrypt -############################################################################### -sub _get_cipher { +sub _get_cipher_Rijndael { my ($password) = @_; my $hash_base64 = substr(Digest::SHA::hmac_sha256_base64($password,''), 0, 16); my $iv = '0000000000000000'; - my $cipher = Crypt::CBC->new( - -key => $hash_base64, - -cipher => 'Cipher::AES', - -iv => $iv, - -header => 'none', - -padding => 'standard', # PKCS7 padding - -keysize => 16, - -literal_key => 1 - ); + my $cipher = Crypt::Rijndael->new($hash_base64, Crypt::Rijndael::MODE_CBC()); + $cipher->set_iv($iv); return $cipher; } +############################################################################### +# Encrypt with Rijndael cypher +############################################################################### +sub encrypt_Rijndael { + my ($str_to_encrypt, $password) = @_; + + if (!defined($password)) { + $password = "default_salt"; + } + my $cipher = _get_cipher_Rijndael($password); + + my $block_size = 16; # Rijndael block size is 16 bytes + my $padding_length = $block_size - (length($str_to_encrypt) % $block_size); + my $padded_data = $str_to_encrypt . chr($padding_length) x $padding_length; + + my $cipher_text = $cipher->encrypt($padded_data); + my $b64str = encode_base64($cipher_text, ''); + + return $b64str; +} + +############################################################################### +# Decrypt with Rijndael cypher +############################################################################### +sub decrypt_Rijndael { + my ($str_to_decrypt, $password) = @_; + + if (!defined($password)) { + $password = "default_salt"; + } + my $cipher = _get_cipher_Rijndael($password); + + my $cipher_text = decode_base64($str_to_decrypt); + my $decrypted_data = $cipher->decrypt($cipher_text); + + my $padding_length = ord(substr($decrypted_data, -1)); + my $decrypted_str = substr($decrypted_data, 0, -$padding_length); + + return $decrypted_str; +} + 1; __END__ From dc648167631d38a19f70c66b3617d33399b7d25f Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Thu, 2 Nov 2023 11:26:20 +0100 Subject: [PATCH 057/157] Exported encrypt and decrypt functions in Tools.pm --- pandora_server/lib/PandoraFMS/Tools.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index cb9ca7c86e..cb9b78e1b4 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -184,8 +184,8 @@ our @EXPORT = qw( check_cron_value check_cron_element cron_check - decrypt_AES - encrypt_AES + decrypt_Rijndael + encrypt_Rijndael ); # ID of the different servers From 9e4ba18f49287c18ee108856052281cfc86374f7 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Thu, 2 Nov 2023 12:52:31 +0100 Subject: [PATCH 058/157] Changed pandoraPlugintools encryption funcion and removed encryption functions from Tools.pm --- .../extras/pandoraPlugintools/encryption.py | 21 +++--- pandora_server/lib/PandoraFMS/Tools.pm | 64 +------------------ 2 files changed, 11 insertions(+), 74 deletions(-) diff --git a/pandora_server/extras/pandoraPlugintools/encryption.py b/pandora_server/extras/pandoraPlugintools/encryption.py index 576ae31ae3..6e456d2fcd 100644 --- a/pandora_server/extras/pandoraPlugintools/encryption.py +++ b/pandora_server/extras/pandoraPlugintools/encryption.py @@ -136,9 +136,7 @@ def _get_cipher_Rijndael( hash_result = hash_obj.digest() hash_base64 = base64.b64encode(hash_result)[:16].decode() - iv = b'0000000000000000' - - return AES.new(hash_base64.encode(), AES.MODE_CBC, iv) + return AES.new(hash_base64.encode(), AES.MODE_ECB) #### # Return encrypted string @@ -159,13 +157,13 @@ def encrypt_Rijndael( ''' cipher = _get_cipher_Rijndael(password) - block_size = 16 # Rijndael block size is 16 bytes - padding_length = block_size - (len(str_to_encrypt) % block_size) - padded_data = str_to_encrypt + chr(padding_length) * padding_length - try: - b64str = base64.b64encode(cipher.encrypt(padded_data.encode())).decode() - except Exception as e: + padded_data = str_to_encrypt.encode() + missing = 16 - (len(padded_data) % 16) + padded_data += bytes([0] * missing) if missing != 16 else b'' + + b64str = base64.b64encode(cipher.encrypt(padded_data)).decode() + except: b64str = '' return b64str @@ -190,9 +188,8 @@ def decrypt_Rijndael( cipher = _get_cipher_Rijndael(password) try: - decrypted_data = cipher.decrypt(base64.b64decode(str_to_decrypt)).decode().strip() - padding_length = ord(decrypted_data[-1]) - decrypted_str = decrypted_data[:-padding_length] + decrypted_data = cipher.decrypt(base64.b64decode(str_to_decrypt)) + decrypted_str = decrypted_data.rstrip(b'\x00').decode() except: decrypted_str = '' diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index cb9b78e1b4..61b68cd2ce 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -30,9 +30,6 @@ use Scalar::Util qw(looks_like_number); use LWP::UserAgent; use threads; use threads::shared; -use MIME::Base64; -use Crypt::Rijndael; -use Digest::SHA qw(hmac_sha256_base64); use JSON; use Encode qw/decode_utf8 encode_utf8/; @@ -184,8 +181,8 @@ our @EXPORT = qw( check_cron_value check_cron_element cron_check - decrypt_Rijndael - encrypt_Rijndael + decrypt_AES + encrypt_AES ); # ID of the different servers @@ -2988,63 +2985,6 @@ sub get_server_name { return "UNKNOWN"; } -############################################################################### -# Get cipher for Rijndael encrypt and decrypt -############################################################################### -sub _get_cipher_Rijndael { - my ($password) = @_; - - my $hash_base64 = substr(Digest::SHA::hmac_sha256_base64($password,''), 0, 16); - - my $iv = '0000000000000000'; - - my $cipher = Crypt::Rijndael->new($hash_base64, Crypt::Rijndael::MODE_CBC()); - $cipher->set_iv($iv); - - return $cipher; -} - -############################################################################### -# Encrypt with Rijndael cypher -############################################################################### -sub encrypt_Rijndael { - my ($str_to_encrypt, $password) = @_; - - if (!defined($password)) { - $password = "default_salt"; - } - my $cipher = _get_cipher_Rijndael($password); - - my $block_size = 16; # Rijndael block size is 16 bytes - my $padding_length = $block_size - (length($str_to_encrypt) % $block_size); - my $padded_data = $str_to_encrypt . chr($padding_length) x $padding_length; - - my $cipher_text = $cipher->encrypt($padded_data); - my $b64str = encode_base64($cipher_text, ''); - - return $b64str; -} - -############################################################################### -# Decrypt with Rijndael cypher -############################################################################### -sub decrypt_Rijndael { - my ($str_to_decrypt, $password) = @_; - - if (!defined($password)) { - $password = "default_salt"; - } - my $cipher = _get_cipher_Rijndael($password); - - my $cipher_text = decode_base64($str_to_decrypt); - my $decrypted_data = $cipher->decrypt($cipher_text); - - my $padding_length = ord(substr($decrypted_data, -1)); - my $decrypted_str = substr($decrypted_data, 0, -$padding_length); - - return $decrypted_str; -} - 1; __END__ From e6f505da5422b0ff60ed98857df396928bcebe6c Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Thu, 2 Nov 2023 12:53:38 +0100 Subject: [PATCH 059/157] Removed encryption functions from Tools.pm exporting --- pandora_server/lib/PandoraFMS/Tools.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 61b68cd2ce..70d697dab4 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -181,8 +181,6 @@ our @EXPORT = qw( check_cron_value check_cron_element cron_check - decrypt_AES - encrypt_AES ); # ID of the different servers From 513a0bc2965ac9c547dd1c3fc8427b2b666713bb Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Fri, 3 Nov 2023 14:25:44 +0100 Subject: [PATCH 060/157] #8365 Added csv report for device lists. Fixed overlay for modals --- .../reporting_builder.item_editor.php | 6 +- .../godmode/reporting/reporting_builder.php | 12 +++ .../include/functions_reporting.php | 2 +- .../include/functions_reporting_html.php | 93 +++++++++++++------ pandora_console/include/functions_reports.php | 12 +-- .../include/javascript/pandora_ui.js | 9 +- .../include/styles/js/jquery-ui_custom.css | 6 ++ 7 files changed, 96 insertions(+), 44 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index d13071c60a..f50b451683 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -1036,7 +1036,8 @@ switch ($action) { break; case 'ncm': - $idAgent = $item['id_agent']; + $id_agent_ncm = $item['id_agent']; + $ncm_group = $item['id_group']; break; case 'ncm_backups': @@ -7835,7 +7836,8 @@ function chooseType() { break; case 'ncm': - $("#row_agent").show(); + $("#row_ncm_group").show(); + $("#row_ncm_agent").show(); break; case 'ncm_backups': diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index 349bad535e..f155a89831 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -2051,6 +2051,12 @@ switch ($action) { $good_format = true; break; + case 'ncm': + $values['id_agent'] = get_parameter('agent_ncm'); + $values['id_group'] = get_parameter('ncm_group'); + $good_format = true; + break; + default: $values['period'] = get_parameter('period'); $values['top_n'] = get_parameter( @@ -2995,6 +3001,12 @@ switch ($action) { $good_format = true; break; + case 'ncm': + $values['id_agent'] = get_parameter('agent_ncm'); + $values['id_group'] = get_parameter('ncm_group'); + $good_format = true; + break; + default: $values['period'] = get_parameter('period'); $values['top_n'] = get_parameter( diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index 19c3f80b10..54f1284a2c 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -965,7 +965,7 @@ function reporting_make_reporting_data( break; case 'ncm': - $report['contents'][] = reporting_ncm_config( + $report['contents'][] = reporting_ncm_list( $report, $content, $pdf diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 76f0920e34..a74fcb4a47 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -477,7 +477,7 @@ function reporting_html_print_report($report, $mini=false, $report_info=1, $cust break; case 'ncm': - reporting_html_ncm_config($table, $item); + reporting_html_ncm_list($table, $item); break; case 'ncm_backups': @@ -7347,41 +7347,76 @@ function reporting_html_permissions($table, $item, $pdf=0) /** - * HTML content for ncm configuration diff report. + * HTML content for ncm devices list. * - * @param array $item Content generated by reporting_ncm_config. + * @param array $item Content generated by reporting_ncm_list. * * @return string HTML code. */ -function reporting_html_ncm_config($table, $item, $pdf=0) +function reporting_html_ncm_list($table, $item, $pdf=0) { - $key = uniqid(); + // Create table diff. + $table_ncm = new stdClass(); + $table_ncm->width = '100%'; + $table_ncm->class = 'info_table'; + $table_ncm->styleTable = 'table-layout: fixed;'; + $table_ncm->titleclass = 'title_table_pdf'; + + $table_ncm->align = []; + $table_ncm->align['name'] = 'left'; + $table_ncm->align['ip'] = 'left'; + $table_ncm->align['vendor'] = 'left'; + $table_ncm->align['model'] = 'left'; + $table_ncm->align['firmware'] = 'left'; + $table_ncm->align['last_backup_date'] = 'left'; + + $table_ncm->headstyle['name'] = 'text-align: left'; + $table_ncm->headstyle['ip'] = 'text-align: left'; + $table_ncm->headstyle['vendor'] = 'text-align: left'; + $table_ncm->headstyle['model'] = 'text-align: left'; + $table_ncm->headstyle['firmware'] = 'text-align: left'; + $table_ncm->headstyle['last_backup_date'] = 'text-align: left'; + + $table_ncm->head = []; + $table_ncm->head['name'] = __('Name'); + $table_ncm->head['ip'] = __('Ip'); + $table_ncm->head['vendor'] = __('Vendor'); + $table_ncm->head['model'] = __('Model'); + $table_ncm->head['firmware'] = __('Firmware'); + $table_ncm->head['last_backup_date'] = __('Last backup date'); + + $table_ncm->data = []; + foreach ($item['data'] as $key => $row) { + $title = $row['last_error']; + if (empty($title) === true) { + $title = null; + } + + $table_ncm->data[] = [ + $row['alias'], + $row['direccion'], + $row['vendor'], + $row['model'], + $row['firmware'], + $row['last_backup_date'], + ]; + } + if ($pdf === 0) { - ui_require_javascript_file('diff2html-ui.min'); - ui_require_css_file('diff2html.min'); - $script = "$(document).ready(function() { - const configuration = { - drawFileList: false, - collapsed: true, - matching: 'lines', - outputFormat: 'side-by-side', - }; - const diff2htmlUi = new Diff2HtmlUI( - document.getElementById('".$key."'), - atob('".base64_encode($item['data'])."'), - configuration - ); - diff2htmlUi.draw(); - });"; - $content = '
'; - $content .= ''; - $table->data[1] = $content; - $table->colspan[1][0] = 2; + $table->colspan['data']['cell'] = 3; + $table->cellstyle['data']['cell'] = 'text-align: left;'; + $table->data['data']['cell'] = html_print_table( + $table_ncm, + true + ); } else { - $content = '
'; - $content .= str_replace("\n", '
', $item['data']); - $content .= '
'; - return $content; + $table_ncm->titleclass = 'title_table_pdf'; + $table_ncm->titlestyle = 'text-align:left;'; + + return html_print_table( + $table_ncm, + true + ); } } diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index 8956e3adc9..c3f6427ac2 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -963,14 +963,14 @@ function reports_get_report_types($template=false, $not_editor=false) ]; } - $types['ncm'] = [ - 'optgroup' => __('NCM'), - 'name' => __('Network configuration changes'), - ]; - $types['ncm_backups'] = [ 'optgroup' => __('NCM'), - 'name' => __('Network backups'), + 'name' => __('NCM configuration changes'), + ]; + + $types['ncm'] = [ + 'optgroup' => __('NCM'), + 'name' => __('NCM devices list'), ]; if (enterprise_installed() === true) { diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index 45ca47e92b..80ddfd06f5 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -104,11 +104,8 @@ function load_modal(settings) { width = settings.onshow.width; } - if (settings.modal.overlay == undefined) { - settings.modal.overlay = { - opacity: 0.5, - background: "black" - }; + if (settings.modal.overlay === true) { + $("body").append(""); } if (settings.beforeClose == undefined) { @@ -496,7 +493,6 @@ function load_modal(settings) { settings.onshow.maxHeight != undefined ? settings.onshow.maxHeight : "auto", - overlay: settings.modal.overlay, position: { my: "top+20%", at: "top", @@ -518,6 +514,7 @@ function load_modal(settings) { if (settings.cleanup != undefined) { settings.cleanup(); } + $("#modal_overlay").removeClass("ui-widget-overlay"); }, beforeClose: settings.beforeClose() }); diff --git a/pandora_console/include/styles/js/jquery-ui_custom.css b/pandora_console/include/styles/js/jquery-ui_custom.css index 9c17d7fdab..905c3d5d67 100644 --- a/pandora_console/include/styles/js/jquery-ui_custom.css +++ b/pandora_console/include/styles/js/jquery-ui_custom.css @@ -371,3 +371,9 @@ input[type="submit"].ui-button-dialog { .ui_tpicker_time { margin-left: 10px !important; } + +.ui-widget-overlay { + background: #aaa !important; + opacity: 0.3 !important; + z-index: 1114; +} From 92ee718f918c4730e784a089f02b4417661ad5df Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 3 Nov 2023 17:48:15 +0100 Subject: [PATCH 061/157] Optimiized monitors view --- .../operation/agentes/status_monitor.php | 115 +++++++++--------- 1 file changed, 60 insertions(+), 55 deletions(-) diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index 046fbc5222..5868b73707 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -27,6 +27,7 @@ */ // Begin. +use PandoraFMS\Enterprise\Metaconsole\Node; global $config; check_login(); @@ -188,7 +189,7 @@ $sql_from = ' FROM tagente_modulo INNER JOIN tagente ON tagente_modulo.id_agente = tagente.id_agente LEFT JOIN tagent_secondary_group tasg - ON tagente.id_agente = tasg.id_agent + ON tagente_modulo.id_agente = tasg.id_agent INNER JOIN tagente_estado ON tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo INNER JOIN tmodule @@ -436,12 +437,22 @@ if ($moduletype != '') { // Freestring selector. if ($ag_freestring != '') { - $sql_conditions .= ' AND (tagente.nombre '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' - OR tagente.alias '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' - OR tagente_modulo.nombre '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' - OR tagente_modulo.descripcion '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\')'; + $sql_conditions .= ' AND EXISTS ( + SELECT 1 + FROM tagente + WHERE tagente.id_agente = tagente_modulo.id_agente + AND ( + tagente.nombre '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' OR tagente.alias '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' + ) + AND ( + tagente_modulo.nombre '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\' + OR tagente_modulo.descripcion '.$not_condition.' LIKE \'%%'.$ag_freestring.'%%\') + )'; } + + + // Status selector. if ($status == AGENT_MODULE_STATUS_NORMAL) { // Normal. @@ -1348,15 +1359,10 @@ $sql = 'SELECT tagente.nombre AS agent_name, tagente_modulo.nombre AS module_name, tagente_modulo.history_data, - tagente_modulo.flag AS flag, tagente.id_grupo AS id_group, tagente.id_agente AS id_agent, tagente_modulo.id_tipo_modulo AS module_type, tagente_modulo.module_interval, - tagente_modulo.tcp_send, - tagente_modulo.ip_target, - tagente_modulo.snmp_community, - tagente_modulo.snmp_oid, tagente_estado.datos, tagente_estado.estado, tagente_estado.last_status_change, @@ -1370,13 +1376,12 @@ $sql = 'SELECT tagente_modulo.extended_info, tagente_modulo.critical_inverse, tagente_modulo.warning_inverse, - tagente_modulo.critical_instructions, - tagente_modulo.warning_instructions, - tagente_modulo.unknown_instructions, tagente_estado.utimestamp AS utimestamp'.$sql_from.$sql_conditions_all.' GROUP BY tagente_modulo.id_agente_modulo ORDER BY '.$order['field'].' '.$order['order'].' - LIMIT '.$offset.','.$limit_sql; + LIMIT '.$limit_sql.' OFFSET '.$offset; + + hd($sql); // We do not show the modules until the user searches with the filter. if ($autosearch) { @@ -1402,53 +1407,53 @@ if ($autosearch) { $result = []; $count_modules = 0; foreach ($servers as $server) { - // If connection was good then retrieve all data server. - if (metaconsole_connect($server) === NOERR) { - $connection = true; - } else { - $connection = false; - } + try { + $node = new Node((int) $server['id']); + $node->connect(); - $result_server = db_get_all_rows_sql($sql); + $result_server = db_get_all_rows_sql($sql); - if (empty($result_server) === false) { - // Create HASH login info. - $pwd = $server['auth_token']; - $auth_serialized = json_decode($pwd, true); + if (empty($result_server) === false) { + // Create HASH login info. + $pwd = $server['auth_token']; + $auth_serialized = json_decode($pwd, true); - if (is_array($auth_serialized)) { - $pwd = $auth_serialized['auth_token']; - $api_password = $auth_serialized['api_password']; - $console_user = $auth_serialized['console_user']; - $console_password = $auth_serialized['console_password']; + if (is_array($auth_serialized)) { + $pwd = $auth_serialized['auth_token']; + $api_password = $auth_serialized['api_password']; + $console_user = $auth_serialized['console_user']; + $console_password = $auth_serialized['console_password']; + } + + $user = $config['id_user']; + $user_rot13 = str_rot13($config['id_user']); + $hashdata = $user.$pwd; + $hashdata = md5($hashdata); + + foreach ($result_server as $result_element_key => $result_element_value) { + $result_server[$result_element_key]['server_id'] = $server['id']; + $result_server[$result_element_key]['server_name'] = $server['server_name']; + $result_server[$result_element_key]['server_url'] = $server['server_url'].'/'; + $result_server[$result_element_key]['hashdata'] = $hashdata; + $result_server[$result_element_key]['user'] = $config['id_user']; + $result_server[$result_element_key]['groups_in_server'] = agents_get_all_groups_agent( + $result_element_value['id_agent'], + $result_element_value['id_group'] + ); + + $count_modules++; + } + + $result = array_merge($result, $result_server); } - $user = $config['id_user']; - $user_rot13 = str_rot13($config['id_user']); - $hashdata = $user.$pwd; - $hashdata = md5($hashdata); - $url_hash = '&'.'loginhash=auto&'.'loginhash_data='.$hashdata.'&'.'loginhash_user='.$user_rot13; - - foreach ($result_server as $result_element_key => $result_element_value) { - $result_server[$result_element_key]['server_id'] = $server['id']; - $result_server[$result_element_key]['server_name'] = $server['server_name']; - $result_server[$result_element_key]['server_url'] = $server['server_url'].'/'; - $result_server[$result_element_key]['hashdata'] = $hashdata; - $result_server[$result_element_key]['user'] = $config['id_user']; - $result_server[$result_element_key]['groups_in_server'] = agents_get_all_groups_agent( - $result_element_value['id_agent'], - $result_element_value['id_group'] - ); - - $count_modules++; - } - - $result = array_merge($result, $result_server); + usort($result, arrayOutputSorting($sort, $fieldForSorting)); + } catch (\Exception $e) { + $node->disconnect(); + return; + } finally { + $node->disconnect(); } - - usort($result, arrayOutputSorting($sort, $fieldForSorting)); - - metaconsole_restore_db(); } if ($count_modules > $config['block_size']) { From 3506ba1b5a3e6ffe37beb33f0d72d6b65c0bb5bd Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Mon, 6 Nov 2023 15:06:16 +0100 Subject: [PATCH 062/157] Added default NCM templates --- pandora_console/extras/mr/67.sql | 1007 ++++++++++++++++++++++++++++ pandora_console/pandoradb_data.sql | 146 +++- 2 files changed, 1148 insertions(+), 5 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index b2b34e5ce4..2a604941e0 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -29,5 +29,1012 @@ ADD COLUMN `agent_data_cron_interval` VARCHAR(100) NULL DEFAULT '' AFTER `cron_i ALTER TABLE `tncm_agent` ADD COLUMN `agent_data_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `event_on_change`; +-- Add new vendor and model +SET @vendor_name = 'Cisco'; +SET @model_name = 'Cisco-Generic'; +SET @template_name = 'Cisco-Generic'; +SET @agent_data_template_name = 'Cisco-Generic'; +SET @script_test = 'enable\n expect:Password:\s* _enablepass_\n exit\n'; +SET @script_get_config = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'; +SET @script_set_config = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'; +SET @script_get_firmware = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'; +SET @script_set_firmware = 'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'Juniper'; +SET @model_name = 'Juniper-Generic'; +SET @template_name = 'Juniper-Generic'; +SET @agent_data_template_name = 'Juniper-Generic'; +SET @script_test = 'expect:root@% cli\n exit\n'; +SET @script_get_config = 'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'; +SET @script_set_config = 'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'; +SET @script_get_firmware = 'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'; +SET @script_set_firmware = 'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'Palo Alto'; +SET @model_name = 'Palo Alto-Generic'; +SET @template_name = 'Palo Alto-Generic'; +SET @agent_data_template_name = 'Palo Alto-Generic'; +SET @script_test = 'sleep:1 exit\n'; +SET @script_get_config = 'set cli pager off \n capture:show config running\n exit\n'; +SET @script_set_config = 'set cli terminal width 500\n set cli scripting-mode on\n configure\n _applyconfigbackup_\n commit\n'; +SET @script_get_firmware = 'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'; +SET @script_set_firmware = 'tftp import software from _TFTP_SERVER_IP_ file _FIRMWARE_NAME_\n request system software install version\n reboot\n exit\n'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'A10'; +SET @model_name = 'A10-Generic'; +SET @template_name = 'A10-Generic'; +SET @agent_data_template_name = 'A10-Generic'; +SET @script_test = 'sleep:1 enable\n expect:Password:\s* _enablepass_\n'; +SET @script_get_config = 'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'; +SET @script_set_config = 'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n _applyconfigbackup_\n exit\n'; +SET @script_get_firmware = 'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'; +SET @script_set_firmware = 'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n expect:(config) restore _TFTP_SERVER_IP_/_FIRMWARE_NAME_\n expect:Password:\s* _enablepass_\n expect:skip port map yes\n expect: see the diff yes\n sleep:1 expect:Proceed with reboot yes\n expect:eof'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'Alcatel-Lucent Enterprise'; +SET @model_name = 'Alcatel-Generic'; +SET @template_name = 'Alcatel-Generic'; +SET @agent_data_template_name = 'Alcatel-Generic'; +SET @script_test = 'enable\n expect:Password:\s* _enablepass_\n exit\n'; +SET @script_get_config = 'enable\n expect:Password:\s* _enablepass_\n capture:admin display-config\n logout\n'; +SET @script_set_config = ''; +SET @script_get_firmware = 'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'; +SET @script_set_firmware = ''; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'Aruba'; +SET @model_name = 'Aruba-Generic'; +SET @template_name = 'Aruba-Generic'; +SET @agent_data_template_name = 'Aruba-Generic'; +SET @script_test = 'enable\n expect:Password:\s* _enablepass_\n exit\n'; +SET @script_get_config = 'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'; +SET @script_set_config = 'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'; +SET @script_get_firmware = 'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'; +SET @script_set_firmware = 'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); + +-- Add new vendor and model +SET @vendor_name = 'Mikrotik'; +SET @model_name = 'Mikrotik-Generic'; +SET @template_name = 'Mikrotik-Generic'; +SET @agent_data_template_name = 'Mikrotik-Generic'; +SET @script_test = 'sleep:1 exit\n\r'; +SET @script_get_config = 'sleep:1 capture:system resource print\n\r exit\n\r'; +SET @script_set_config = 'sleep:1 system backup load name=_nameBackup_ password=_passwordBackup_\n\r expect:Restore yes\n\r exit\n\r'; +SET @script_get_firmware = 'sleep:1 capture:/system package print\n\r exit\n\r'; +SET @script_set_firmware = 'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'; +SET @script_custom = ''; +SET @script_os_version = @script_get_firmware; + +-- Try to insert vendor +INSERT IGNORE INTO `tncm_vendor` (`id`, `name`, `icon`) VALUES ('', @vendor_name, ''); +-- Get vendor ID +SELECT @id_vendor := `id` FROM `tncm_vendor` WHERE `name` = @vendor_name; + +-- Try to insert model +INSERT IGNORE INTO `tncm_model` (`id`, `id_vendor`, `name`) VALUES ('', @id_vendor, @model_name); +-- Get model ID +SELECT @id_model := `id` FROM `tncm_model` WHERE `id_vendor` = @id_vendor AND `name` = @model_name; + +-- Get template ID if exists +SET @id_template = NULL; +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; +-- Try to insert template +INSERT IGNORE INTO `tncm_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_template, @template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get template ID again if inserted +SELECT @id_template := `id` FROM `tncm_template` WHERE `name` = @template_name; + +-- Get agent data template ID if exists +SET @id_agent_data_template = NULL; +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; +-- Try to insert agent data template +INSERT IGNORE INTO `tncm_agent_data_template` (`id`, `name`, `vendors`, `models`) VALUES (@id_agent_data_template, @agent_data_template_name, CONCAT('[',@id_vendor,']'), CONCAT('[',@id_model,']')); +-- Get agent data template ID again if inserted +SELECT @id_agent_data_template := `id` FROM `tncm_agent_data_template` WHERE `name` = @agent_data_template_name; + +-- Get test script ID if exists +SET @id_script_test = NULL; +SET @script_type = 0; +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; +-- Try to insert test script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_test, @script_type, @script_test); +-- Get test script ID again if inserted +SELECT @id_script_test := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_test; + +-- Get get_config script ID if exists +SET @id_script_get_config = NULL; +SET @script_type = 1; +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; +-- Try to insert get_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_config, @script_type, @script_get_config); +-- Get get_config script ID again if inserted +SELECT @id_script_get_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_config; + +-- Get set_config script ID if exists +SET @id_script_set_config = NULL; +SET @script_type = 2; +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; +-- Try to insert set_config script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_config, @script_type, @script_set_config); +-- Get set_config script ID again if inserted +SELECT @id_script_set_config := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_config; + +-- Get get_firmware script ID if exists +SET @id_script_get_firmware = NULL; +SET @script_type = 3; +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; +-- Try to insert get_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_get_firmware, @script_type, @script_get_firmware); +-- Get get_firmware script ID again if inserted +SELECT @id_script_get_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_get_firmware; + +-- Get set_firmware script ID if exists +SET @id_script_set_firmware = NULL; +SET @script_type = 4; +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; +-- Try to insert set_firmware script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_set_firmware, @script_type, @script_set_firmware); +-- Get set_firmware script ID again if inserted +SELECT @id_script_set_firmware := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_set_firmware; + +-- Get custom script ID if exists +SET @id_script_custom = NULL; +SET @script_type = 5; +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; +-- Try to insert custom script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_custom, @script_type, @script_custom); +-- Get custom script ID again if inserted +SELECT @id_script_custom := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_custom; + +-- Get os_version script ID if exists +SET @id_script_os_version = NULL; +SET @script_type = 7; +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; +-- Try to insert os_version script +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_script_os_version, @script_type, @script_os_version); +-- Get os_version script ID again if inserted +SELECT @id_script_os_version := `id` FROM `tncm_script` WHERE `type` = @script_type AND `content` = @script_os_version; + +-- Get template scripts ID if exists +SET @id_ts_test = NULL; +SELECT @id_ts_test := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_test; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_test, @id_template, @id_script_test); + +-- Get template scripts ID if exists +SET @id_ts_get_config = NULL; +SELECT @id_ts_get_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_config, @id_template, @id_script_get_config); + +-- Get template scripts ID if exists +SET @id_ts_set_config = NULL; +SELECT @id_ts_set_config := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_config; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_config, @id_template, @id_script_set_config); + +-- Get template scripts ID if exists +SET @id_ts_get_firmware = NULL; +SELECT @id_ts_get_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_get_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_get_firmware, @id_template, @id_script_get_firmware); + +-- Get template scripts ID if exists +SET @id_ts_set_firmware = NULL; +SELECT @id_ts_set_firmware := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_set_firmware; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_set_firmware, @id_template, @id_script_set_firmware); + +-- Get template scripts ID if exists +SET @id_ts_custom = NULL; +SELECT @id_ts_custom := `id` FROM `tncm_template_scripts` WHERE `id_template` = @id_template AND `id_script` = @id_script_custom; +-- Try to insert +INSERT IGNORE INTO `tncm_template_scripts` (`id`, `id_template`, `id_script`) VALUES (@id_ts_custom, @id_template, @id_script_custom); + +-- Get template scripts ID if exists +SET @id_ts_os_version = NULL; +SELECT @id_ts_os_version := `id` FROM `tncm_agent_data_template_scripts` WHERE `id_agent_data_template` = @id_template AND `id_script` = @id_script_os_version; +-- Try to insert +INSERT IGNORE INTO `tncm_agent_data_template_scripts` (`id`, `id_agent_data_template`, `id_script`) VALUES (@id_ts_os_version, @id_agent_data_template, @id_script_os_version); COMMIT; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 47365fcc6e..8229c96ee7 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2512,11 +2512,32 @@ INSERT INTO `tncm_vendor` (`id`, `name`) VALUES (11, 'Netlink'), (12, 'Ascom'), (13, 'Synology Inc.'), - (14, 'Fujitsu Network Communications, Inc.'); + (14, 'Fujitsu Network Communications, Inc.'), + (15, 'Juniper'), + (16, 'Palo Alto'), + (17, 'A10'), + (18, 'Aruba'), + (19, 'Mikrotik'); -INSERT INTO `tncm_model` VALUES (1,1,'7200'); +INSERT INTO `tncm_model` VALUES + (1,1,'7200'), + (2,1,'Cisco-Generic'), + (3,15,'Juniper-Generic'), + (4,16,'Palo Alto-Generic'), + (5,17,'A10-Generic'), + (6,4,'Alcatel-Generic'), + (7,18,'Aruba-Generic'), + (8,19,'Mikrotik-Generic'); -INSERT INTO `tncm_template` VALUES (1,'cisco-base','[\"1\"]','[\"1\"]'); +INSERT INTO `tncm_template` VALUES + (1,'cisco-base','[\"1\"]','[\"1\"]'), + (2,'Cisco-Generic','[\"1\"]','[\"2\"]'), + (3,'Juniper-Generic','[\"15\"]','[\"3\"]'), + (4,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), + (5,'A10-Generic','[\"17\"]','[\"5\"]'), + (6,'Alcatel-Generic','[\"4\"]','[\"6\"]'), + (7,'Aruba-Generic','[\"18\"]','[\"7\"]'), + (8,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); INSERT INTO `tncm_script` VALUES (1,0,'enable expect:Password:\s* _enablepass_ exit'), @@ -2524,9 +2545,124 @@ INSERT INTO `tncm_script` VALUES (3,2,'enable expect:Password:\s* _enablepass_ term length 0 config terminal _applyconfigbackup_ exit '), (4,3,'enable expect:Password:\s* _enablepass_ term length 0 capture:show version | i IOS Software exit '), (5,5,'enable expect:Password:\s* _enablepass_ term length 0 config term end end exit '), - (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? _DESTINATION_FILE_NAME_ show flash reload expect:confirm y config terminal boot system _DESTINATION_FILE_NAME_'); + (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? _DESTINATION_FILE_NAME_ show flash reload expect:confirm y config terminal boot system _DESTINATION_FILE_NAME_'), + (7,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (8,1,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'), + (9,2,'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'), + (10,3,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), + (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'), + (12,5,''), + (13,7,''), + (14,0,'expect:root@% cli\n exit\n'), + (15,1,'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'), + (16,2,'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'), + (17,3,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), + (18,4,'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'), + (19,5,''), + (20,7,''), + (21,0,'sleep:1 exit\n'), + (22,1,'set cli pager off \n capture:show config running\n exit\n'), + (23,2,'set cli terminal width 500\n set cli scripting-mode on\n configure\n _applyconfigbackup_\n commit\n'), + (24,3,'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'), + (25,4,'tftp import software from _TFTP_SERVER_IP_ file _FIRMWARE_NAME_\n request system software install version\n reboot\n exit\n'), + (26,5,''), + (27,7,''), + (28,0,'sleep:1 enable\n expect:Password:\s* _enablepass_\n'), + (29,1,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), + (30,2,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n _applyconfigbackup_\n exit\n'), + (31,3,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), + (32,4,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n expect:(config) restore _TFTP_SERVER_IP_/_FIRMWARE_NAME_\n expect:Password:\s* _enablepass_\n expect:skip port map yes\n expect: see the diff yes\n sleep:1 expect:Proceed with reboot yes\n expect:eof'), + (33,5,''), + (34,7,''), + (35,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (36,1,'enable\n expect:Password:\s* _enablepass_\n capture:admin display-config\n logout\n'), + (37,2,''), + (38,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'), + (39,4,''), + (40,5,''), + (41,7,''), + (42,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (43,1,'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), + (44,2,'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'), + (45,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), + (46,4,'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'), + (47,5,''), + (48,7,''), + (49,0,'sleep:1 exit\n\r'), + (50,1,'sleep:1 capture:system resource print\n\r exit\n\r'), + (51,2,'sleep:1 system backup load name=_nameBackup_ password=_passwordBackup_\n\r expect:Restore yes\n\r exit\n\r'), + (52,3,'sleep:1 capture:/system package print\n\r exit\n\r'), + (53,4,'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'), + (54,5,''), + (55,7,''); -INSERT INTO `tncm_template_scripts`(`id_template`, `id_script`) VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6); +INSERT INTO `tncm_template_scripts`(`id_template`, `id_script`) VALUES + (1,1), + (1,2), + (1,3), + (1,4), + (1,5), + (1,6), + (2,7), + (2,8), + (2,9), + (2,10), + (2,11), + (2,12), + (3,14), + (3,15), + (3,16), + (3,17), + (3,18), + (3,19), + (4,21), + (4,22), + (4,23), + (4,24), + (4,25), + (4,26), + (5,28), + (5,29), + (5,30), + (5,31), + (5,32), + (5,33), + (6,35), + (6,36), + (6,37), + (6,38), + (6,39), + (6,40), + (7,42), + (7,43), + (7,44), + (7,45), + (7,46), + (7,47), + (8,49), + (8,50), + (8,51), + (8,52), + (8,53), + (8,54); + +INSERT INTO `tncm_agent_data_template` VALUES + (1,'Cisco-Generic','[\"1\"]','[\"2\"]'), + (2,'Juniper-Generic','[\"15\"]','[\"3\"]'), + (3,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), + (4,'A10-Generic','[\"17\"]','[\"5\"]'), + (5,'Alcatel-Generic','[\"4\"]','[\"6\"]'), + (6,'Aruba-Generic','[\"18\"]','[\"7\"]'), + (7,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); + +INSERT INTO `tncm_agent_data_template_scripts`(`id_agent_data_template`, `id_script`) VALUES + (1,13), + (2,20), + (3,27), + (4,34), + (5,41), + (6,48), + (7,55), INSERT INTO `talert_calendar` VALUES (1, 'Default', 0, 'Default calendar'); From c266640f39c64c1b747ff6cb8f934b4c8972dadc Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Mon, 6 Nov 2023 15:07:43 +0100 Subject: [PATCH 063/157] Fixed syntax error in SQL --- pandora_console/pandoradb_data.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 8229c96ee7..7f3664620a 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2662,7 +2662,7 @@ INSERT INTO `tncm_agent_data_template_scripts`(`id_agent_data_template`, `id_scr (4,34), (5,41), (6,48), - (7,55), + (7,55); INSERT INTO `talert_calendar` VALUES (1, 'Default', 0, 'Default calendar'); From 26ed76b82109a765bfda684fb0bd98932178bf0f Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Mon, 6 Nov 2023 16:41:37 +0100 Subject: [PATCH 064/157] Fixed SQL issue --- pandora_console/pandoradb_data.sql | 302 ++++++++++++++--------------- 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 7f3664620a..7e4bee1954 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -369,11 +369,11 @@ INSERT INTO `tusuario_perfil` (`id_up`, `id_usuario`, `id_perfil`, `id_grupo`, ` -- INSERT INTO `tperfil` VALUES - (1,'Operator (Read)',1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0), - (2,'Operator (Write)',1,0,0,0,0,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0), - (3,'Chief Operator',1,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0), - (4,'Group coordinator',1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0), - (5,'Pandora Administrator',1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); + (1,'Operator (Read)',1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0), + (2,'Operator (Write)',1,0,0,0,0,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0), + (3,'Chief Operator',1,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0), + (4,'Group coordinator',1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0), + (5,'Pandora Administrator',1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); -- -- Dumping data for table `tnews` @@ -388,7 +388,7 @@ INSERT INTO tmodule VALUES (5,'Prediction module'); INSERT INTO tmodule VALUES (6,'WMI module'); INSERT INTO tmodule VALUES (7, 'Web module'); INSERT INTO tmodule VALUES (8, 'Wux module'); -INSERT INTO tmodule VALUES (9, 'Wizard module'); +INSERT INTO tmodule VALUES (9, 'Wizard module'); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (1,'OS Total process','Total process in Operating System (UNIX MIB)',13,15,0,0,300,0,'','','public','HOST-RESOURCES-MIB::hrSystemProcesses.0 ',4,2,0,NULL,NULL,NULL,0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); @@ -732,11 +732,11 @@ INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `t INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (513,'MSDTC TransactionsPersec','Transactions performed per second.',22,1,0,0,300,0,'','','','select TransactionsPersec from Win32_PerfRawData_MSDTC_DistributedTransactionCoordinator',3,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (514,'c2900InfoPeakBuffersUsed','ftp://ftp.cisco.com/pub/mibs/oid/CISCO-C2900-MIB.oid',23,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.87.1.1.2.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (515,'c2900InfoTotalBufferDepth','ftp://ftp.cisco.com/pub/mibs/oid/CISCO-C2900-MIB.oid',23,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.87.1.1.3.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); -INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (516,'c2900BandwidthUsageCurrent ','ftp://ftp.cisco.com/pub/mibs/oid/CISCO-C2900-MIB.oid',23,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.87.1.5.1.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); +INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (516,'c2900BandwidthUsageCurrent ','ftp://ftp.cisco.com/pub/mibs/oid/CISCO-C2900-MIB.oid',23,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.87.1.5.1.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (517,'Latest Message ','Get the last message sent in Syslog',2,17,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.41.1.2.3.1.5.12',1,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (518,'Latest Message date','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.9.41.1.2.3.1.6.12',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); -INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (519,'CPU avgBusy1min ','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.2.1.57.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); -INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (520,'CPU avgBusy5min ','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.2.1.58.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); +INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (519,'CPU avgBusy1min ','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.2.1.57.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); +INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (520,'CPU avgBusy5min ','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.2.1.58.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (521,'Software Image running ','',2,17,0,0,1800,0,'','','public','1.3.6.1.4.1.9.2.1.73.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (522,'nvRAMUsed','',2,15,0,0,300,0,'','','public','1.3.6.1.4.1.9.3.6.8.0',2,2,0,'','','0',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (523,'Printers BytesPrintedPersec','Number of bytes per second printed on a print queue.',24,1,0,0,300,0,'','','','select BytesPrintedPersec from Win32_PerfRawData_Spooler_PrintQueue where NAME = '_total'',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); @@ -748,7 +748,7 @@ INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `t INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (529,'Printers OutofPaperErrors','Total number of out-of-paper errors in a print queue after the last restart.',24,1,0,0,300,0,'','','','select OutofPaperErrors from Win32_PerfRawData_Spooler_PrintQueue where NAME = '_total'',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (530,'Printers TotalJobsPrinted','Total number of jobs printed on a print queue after the last restart.',24,1,0,0,300,0,'','','','select TotalJobsPrinted from Win32_PerfRawData_Spooler_PrintQueue where NAME = '_total'',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (531,'Printers TotalPagesPrinted','Total number of pages printed through GDI on a print queue after the last restart.',24,1,0,0,300,0,'','','','select TotalPagesPrinted from Win32_PerfRawData_Spooler_PrintQueue where NAME = '_total'',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); -INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (532,'Printers Availability','Availability and status of the device\r\n\r\nValue Meaning\r\n\r\n10x1 Other\r\n\r\n20x2 Unknown\r\n\r\n30x3 Running or Full Power\r\n\r\n40x4 Warning\r\n\r\n50x5 In Test\r\n\r\n60x6 Not Applicable\r',24,3,0,0,300,0,'','','','select Availability from Win32_Printer',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); +INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (532,'Printers Availability','Availability and status of the device\r\n\r\nValue Meaning\r\n\r\n10x1 Other\r\n\r\n20x2 Unknown\r\n\r\n30x3 Running or Full Power\r\n\r\n40x4 Warning\r\n\r\n50x5 In Test\r\n\r\n60x6 Not Applicable\r',24,3,0,0,300,0,'','','','select Availability from Win32_Printer',5,6,0,'','','10',0,1,0.00,0.00,NULL,0.00,0.00,NULL,0,NULL,NULL,NULL,0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (533,'Serv_IISAdmin','IIS Administration Server service status.',26,2,0,0,300,0,'','','Running','Select State from Win32_Service WHERE name = 'IISAdmin'',3,6,0,'Administrador','6683','',0,1,0.00,0.00,'',0.00,0.00,'',0,'','','',0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (534,'Serv_MSSQL_server','Displays if MS SQL SERVER is running',27,2,0,0,0,0,'','','Running','select state from Win32_Service where name = "MSSQLSERVER"',7,6,0,'','','',0,1,0.00,0.00,'',0.00,0.00,'',0,'','','',0,0,0.0000000000000,'basic','','','','','',''); INSERT INTO `tnetwork_component` (`id_nc`, `name`, `description`, `id_group`, `type`, `max`, `min`, `module_interval`, `tcp_port`, `tcp_send`, `tcp_rcv`, `snmp_community`, `snmp_oid`, `id_module_group`, `id_modulo`, `id_plugin`, `plugin_user`, `plugin_pass`, `plugin_parameter`, `max_timeout`, `history_data`, `min_warning`, `max_warning`, `str_warning`, `min_critical`, `max_critical`, `str_critical`, `min_ff_event`, `custom_string_1`, `custom_string_2`, `custom_string_3`, `custom_integer_1`, `custom_integer_2`, `post_process`, `wizard_level`, `critical_instructions`, `warning_instructions`, `unknown_instructions`, `tags`, `disabled_types_event`, `module_macros`) VALUES (535,'SQLServer_DataFilesSizeKB','Sql database size in kb ',27,1,0,0,0,0,'','','','select state from Win32_Service where name = "MSSQLSERVER"',7,6,0,'','','',0,1,0.00,0.00,'',0.00,0.00,'',0,'','','',0,0,0.0000000000000,'basic','','','','','',''); @@ -1290,8 +1290,8 @@ INSERT INTO `tcontainer` SET `name` = 'Default graph container'; -- Dumping data for table `tlog_graph_models` -- INSERT INTO tlog_graph_models VALUES (1, 'Apache log model', - '^.*?\s+.*".*?\s(\/.*?)\?.*1.1"\s+(.*?)\s+(.*?)\s+', - 'pagina, html_err_code, _tiempo_', 1); + '^.*?\s+.*".*?\s(\/.*?)\?.*1.1"\s+(.*?)\s+(.*?)\s+', + 'pagina, html_err_code, _tiempo_', 1); INSERT INTO tlog_graph_models VALUES (2, 'Apache accesses per client and status', '(.*?)\ -.*1.1"\ (\d+)\ \d+', @@ -1347,13 +1347,13 @@ UPDATE `tnotification_source` SET `enabled`=1 WHERE `description` = 'System INSERT INTO `tpen` VALUES - (9,'cisco','Cisco System'), - (11,'hp','Hewlett Packard'), - (2021,'general_snmp','U.C. Davis, ECE Dept. Tom'), - (2636,'juniper','Juniper Networks'), - (3375,'f5','F5 Labs'), - (8072,'general_snmp','Net SNMP'), - (12356,'fortinet','Fortinet') + (9,'cisco','Cisco System'), + (11,'hp','Hewlett Packard'), + (2021,'general_snmp','U.C. Davis, ECE Dept. Tom'), + (2636,'juniper','Juniper Networks'), + (3375,'f5','F5 Labs'), + (8072,'general_snmp','Net SNMP'), + (12356,'fortinet','Fortinet') ; -- @@ -2500,7 +2500,7 @@ INSERT IGNORE INTO `tpen` VALUES (171,'dlink','D-Link Systems, Inc.'),(14988,'mi INSERT INTO `tncm_vendor` (`id`, `name`) VALUES (1,'Cisco'), - (2, 'D-Link Systems, Inc.'), + (2, 'D-Link Systems, Inc.'), (3, 'MikroTik'), (4, 'Alcatel-Lucent Enterprise'), (5, 'Ubiquiti Networks, Inc.'), @@ -2520,149 +2520,149 @@ INSERT INTO `tncm_vendor` (`id`, `name`) VALUES (19, 'Mikrotik'); INSERT INTO `tncm_model` VALUES - (1,1,'7200'), - (2,1,'Cisco-Generic'), - (3,15,'Juniper-Generic'), - (4,16,'Palo Alto-Generic'), - (5,17,'A10-Generic'), - (6,4,'Alcatel-Generic'), - (7,18,'Aruba-Generic'), - (8,19,'Mikrotik-Generic'); + (1,1,'7200'), + (2,1,'Cisco-Generic'), + (3,15,'Juniper-Generic'), + (4,16,'Palo Alto-Generic'), + (5,17,'A10-Generic'), + (6,4,'Alcatel-Generic'), + (7,18,'Aruba-Generic'), + (8,19,'Mikrotik-Generic'); INSERT INTO `tncm_template` VALUES - (1,'cisco-base','[\"1\"]','[\"1\"]'), - (2,'Cisco-Generic','[\"1\"]','[\"2\"]'), - (3,'Juniper-Generic','[\"15\"]','[\"3\"]'), - (4,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), - (5,'A10-Generic','[\"17\"]','[\"5\"]'), - (6,'Alcatel-Generic','[\"4\"]','[\"6\"]'), - (7,'Aruba-Generic','[\"18\"]','[\"7\"]'), - (8,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); + (1,'cisco-base','[\"1\"]','[\"1\"]'), + (2,'Cisco-Generic','[\"1\"]','[\"2\"]'), + (3,'Juniper-Generic','[\"15\"]','[\"3\"]'), + (4,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), + (5,'A10-Generic','[\"17\"]','[\"5\"]'), + (6,'Alcatel-Generic','[\"4\"]','[\"6\"]'), + (7,'Aruba-Generic','[\"18\"]','[\"7\"]'), + (8,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); INSERT INTO `tncm_script` VALUES (1,0,'enable expect:Password:\s* _enablepass_ exit'), (2,1,'enable expect:Password:\s* _enablepass_ term length 0 capture:show running-config exit '), - (3,2,'enable expect:Password:\s* _enablepass_ term length 0 config terminal _applyconfigbackup_ exit '), - (4,3,'enable expect:Password:\s* _enablepass_ term length 0 capture:show version | i IOS Software exit '), - (5,5,'enable expect:Password:\s* _enablepass_ term length 0 config term end end exit '), - (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? _DESTINATION_FILE_NAME_ show flash reload expect:confirm y config terminal boot system _DESTINATION_FILE_NAME_'), - (7,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), - (8,1,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'), - (9,2,'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'), - (10,3,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), - (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'), - (12,5,''), - (13,7,''), - (14,0,'expect:root@% cli\n exit\n'), - (15,1,'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'), - (16,2,'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'), - (17,3,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), - (18,4,'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'), - (19,5,''), - (20,7,''), - (21,0,'sleep:1 exit\n'), - (22,1,'set cli pager off \n capture:show config running\n exit\n'), - (23,2,'set cli terminal width 500\n set cli scripting-mode on\n configure\n _applyconfigbackup_\n commit\n'), - (24,3,'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'), - (25,4,'tftp import software from _TFTP_SERVER_IP_ file _FIRMWARE_NAME_\n request system software install version\n reboot\n exit\n'), - (26,5,''), - (27,7,''), - (28,0,'sleep:1 enable\n expect:Password:\s* _enablepass_\n'), - (29,1,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), - (30,2,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n _applyconfigbackup_\n exit\n'), - (31,3,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), - (32,4,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n expect:(config) restore _TFTP_SERVER_IP_/_FIRMWARE_NAME_\n expect:Password:\s* _enablepass_\n expect:skip port map yes\n expect: see the diff yes\n sleep:1 expect:Proceed with reboot yes\n expect:eof'), - (33,5,''), - (34,7,''), - (35,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), - (36,1,'enable\n expect:Password:\s* _enablepass_\n capture:admin display-config\n logout\n'), - (37,2,''), - (38,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'), - (39,4,''), - (40,5,''), - (41,7,''), - (42,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), - (43,1,'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), - (44,2,'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'), - (45,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), - (46,4,'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'), - (47,5,''), - (48,7,''), - (49,0,'sleep:1 exit\n\r'), - (50,1,'sleep:1 capture:system resource print\n\r exit\n\r'), - (51,2,'sleep:1 system backup load name=_nameBackup_ password=_passwordBackup_\n\r expect:Restore yes\n\r exit\n\r'), - (52,3,'sleep:1 capture:/system package print\n\r exit\n\r'), - (53,4,'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'), - (54,5,''), - (55,7,''); + (3,2,'enable expect:Password:\s* _enablepass_ term length 0 config terminal _applyconfigbackup_ exit '), + (4,3,'enable expect:Password:\s* _enablepass_ term length 0 capture:show version | i IOS Software exit '), + (5,5,'enable expect:Password:\s* _enablepass_ term length 0 config term end end exit '), + (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? _DESTINATION_FILE_NAME_ show flash reload expect:confirm y config terminal boot system _DESTINATION_FILE_NAME_'), + (7,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (8,1,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'), + (9,2,'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'), + (10,3,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), + (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'), + (12,5,''), + (13,7,''), + (14,0,'expect:root@% cli\n exit\n'), + (15,1,'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'), + (16,2,'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'), + (17,3,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), + (18,4,'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'), + (19,5,''), + (20,7,''), + (21,0,'sleep:1 exit\n'), + (22,1,'set cli pager off \n capture:show config running\n exit\n'), + (23,2,'set cli terminal width 500\n set cli scripting-mode on\n configure\n _applyconfigbackup_\n commit\n'), + (24,3,'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'), + (25,4,'tftp import software from _TFTP_SERVER_IP_ file _FIRMWARE_NAME_\n request system software install version\n reboot\n exit\n'), + (26,5,''), + (27,7,''), + (28,0,'sleep:1 enable\n expect:Password:\s* _enablepass_\n'), + (29,1,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), + (30,2,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n _applyconfigbackup_\n exit\n'), + (31,3,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), + (32,4,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n expect:(config) restore _TFTP_SERVER_IP_/_FIRMWARE_NAME_\n expect:Password:\s* _enablepass_\n expect:skip port map yes\n expect: see the diff yes\n sleep:1 expect:Proceed with reboot yes\n expect:eof'), + (33,5,''), + (34,7,''), + (35,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (36,1,'enable\n expect:Password:\s* _enablepass_\n capture:admin display-config\n logout\n'), + (37,2,''), + (38,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'), + (39,4,''), + (40,5,''), + (41,7,''), + (42,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), + (43,1,'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), + (44,2,'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'), + (45,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), + (46,4,'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'), + (47,5,''), + (48,7,''), + (49,0,'sleep:1 exit\n\r'), + (50,1,'sleep:1 capture:system resource print\n\r exit\n\r'), + (51,2,'sleep:1 system backup load name=_nameBackup_ password=_passwordBackup_\n\r expect:Restore yes\n\r exit\n\r'), + (52,3,'sleep:1 capture:/system package print\n\r exit\n\r'), + (53,4,'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'), + (54,5,''), + (55,7,''); INSERT INTO `tncm_template_scripts`(`id_template`, `id_script`) VALUES - (1,1), - (1,2), - (1,3), - (1,4), - (1,5), - (1,6), - (2,7), - (2,8), - (2,9), - (2,10), - (2,11), - (2,12), - (3,14), - (3,15), - (3,16), - (3,17), - (3,18), - (3,19), - (4,21), - (4,22), - (4,23), - (4,24), - (4,25), - (4,26), - (5,28), - (5,29), - (5,30), - (5,31), - (5,32), - (5,33), - (6,35), - (6,36), - (6,37), - (6,38), - (6,39), - (6,40), - (7,42), - (7,43), - (7,44), - (7,45), - (7,46), - (7,47), - (8,49), - (8,50), - (8,51), - (8,52), - (8,53), - (8,54); + (1,1), + (1,2), + (1,3), + (1,4), + (1,5), + (1,6), + (2,7), + (2,8), + (2,9), + (2,10), + (2,11), + (2,12), + (3,14), + (3,15), + (3,16), + (3,17), + (3,18), + (3,19), + (4,21), + (4,22), + (4,23), + (4,24), + (4,25), + (4,26), + (5,28), + (5,29), + (5,30), + (5,31), + (5,32), + (5,33), + (6,35), + (6,36), + (6,37), + (6,38), + (6,39), + (6,40), + (7,42), + (7,43), + (7,44), + (7,45), + (7,46), + (7,47), + (8,49), + (8,50), + (8,51), + (8,52), + (8,53), + (8,54); INSERT INTO `tncm_agent_data_template` VALUES - (1,'Cisco-Generic','[\"1\"]','[\"2\"]'), - (2,'Juniper-Generic','[\"15\"]','[\"3\"]'), - (3,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), - (4,'A10-Generic','[\"17\"]','[\"5\"]'), - (5,'Alcatel-Generic','[\"4\"]','[\"6\"]'), - (6,'Aruba-Generic','[\"18\"]','[\"7\"]'), - (7,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); + (1,'Cisco-Generic','[\"1\"]','[\"2\"]'), + (2,'Juniper-Generic','[\"15\"]','[\"3\"]'), + (3,'Palo Alto-Generic','[\"16\"]','[\"4\"]'), + (4,'A10-Generic','[\"17\"]','[\"5\"]'), + (5,'Alcatel-Generic','[\"4\"]','[\"6\"]'), + (6,'Aruba-Generic','[\"18\"]','[\"7\"]'), + (7,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); INSERT INTO `tncm_agent_data_template_scripts`(`id_agent_data_template`, `id_script`) VALUES - (1,13), - (2,20), - (3,27), - (4,34), - (5,41), - (6,48), - (7,55); + (1,13), + (2,20), + (3,27), + (4,34), + (5,41), + (6,48), + (7,55); INSERT INTO `talert_calendar` VALUES (1, 'Default', 0, 'Default calendar'); From 86804398fe8b619aab7a488b6728be41993082f2 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Mon, 6 Nov 2023 16:50:54 +0100 Subject: [PATCH 065/157] Fixed SQL issue --- pandora_console/pandoradb_data.sql | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 7e4bee1954..e7327e578b 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2516,8 +2516,7 @@ INSERT INTO `tncm_vendor` (`id`, `name`) VALUES (15, 'Juniper'), (16, 'Palo Alto'), (17, 'A10'), - (18, 'Aruba'), - (19, 'Mikrotik'); + (18, 'Aruba'); INSERT INTO `tncm_model` VALUES (1,1,'7200'), @@ -2527,7 +2526,7 @@ INSERT INTO `tncm_model` VALUES (5,17,'A10-Generic'), (6,4,'Alcatel-Generic'), (7,18,'Aruba-Generic'), - (8,19,'Mikrotik-Generic'); + (8,3,'Mikrotik-Generic'); INSERT INTO `tncm_template` VALUES (1,'cisco-base','[\"1\"]','[\"1\"]'), @@ -2537,7 +2536,7 @@ INSERT INTO `tncm_template` VALUES (5,'A10-Generic','[\"17\"]','[\"5\"]'), (6,'Alcatel-Generic','[\"4\"]','[\"6\"]'), (7,'Aruba-Generic','[\"18\"]','[\"7\"]'), - (8,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); + (8,'Mikrotik-Generic','[\"3\"]','[\"8\"]'); INSERT INTO `tncm_script` VALUES (1,0,'enable expect:Password:\s* _enablepass_ exit'), @@ -2653,7 +2652,7 @@ INSERT INTO `tncm_agent_data_template` VALUES (4,'A10-Generic','[\"17\"]','[\"5\"]'), (5,'Alcatel-Generic','[\"4\"]','[\"6\"]'), (6,'Aruba-Generic','[\"18\"]','[\"7\"]'), - (7,'Mikrotik-Generic','[\"19\"]','[\"8\"]'); + (7,'Mikrotik-Generic','[\"3\"]','[\"8\"]'); INSERT INTO `tncm_agent_data_template_scripts`(`id_agent_data_template`, `id_script`) VALUES (1,13), From aaa590b65fd8ac0ee75e4b2e0ca52c9f7ecca8e6 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 7 Nov 2023 09:20:48 +0100 Subject: [PATCH 066/157] VC Public links pandora_enterprise#12329 --- pandora_console/ajax.php | 4 +- .../javascript/pandora_visual_console.js | 4 +- .../rest-api/models/VisualConsole/Item.php | 8 ++-- .../operation/visual_console/public_view.php | 48 +++++++++---------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/pandora_console/ajax.php b/pandora_console/ajax.php index b3b9463ee6..a5dcf2cb0d 100644 --- a/pandora_console/ajax.php +++ b/pandora_console/ajax.php @@ -183,7 +183,9 @@ if (isset($config['force_instant_logout']) === true $_SESSION = []; session_destroy(); header_remove('Set-Cookie'); - setcookie(session_name(), $_COOKIE[session_name()], (time() - 4800), '/'); + if (isset($_COOKIE[session_name()]) === true) { + setcookie(session_name(), $_COOKIE[session_name()], (time() - 4800), '/'); + } if ($config['auth'] === 'saml' && empty($public_hash) === true) { include_once $config['saml_path'].'simplesamlphp/lib/_autoload.php'; diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index adcbd3ce0c..0e16bb303f 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -808,8 +808,8 @@ function loadVisualConsoleData( getVisualConsoleItems: 1, size: size, visualConsoleId: vcId, - id_user: typeof id_user == undefined ? id_user : null, - auth_hash: typeof hash == undefined ? hash : null, + id_user: typeof id_user !== undefined ? id_user : null, + auth_hash: typeof hash !== undefined ? hash : null, mode: mode, widthScreen: widthScreen }, diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index 0db9d999c2..411d605c0e 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1196,7 +1196,7 @@ class Item extends CachedModel 'operation/visual_console/view', ['id' => $vcId], // No autologin from the public view. - !$config['public_view'], + !$config['public_access'], $mobile_navigation, [ 'page' => 'visualmap', @@ -1302,7 +1302,7 @@ class Item extends CachedModel 'enterprise/operation/services/services', ['id_service' => $serviceId], // No autologin from the public view. - !$config['public_view'] + !$config['public_access'] ); } else { // A regular module. @@ -1312,7 +1312,7 @@ class Item extends CachedModel 'operation/agentes/status_monitor', ['id_module' => $moduleId], // No autologin from the public view. - !((isset($config['public_view']) === true) ? $config['public_view'] : false), + !((isset($config['public_access']) === true) ? $config['public_access'] : false), $mobile_navigation, [ 'id' => $moduleId, @@ -1377,7 +1377,7 @@ class Item extends CachedModel 'operation/agentes/ver_agente', ['id_agente' => $agentId], // No autologin from the public view. - !$config['public_view'], + !$config['public_access'], $mobile_navigation, [ 'id' => $agentId, diff --git a/pandora_console/operation/visual_console/public_view.php b/pandora_console/operation/visual_console/public_view.php index 46dd4e43b4..64529133b4 100644 --- a/pandora_console/operation/visual_console/public_view.php +++ b/pandora_console/operation/visual_console/public_view.php @@ -33,7 +33,7 @@ require_once $config['homedir'].'/vendor/autoload.php'; ui_require_css_file('register', 'include/styles/', true); // Connection lost alert. -ui_require_javascript_file('connection_check', 'include/javascript/', true); +// ui_require_javascript_file('connection_check', 'include/javascript/', true); set_js_value('absolute_homeurl', ui_get_full_url(false, false, false, false)); $conn_title = __('Connection with console has been lost'); $conn_text = __('Connection to the console has been lost. Please check your internet connection.'); @@ -47,7 +47,7 @@ global $vc_public_view; global $config; $vc_public_view = true; -$config['public_view'] = true; +$config['public_access'] = true; // This starts the page head. In the call back function, // things from $page['head'] array will be processed into the head. @@ -62,12 +62,6 @@ require_once 'include/functions_visual_map.php'; $hash = (string) get_parameter('hash'); -// For public link issue. -$force_instant_logout = true; -if (isset($config['id_user']) === true) { - $force_instant_logout = false; -} - // Check input hash. // DO NOT move it after of get parameter user id. if (User::validatePublicHash($hash) !== true) { @@ -256,17 +250,17 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( if (menuLinks !== null) { menuLinks.forEach(function (menuLink) { menuLink.href = menuLink.href.replace(regex, replacement); - menuLink.href = menuLink.href.replace( - regex_hash, - replacement_hash - ); + //menuLink.href = menuLink.href.replace( + // regex_hash, + // replacement_hash + //); }); } // Change the URL (if the browser has support). if ("history" in window) { var href = window.location.href.replace(regex, replacement); - href = href.replace(regex_hash, replacement_hash); + //href = href.replace(regex_hash, replacement_hash); window.history.replaceState({}, document.title, href); } } @@ -321,20 +315,24 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( } } }); - - - // No click enabled when user not logged. - $( "a" ).on( "click", function( event ) { - event.preventDefault(); - $('#visual-console-container').removeClass('is-updating'); - $('.div-visual-console-spinner').remove(); - }); - 0) { + ob_end_flush(); } \ No newline at end of file From 194a3ca8c4668d73dceb3f2d472b8d6a56c3fb8e Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 7 Nov 2023 12:36:05 +0100 Subject: [PATCH 067/157] #12381 fix dropdown select2 modal position --- .../godmode/agentes/module_manager_editor_common.php | 2 +- pandora_console/include/styles/pandora.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/module_manager_editor_common.php b/pandora_console/godmode/agentes/module_manager_editor_common.php index ca74b7d171..de08a299de 100644 --- a/pandora_console/godmode/agentes/module_manager_editor_common.php +++ b/pandora_console/godmode/agentes/module_manager_editor_common.php @@ -1387,7 +1387,7 @@ $table_advanced->data['made_enabled'][0] = html_print_checkbox_switch( 'made_enabled', 1, (bool) $made_enabled, - false, + true, false, '', false, diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 63179618b1..dd6723dfb2 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -12798,3 +12798,7 @@ tr.shown td.details-control { position: relative; top: -92px; } + +.tags_selected_container > span.select2 { + background-color: white !important; +} From 8700d1146117c2b303bd9ea3eb238ff6355bea6c Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Tue, 7 Nov 2023 13:13:45 +0100 Subject: [PATCH 068/157] Fixed agent data scripts on pandoradb_data.sql --- pandora_console/pandoradb_data.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index e7327e578b..123940c22e 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2551,49 +2551,49 @@ INSERT INTO `tncm_script` VALUES (10,3,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'), (12,5,''), - (13,7,''), + (13,7,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), (14,0,'expect:root@% cli\n exit\n'), (15,1,'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'), (16,2,'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'), (17,3,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), (18,4,'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'), (19,5,''), - (20,7,''), + (20,7,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), (21,0,'sleep:1 exit\n'), (22,1,'set cli pager off \n capture:show config running\n exit\n'), (23,2,'set cli terminal width 500\n set cli scripting-mode on\n configure\n _applyconfigbackup_\n commit\n'), (24,3,'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'), (25,4,'tftp import software from _TFTP_SERVER_IP_ file _FIRMWARE_NAME_\n request system software install version\n reboot\n exit\n'), (26,5,''), - (27,7,''), + (27,7,'set cli pager off \n capture:show system info | match app-version:\n sleep:1 expect:app-version:\s* exit \n'), (28,0,'sleep:1 enable\n expect:Password:\s* _enablepass_\n'), (29,1,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), (30,2,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n _applyconfigbackup_\n exit\n'), (31,3,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), (32,4,'sleep:1 enable\n expect:Password:\s* _enablepass_\n configure\n expect:(config) restore _TFTP_SERVER_IP_/_FIRMWARE_NAME_\n expect:Password:\s* _enablepass_\n expect:skip port map yes\n expect: see the diff yes\n sleep:1 expect:Proceed with reboot yes\n expect:eof'), (33,5,''), - (34,7,''), + (34,7,'sleep:1 enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), (35,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), (36,1,'enable\n expect:Password:\s* _enablepass_\n capture:admin display-config\n logout\n'), (37,2,''), (38,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'), (39,4,''), (40,5,''), - (41,7,''), + (41,7,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n logout\n'), (42,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), (43,1,'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), (44,2,'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'), (45,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), (46,4,'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'), (47,5,''), - (48,7,''), + (48,7,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), (49,0,'sleep:1 exit\n\r'), (50,1,'sleep:1 capture:system resource print\n\r exit\n\r'), (51,2,'sleep:1 system backup load name=_nameBackup_ password=_passwordBackup_\n\r expect:Restore yes\n\r exit\n\r'), (52,3,'sleep:1 capture:/system package print\n\r exit\n\r'), (53,4,'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'), (54,5,''), - (55,7,''); + (55,7,'sleep:1 capture:/system package print\n\r exit\n\r'); INSERT INTO `tncm_template_scripts`(`id_template`, `id_script`) VALUES (1,1), From 46a74c2e220efaad8e520bef24cf61bdb33c1378 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 7 Nov 2023 13:35:08 +0100 Subject: [PATCH 069/157] #12345 Fixed enable/disable --- .../godmode/agentes/configurar_agente.php | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 88d4b0e4ed..baf0a24524 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -2149,6 +2149,28 @@ if ($update_module || $create_module || ($module_in_policy && !$module_linked) ) { if ($success_action > 0) { + if (empty($old_configuration_data) === true + && empty($configuration_data) === true && $disabled === '0' + && ($enable_module || $disable_module) + ) { + $modulo_nombre = io_safe_output( + db_get_value( + 'nombre', + 'tagente_modulo', + 'id_agente_modulo', + (empty($disable_module) === false) ? $disable_module : $enable_module + ) + ); + + $old_configuration_data = config_agents_get_module_from_conf( + $id_agente, + $modulo_nombre + ); + $configuration_data = $old_configuration_data; + + $disabled = (empty($disable_module) === false) ? true : false; + } + enterprise_hook( 'config_agents_write_module_in_conf', [ @@ -2297,7 +2319,6 @@ if ($disable_module) { $modulo_nombre = io_safe_output($modulo_nombre['nombre']); if ($result === NOERR) { - enterprise_hook('config_agents_disable_module_conf', [$id_agente, $disable_module]); db_pandora_audit( AUDIT_LOG_MODULE_MANAGEMENT, 'Disable #'.$disable_module.' | '.$modulo_nombre.' | '.$agent['alias'] From 2d7895b39b7a4a258da9698bd133185b39220247 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Tue, 7 Nov 2023 15:22:22 +0100 Subject: [PATCH 070/157] #8365 Fixed ncm reports of html type --- .../godmode/reporting/reporting_builder.item_editor.php | 7 +++++++ pandora_console/include/functions_reporting_html.php | 7 ++++++- pandora_console/include/styles/pandora.css | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index f50b451683..c16cbd4a05 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -8146,10 +8146,17 @@ function filterNcmAgentChange() { }, success: function(data) { $("#agent_ncm").empty(); + var optionAny = $("") + .attr("value",0) + .html("Any"); + // Add any option. + $("#agent_ncm").append(optionAny); + data.map(item => { var option = $("") .attr("value", item.id_agent) .html(item.alias); + // Add agents options. $("#agent_ncm").append(option); }); }, diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index a74fcb4a47..d2d4f5850f 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -7437,6 +7437,7 @@ function reporting_html_ncm_backups($table, $item, $pdf=0) ui_require_javascript_file('highlight.min'); ui_require_javascript_file('highlightjs-line-numbers.min'); ui_require_javascript_file('languages/plaintext.min'); + ui_require_javascript_file('jquery', ENTERPRISE_DIR.'/include/javascript/'); ui_require_javascript_file('functions_ncm', ENTERPRISE_DIR.'/include/javascript/'); // Create table diff. @@ -7448,6 +7449,8 @@ function reporting_html_ncm_backups($table, $item, $pdf=0) $table_ncm->head = []; $table_ncm->head[0] = __('Date'); $table_ncm->head[1] = __('Diff'); + $table_ncm->caption = $item['caption']; + $table_ncm->id = 'ncm_backups'; $table_ncm->data = []; @@ -7459,7 +7462,9 @@ function reporting_html_ncm_backups($table, $item, $pdf=0) ]; } - return $table->data[] = html_print_table( + $table->colspan['ncm_backups']['cell'] = 3; + $table->cellstyle['ncm_backups']['cell'] = 'text-align: left;'; + $table->data['ncm_backups']['cell'] = html_print_table( $table_ncm, true ); diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 63179618b1..7e9669bc21 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -12798,3 +12798,7 @@ tr.shown td.details-control { position: relative; top: -92px; } + +#ncm_backups > caption > h4 { + color: black; +} From 14fff848760653ab06d9b61f2b65e99479dcf873 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 8 Nov 2023 11:56:32 +0100 Subject: [PATCH 071/157] queries remove field transactional_agent pandora_enterprise#12334 --- pandora_console/extras/mr/67.sql | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 pandora_console/extras/mr/67.sql diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql new file mode 100644 index 0000000000..0a5fcd9fb0 --- /dev/null +++ b/pandora_console/extras/mr/67.sql @@ -0,0 +1,13 @@ +START TRANSACTION; + +SET @exist = (SELECT count(*) FROM information_schema.columns WHERE TABLE_NAME='tmetaconsole_agent' AND COLUMN_NAME='transactional_agent' AND table_schema = DATABASE()); +SET @sqlstmt = IF (@exist>0, 'ALTER TABLE `tmetaconsole_agent` DROP COLUMN `transactional_agent`', 'SELECT ""'); +prepare stmt from @sqlstmt; +execute stmt; + +SET @exist = (SELECT count(*) FROM information_schema.columns WHERE TABLE_NAME='tagente' AND COLUMN_NAME='transactional_agent' AND table_schema = DATABASE()); +SET @sqlstmt = IF (@exist>0, 'ALTER TABLE `tagente` DROP COLUMN `transactional_agent`', 'SELECT ""'); +prepare stmt from @sqlstmt; +execute stmt; + +COMMIT; From 98bc73a83ab0b6308703b90132187392a9a8e2ae Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Wed, 8 Nov 2023 14:40:47 +0100 Subject: [PATCH 072/157] #8365 Fix ncm report for multiple agents --- pandora_console/extras/mr/67.sql | 3 + .../reporting_builder.item_editor.php | 6 +- .../godmode/reporting/reporting_builder.php | 11 ++- .../include/functions_reporting_html.php | 71 ++++++++++--------- pandora_console/pandoradb.sql | 1 + 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 2a604941e0..2913cd8248 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -29,6 +29,9 @@ ADD COLUMN `agent_data_cron_interval` VARCHAR(100) NULL DEFAULT '' AFTER `cron_i ALTER TABLE `tncm_agent` ADD COLUMN `agent_data_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `event_on_change`; +ALTER TABLE `treport_content` +ADD COLUMN `ncm_agents` MEDIUMTEXT NULL AFTER `status_of_check`; + -- Add new vendor and model SET @vendor_name = 'Cisco'; SET @model_name = 'Cisco-Generic'; diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index c16cbd4a05..49c7ac7f80 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -1036,12 +1036,12 @@ switch ($action) { break; case 'ncm': - $id_agent_ncm = $item['id_agent']; + $id_agent_ncm = json_decode($item['ncm_agents']); $ncm_group = $item['id_group']; break; case 'ncm_backups': - $id_agent_ncm = $item['id_agent']; + $id_agent_ncm = json_decode($item['ncm_agents']); $ncm_group = $item['id_group']; break; @@ -1973,7 +1973,7 @@ if (is_metaconsole() === true) { $all_agents = agents_get_agents_selected($ncm_group); html_print_select( $all_agents, - 'agent_ncm', + 'agent_ncm[]', $id_agent_ncm, '', __('Any'), diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index f155a89831..e449b766ff 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -2046,13 +2046,15 @@ switch ($action) { break; case 'ncm_backups': - $values['id_agent'] = get_parameter('agent_ncm'); + $agents_ncm = get_parameter('agent_ncm'); + $values['ncm_agents'] = json_encode($agents_ncm); $values['id_group'] = get_parameter('ncm_group'); $good_format = true; break; case 'ncm': - $values['id_agent'] = get_parameter('agent_ncm'); + $agents_ncm = get_parameter('agent_ncm'); + $values['ncm_agents'] = json_encode($agents_ncm); $values['id_group'] = get_parameter('ncm_group'); $good_format = true; break; @@ -2996,12 +2998,15 @@ switch ($action) { break; case 'ncm_backups': - $values['id_agent'] = get_parameter('agent_ncm'); + $agents_ncm = get_parameter('agent_ncm'); + $values['ncm_agents'] = json_encode($agents_ncm); $values['id_group'] = get_parameter('ncm_group'); $good_format = true; break; case 'ncm': + $agents_ncm = get_parameter('agent_ncm'); + $values['ncm_agents'] = json_encode($agents_ncm); $values['id_agent'] = get_parameter('agent_ncm'); $values['id_group'] = get_parameter('ncm_group'); $good_format = true; diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index d2d4f5850f..0fbae441ec 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -7441,45 +7441,52 @@ function reporting_html_ncm_backups($table, $item, $pdf=0) ui_require_javascript_file('functions_ncm', ENTERPRISE_DIR.'/include/javascript/'); // Create table diff. - $table_ncm = new stdClass(); - $table_ncm->width = '100%'; - $table_ncm->class = 'info_table'; - $table_ncm->styleTable = 'table-layout: fixed;'; - $table_ncm->headstyle[0] = 'width: 250px'; - $table_ncm->head = []; - $table_ncm->head[0] = __('Date'); - $table_ncm->head[1] = __('Diff'); - $table_ncm->caption = $item['caption']; - $table_ncm->id = 'ncm_backups'; - - $table_ncm->data = []; - - if ($pdf === 0) { - foreach ($item['data'] as $key => $row) { - $table_ncm->data[] = [ - $row['updated_at'], - $row['diff'], - ]; + foreach ($item['data'] as $ncm_agent_key => $ncm_agent) { + $table_ncm = new stdClass(); + if ($pdf === 1) { + $table_ncm->width = '100%'; } - $table->colspan['ncm_backups']['cell'] = 3; - $table->cellstyle['ncm_backups']['cell'] = 'text-align: left;'; - $table->data['ncm_backups']['cell'] = html_print_table( - $table_ncm, - true - ); - } else { - foreach ($item['data'] as $key => $row) { - $table_ncm->data[] = [ - $row['updated_at'], - ($row['diffstr'] === '') ? $row['diff'] : str_replace("\n", '
', $row['diffstr']), - ]; + $table_ncm->class = 'info_table'; + $table_ncm->styleTable = 'table-layout: fixed;'; + $table_ncm->headstyle[0] = 'width: 250px'; + $table_ncm->head = []; + $table_ncm->head[0] = __('Date'); + $table_ncm->head[1] = __('Diff'); + $table_ncm->id = 'ncm_backups'; + $table_ncm->name = 'ncm_backups'; + $table_ncm->title = $ncm_agent['caption']; + $row = []; + foreach ($ncm_agent['data'] as $ncm_agent_data) { + if ($pdf === 1) { + $row[] = [ + $ncm_agent_data['updated_at'], + ($ncm_agent_data['diffstr'] === '') ? $ncm_agent_data['diff'] : str_replace("\n", '
', $ncm_agent_data['diffstr']), + ]; + } else { + $row[] = [ + $ncm_agent_data['updated_at'], + $ncm_agent_data['diff'], + ]; + } + + $table_ncm->data = $row; } - return html_print_table( + $table->colspan[$ncm_agent_key]['cell'] = 3; + $table->cellstyle[$ncm_agent_key]['cell'] = 'text-align: left;'; + $table->data[$ncm_agent_key]['cell'] = html_print_table( $table_ncm, true ); } + if ($pdf === 1) { + $table->width = '100%'; + return html_print_table( + $table, + true + ); + } + } diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 8b83b26011..334afe02b2 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1645,6 +1645,7 @@ CREATE TABLE IF NOT EXISTS `treport_content` ( `cat_security_hardening` INT NOT NULL DEFAULT 0, `ignore_skipped` INT NOT NULL DEFAULT 0, `status_of_check` TINYTEXT, + `ncm_agents` MEDIUMTEXT, PRIMARY KEY(`id_rc`), FOREIGN KEY (`id_report`) REFERENCES treport(`id_report`) ON UPDATE CASCADE ON DELETE CASCADE From f773230ebf3851f65c85f339017650d817c5f8fc Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Thu, 9 Nov 2023 16:18:06 -0500 Subject: [PATCH 073/157] Modify pandora_cps_enabled function --- pandora_server/lib/PandoraFMS/Core.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index afd3e8e865..797268f032 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -5778,9 +5778,9 @@ sub pandora_inhibit_alerts { sub pandora_cps_enabled($$) { my ($agent, $module) = @_; - return 1 if ($agent->{'cps'} > 0); + return 1 if ($agent->{'cps'} >= 0); - return 1 if ($module->{'cps'} > 0); + return 1 if ($module->{'cps'} >= 0); return 0; } From 5eb5df61906cdf0f1e98aa6213af79660fa00eaf Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Fri, 10 Nov 2023 13:13:57 +0100 Subject: [PATCH 074/157] change url pandorarc name --- pandora_console/godmode/setup/setup.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 0fd6bebff8..c0d59fbde9 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -184,7 +184,7 @@ $buttons['ITSM'] = [ $buttons['ehorus'] = [ 'active' => false, - 'text' => ''.html_print_image( + 'text' => ''.html_print_image( 'images/RC.png', true, [ @@ -297,7 +297,7 @@ switch ($section) { $help_header = 'setup_flow_tab'; break; - case 'ehorus': + case 'pandorarc': $buttons['ehorus']['active'] = true; $subpage = __('Pandora RC'); $help_header = 'setup_ehorus_tab'; @@ -438,7 +438,7 @@ switch ($section) { include_once $config['homedir'].'/godmode/setup/setup_visuals.php'; break; - case 'ehorus': + case 'pandorarc': include_once $config['homedir'].'/godmode/setup/setup_ehorus.php'; break; From ad90fb74b2b3615cbb2be60ba5bc08b0e2a8e752 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 13 Nov 2023 10:42:25 +0100 Subject: [PATCH 075/157] #12390 Fixed group --- pandora_console/include/class/Heatmap.class.php | 6 +++++- pandora_console/include/lib/Dashboard/Widgets/heatmap.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php index 05d6152030..3ed4b3cc72 100644 --- a/pandora_console/include/class/Heatmap.class.php +++ b/pandora_console/include/class/Heatmap.class.php @@ -549,8 +549,12 @@ class Heatmap global $config; $filter_group = ''; - if (empty($this->filter) === false && current($this->filter) != -1) { + if (empty($this->filter) === false && current($this->filter) != -1 + && implode(',', $this->filter) !== '' + ) { $filter_group = 'AND am.id_module_group IN ('.implode(',', $this->filter).')'; + } else { + return false; } $filter_name = ''; diff --git a/pandora_console/include/lib/Dashboard/Widgets/heatmap.php b/pandora_console/include/lib/Dashboard/Widgets/heatmap.php index 363ea1489e..e199a80ad8 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/heatmap.php +++ b/pandora_console/include/lib/Dashboard/Widgets/heatmap.php @@ -320,6 +320,10 @@ class HeatmapWidget extends Widget $module_groups[$module_group['id_mg']] = $module_group['name']; } + if (empty($values['module_groups'][0]) === true) { + $values['module_groups'][0] = 0; + } + $inputs[] = [ 'label' => __('Module group'), 'style' => ($values['type'] === '2') ? '' : 'display:none', @@ -332,7 +336,7 @@ class HeatmapWidget extends Widget 'return' => true, 'multiple' => true, 'nothing' => __('Not assigned'), - 'nothing_value' => 0, + 'nothing_value' => '0', ], ]; From 04649dee00d8d0b25ffa8cab410d7f687a6768d3 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Mon, 13 Nov 2023 13:41:47 +0100 Subject: [PATCH 076/157] #12168 Fixed sql bringing main services --- .../include/class/TreeService.class.php | 16 ++++++---------- .../include/javascript/tree/TreeController.js | 1 + 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php index b218468de3..a627794f0e 100644 --- a/pandora_console/include/class/TreeService.class.php +++ b/pandora_console/include/class/TreeService.class.php @@ -738,19 +738,15 @@ class TreeService extends Tree $filterResult = db_get_all_rows_sql($sqlFilter); + $services = []; foreach ($filterResult as $key => $result) { - $ancestors = services_get_services_ancestors($result['id']); - $idAncestors = implode(',', $ancestors); - $numAncestors = count($ancestors); - if ($numAncestors > 1) { - $whereAncestors = ' AND tse.id_service_child in ('.$idAncestors.')'; - } else if ($numAncestors == 1) { - $whereAncestors = ' AND ts.id ='.$idAncestors; - } else { - $whereAncestors = ' AND ts.id ='.$result['id']; - } + $services_ancestors = services_get_services_ancestors($result['id']); + $services[] = array_pop($services_ancestors); } + $services_list = array_unique($services, SORT_NUMERIC); + $whereAncestors = ' AND tse.id_service IN ('.implode(',', $services_list).')'; + return $whereAncestors; } diff --git a/pandora_console/include/javascript/tree/TreeController.js b/pandora_console/include/javascript/tree/TreeController.js index d8a6daf468..4f850e32d5 100644 --- a/pandora_console/include/javascript/tree/TreeController.js +++ b/pandora_console/include/javascript/tree/TreeController.js @@ -1561,6 +1561,7 @@ var TreeController = { * Filter the tree based on a search criterion */ function _filterItems(rawTree, searched) { + console.log(rawTree); const ancestors = []; const father = []; const newTree = []; From c2bf6e6bf52614c88448dd83e4035cfb65c93b40 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Mon, 13 Nov 2023 17:34:38 +0100 Subject: [PATCH 077/157] fix pgrep process in ubuntu --- pandora_console/include/functions_cron_task.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_cron_task.php b/pandora_console/include/functions_cron_task.php index 9de0520ccd..40a6e159cc 100644 --- a/pandora_console/include/functions_cron_task.php +++ b/pandora_console/include/functions_cron_task.php @@ -459,17 +459,17 @@ function cron_task_start_gotty(bool $restart_mode=true) // Check prev process running and kill it (only if port changed in setup params). if (empty($config['restart_gotty_next_cron_port']) === false) { - config_update_value('restart_gotty_next_cron_port', ''); - - $prevProcessRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'"); + $prevProcessRunning = shell_exec("pgrep -af 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."' | grep -v 'pgrep'"); if (empty($prevProcessRunning) === false) { shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'"); } + + config_update_value('restart_gotty_next_cron_port', ''); } // Check if gotty is running on the configured port. - $processRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_port']."'"); + $processRunning = shell_exec("pgrep -af 'pandora_gotty.*-p ".$config['gotty_port']."' | grep -v 'pgrep'"); $start_proc = true; From f725752f3201b52645c6360cddbad5a6e5d2b45e Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Tue, 14 Nov 2023 12:33:29 +0100 Subject: [PATCH 078/157] #12168 fixed filter in service tree genealogy --- .../include/javascript/tree/TreeController.js | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/pandora_console/include/javascript/tree/TreeController.js b/pandora_console/include/javascript/tree/TreeController.js index 4f850e32d5..06274600ed 100644 --- a/pandora_console/include/javascript/tree/TreeController.js +++ b/pandora_console/include/javascript/tree/TreeController.js @@ -1561,27 +1561,21 @@ var TreeController = { * Filter the tree based on a search criterion */ function _filterItems(rawTree, searched) { - console.log(rawTree); const ancestors = []; const father = []; const newTree = []; + const tmpTree = []; rawTree.map((raw, index) => { if (raw.type === "services") { if (raw.servicesChildren.length !== 0) { // search at parent level - let findedPadre = raw.description.indexOf(searched); + let descr = raw.description.toLowerCase(); + let sear = searched.toLowerCase(); + let findedPadre = descr.indexOf(sear); if (findedPadre === -1) { - // search for children - raw.servicesChildren.map(child => { - let finded = child.description.indexOf(searched); - if (finded === 0) { - //we keep the father of the child that contains it - ancestors.push(child.ancestor); - } else if (findedPadre === -1 && finded === -1) { - //we save the father - father.push(raw.id); - } - }); + father.push(raw.id); + } else if (findedPadre >= 0) { + ancestors.push(raw.id); } else { //we mark the father as found controller.finded = 1; @@ -1607,9 +1601,16 @@ var TreeController = { if (father.length >= 1) { let filterfather = [...new Set(father)]; - const newTree = rawTree.filter( - item => !filterfather.includes(item.id) - ); + + filterfather.map(father => { + tmpTree.push(rawTree.filter(raw => raw.id == father)); + }); + + let tree = [...new Set(tmpTree)]; + tree.map(item => { + let tmpItem = item[0]; + newTree.push(tmpItem); + }); return newTree; } From 4fec6a1ccbef81a0c4bbe9721d32ff635f6a73f9 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 14 Nov 2023 17:04:31 +0100 Subject: [PATCH 079/157] #12296 restyling agent detail filters --- pandora_console/include/styles/pandora.css | 16 ++++++++ .../operation/agentes/estado_agente.php | 41 +++++++++++++------ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 7c740bba2b..43b3823153 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -10214,6 +10214,14 @@ div#err_msg_centralised { align-items: flex-start; } +.div-col-4 { + width: 25%; + display: flex; + flex-direction: column; + align-items: flex-start; + margin-top: 10px; +} + .div-span { width: 100%; color: #161628; @@ -12792,3 +12800,11 @@ tr.shown td.details-control { position: relative; top: -92px; } + +.span_as_label { + font-size: 13px; + line-height: 16px; + color: #161628; + font-weight: bold; + margin-bottom: 10px; +} diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php index d126b19144..d3543b0a7c 100644 --- a/pandora_console/operation/agentes/estado_agente.php +++ b/pandora_console/operation/agentes/estado_agente.php @@ -320,6 +320,7 @@ $table->size[0] = '50%'; $table->size[1] = '50%'; $table->class = 'filter-table-adv'; +$table->cellstyle['group'][0] = 'display: flex;width: 95% !important;'; $table->data['group'][0] = html_print_label_input_block( __('Group'), html_print_select_groups( @@ -336,7 +337,8 @@ $table->data['group'][0] = html_print_label_input_block( true, '', false - ) + ), + ['div_class' => 'w100p'] ); $table->data['group'][0] .= html_print_label_input_block( @@ -346,11 +348,7 @@ $table->data['group'][0] .= html_print_label_input_block( 1, $recursion, true - ), - [ - 'div_class' => 'add-input-reverse', - 'label_class' => 'label-thin', - ] + ) ); $table->data['group'][1] = html_print_label_input_block( @@ -405,7 +403,7 @@ foreach ($pre_fields as $key => $value) { $table->data[1][0] = html_print_label_input_block( __('Operating System'), - html_print_select($fields, 'os', $os, '', 'All', 0, true) + html_print_select($fields, 'os', $os, '', 'All', 0, true, false, true, 'w100p', false, 'width:100%') ); $table->data[1][1] = html_print_label_input_block( @@ -428,9 +426,22 @@ if (function_exists('policies_get_policies') === true) { } } -$table->data[2][0] = html_print_label_input_block( +$table->data[2][1] = html_print_label_input_block( __('Policies'), - html_print_select($fields, 'policies[]', $policies, '', 'All', 0, true, true) + html_print_select( + $fields, + 'policies', + $policies, + 'this.form.submit()', + __('All'), + 0, + true, + false, + true, + 'w100p', + false, + 'width: 100%' + ) ); $custom_fields = db_get_all_fields_in_table('tagent_custom_fields'); @@ -438,7 +449,7 @@ if ($custom_fields === false) { $custom_fields = []; } -$div_custom_fields = '
'; +$div_custom_fields = '
'; foreach ($custom_fields as $custom_field) { $custom_field_value = ''; if (empty($ag_custom_fields) === false) { @@ -448,10 +459,10 @@ foreach ($custom_fields as $custom_field) { } } - $div_custom_fields .= '
'; + $div_custom_fields .= '
'; $div_custom_fields .= '
'; - $div_custom_fields .= ''.$custom_field['name'].''; + $div_custom_fields .= ''.$custom_field['name'].''; $div_custom_fields .= '
'; $div_custom_fields .= '
'; @@ -890,7 +901,11 @@ if ($group_id > 0) { $groups = array_keys($user_groups); } -$all_policies = in_array(0, ($policies ?? [])); +if (is_array($policies)) { + $all_policies = in_array(0, ($policies ?? [])); +} else { + $all_policies = []; +} $id_os_sql = ''; $policies_sql = ''; From 78a5a3bfe8116b0c10b11b8c725301a0eaf102ae Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Tue, 14 Nov 2023 17:12:22 +0100 Subject: [PATCH 080/157] #12168 Hierarchy is added to the title of services --- .../include/class/TreeService.class.php | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php index a627794f0e..177a45a54f 100644 --- a/pandora_console/include/class/TreeService.class.php +++ b/pandora_console/include/class/TreeService.class.php @@ -333,6 +333,7 @@ class TreeService extends Tree $services[$service['id']]['id'] = $service['id']; $services[$service['id']]['description'] = $service['description']; $services[$service['id']]['serviceDetail'] = 'index.php?sec=network&sec2=enterprise/operation/services/services&tab=service_map&id_service='.(int) $service['id']; + $services[$service['id']]['title'] = services_get_parents_title((int) $service['id']); } return $services; @@ -732,20 +733,8 @@ class TreeService extends Tree if (isset($this->filter['searchService']) === true && empty($this->filter['searchService']) === false ) { - $sqlFilter = 'SELECT ts.id FROM tservice ts - where ts.name LIKE "%'.$this->filter['searchService'].'%" - OR ts.description LIKE "%'.$this->filter['searchService'].'%"'; - - $filterResult = db_get_all_rows_sql($sqlFilter); - - $services = []; - foreach ($filterResult as $key => $result) { - $services_ancestors = services_get_services_ancestors($result['id']); - $services[] = array_pop($services_ancestors); - } - - $services_list = array_unique($services, SORT_NUMERIC); - $whereAncestors = ' AND tse.id_service IN ('.implode(',', $services_list).')'; + $whereAncestors = ' AND ts.name LIKE "%'.$this->filter['searchService'].'%" + OR ts.description LIKE "%'.$this->filter['searchService'].'%"'; return $whereAncestors; } From 4579fe21d98e1215413afc262154542271e3deaa Mon Sep 17 00:00:00 2001 From: alejandro Date: Wed, 15 Nov 2023 14:24:42 +0100 Subject: [PATCH 081/157] update version in mr --- pandora_console/extras/mr/67.sql | 6 ++++++ pandora_console/pandoradb_data.sql | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 pandora_console/extras/mr/67.sql diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql new file mode 100644 index 0000000000..48d44b6255 --- /dev/null +++ b/pandora_console/extras/mr/67.sql @@ -0,0 +1,6 @@ +START TRANSACTION; + +UPDATE `tdiscovery_apps` SET `version` = '1.2' WHERE `short_name` = 'pandorafms.vmware'; + +COMMIT; + diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 9ce5355361..6813173de7 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2653,7 +2653,7 @@ SET @short_name = 'pandorafms.vmware'; SET @name = 'VMware'; SET @section = 'app'; SET @description = 'Monitor ESXi hosts, datastores and VMs from a specific datacenter'; -SET @version = '1.1'; +SET @version = '1.2'; INSERT IGNORE INTO `tdiscovery_apps` (`id_app`, `short_name`, `name`, `section`, `description`, `version`) VALUES ('', @short_name, @name, @section, @description, @version); SELECT @id_app := `id_app` FROM `tdiscovery_apps` WHERE `short_name` = @short_name; From 4b0e134fba568048df1cb7f897f136033b1edca8 Mon Sep 17 00:00:00 2001 From: alejandro Date: Wed, 15 Nov 2023 15:13:08 +0100 Subject: [PATCH 082/157] update md5 hash --- .../extras/discovery/DiscoveryApplicationsMigrateCodes.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini b/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini index 6323aec140..1ba02194d2 100644 --- a/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini +++ b/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini @@ -1,4 +1,4 @@ -pandorafms.vmware=9959cc3e5cc6bfcfadd6d05b56d4a11b +pandorafms.vmware=54251ae54994c55b478867cd35a98e6c pandorafms.mysql=fadb4750d18285c0eca34f47c6aa3cfe pandorafms.mssql=1cc215409741d19080269ffba112810e pandorafms.oracle=2d9320a514d1e48a0b2804e1653c31c6 From 804970719d502de1adb91f2b32a055a116830427 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 15 Nov 2023 16:32:02 +0100 Subject: [PATCH 083/157] #12385 Fixed group --- .../agentes/pandora_networkmap.view.php | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/pandora_console/operation/agentes/pandora_networkmap.view.php b/pandora_console/operation/agentes/pandora_networkmap.view.php index 5256c10871..3cbe53e815 100644 --- a/pandora_console/operation/agentes/pandora_networkmap.view.php +++ b/pandora_console/operation/agentes/pandora_networkmap.view.php @@ -1205,57 +1205,6 @@ if (is_ajax() === true) { return; } - if ($get_agents_in_group) { - $id = (int) get_parameter('id', 0); - $group = (int) get_parameter('group', -1); - - $return = []; - $return['correct'] = false; - - if ($group != -1) { - $where_id_agente = ' 1=1 '; - - $agents_in_networkmap = db_get_all_rows_filter( - 'titem', - [ - 'id_map' => $id, - 'deleted' => 0, - ] - ); - if ($agents_in_networkmap !== false) { - $ids = []; - foreach ($agents_in_networkmap as $agent) { - if ($agent['type'] == 0) { - $ids[] = $agent['source_data']; - } - } - - $where_id_agente = ' id_agente NOT IN ('.implode(',', $ids).')'; - } - - - $sql = 'SELECT id_agente, alias - FROM tagente - WHERE id_grupo = '.$group.' AND '.$where_id_agente.' - ORDER BY alias ASC'; - - $agents = db_get_all_rows_sql($sql); - - if ($agents !== false) { - $return['agents'] = []; - foreach ($agents as $agent) { - $return['agents'][$agent['id_agente']] = $agent['alias']; - } - - $return['correct'] = true; - } - } - - echo json_encode($return); - - return; - } - if ($get_agent_info) { $id_agent = (int) get_parameter('id_agent'); From 1a931c71b4114d4f69aa12bd42cf615d56de676e Mon Sep 17 00:00:00 2001 From: alejandro Date: Thu, 16 Nov 2023 10:10:54 +0100 Subject: [PATCH 084/157] update vmwre md5 code --- .../extras/discovery/DiscoveryApplicationsMigrateCodes.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini b/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini index 1ba02194d2..c0cee7d03f 100644 --- a/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini +++ b/pandora_console/extras/discovery/DiscoveryApplicationsMigrateCodes.ini @@ -1,4 +1,4 @@ -pandorafms.vmware=54251ae54994c55b478867cd35a98e6c +pandorafms.vmware=248788e0fb2cd4e11623e4a52ee7d05b pandorafms.mysql=fadb4750d18285c0eca34f47c6aa3cfe pandorafms.mssql=1cc215409741d19080269ffba112810e pandorafms.oracle=2d9320a514d1e48a0b2804e1653c31c6 From 58aeb59b2c1adc4fc769692107137ccf6844ce03 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Fri, 17 Nov 2023 10:22:52 +0100 Subject: [PATCH 085/157] Updated MR --- pandora_console/extras/mr/67.sql | 2 +- pandora_console/pandoradb_data.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 2913cd8248..307228f4cb 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -182,7 +182,7 @@ SET @model_name = 'Juniper-Generic'; SET @template_name = 'Juniper-Generic'; SET @agent_data_template_name = 'Juniper-Generic'; SET @script_test = 'expect:root@% cli\n exit\n'; -SET @script_get_config = 'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'; +SET @script_get_config = 'expect:root@% cli\n expect:root> capture:show configuration | no-more\n capture:\n quit\n expect:root@% exit\n'; SET @script_set_config = 'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'; SET @script_get_firmware = 'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'; SET @script_set_firmware = 'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 123940c22e..1552d16a4c 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2553,7 +2553,7 @@ INSERT INTO `tncm_script` VALUES (12,5,''), (13,7,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), (14,0,'expect:root@% cli\n exit\n'), - (15,1,'expect:root@% cli\n expect:root> capture:show configuration\n capture:\n quit\n expect:root@% exit\n'), + (15,1,'expect:root@% cli\n expect:root> capture:show configuration | no-more\n capture:\n quit\n expect:root@% exit\n'), (16,2,'expect:root@% cli\n expect:root> configure\n load override terminal\n _applyconfigbackup_\n commit\n exit\n'), (17,3,'expect:root@% cli\n expect:root> capture:show version|match Junos:\n capture: \n quit\n expect:root@% exit\n'), (18,4,'expect:root@% cli\n expect:root> save software from tftp _TFTP_SERVER_IP_ _FIRMWARE_NAME_ to flash\n reset\n exit\n'), From d84937e6c9a4e8391ac06459820fec3c8cfc8e9c Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Fri, 17 Nov 2023 12:24:07 +0100 Subject: [PATCH 086/157] Added snippet script to MR and pandoradb_data.sql --- pandora_console/extras/mr/67.sql | 5 +++++ pandora_console/pandoradb_data.sql | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 307228f4cb..76a2619e00 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -32,6 +32,11 @@ ADD COLUMN `agent_data_event_on_change` INT UNSIGNED NULL DEFAULT NULL AFTER `ev ALTER TABLE `treport_content` ADD COLUMN `ncm_agents` MEDIUMTEXT NULL AFTER `status_of_check`; +-- Add needed snippet script to queue tasks. +SET @type_snippet = 6; +SELECT @id_snippet := `id` FROM `tncm_script` WHERE `type` = @type_snippet; +INSERT IGNORE INTO `tncm_script` (`id`, `type`, `content`) VALUES (@id_snippet, @type_snippet, 'snippet'); + -- Add new vendor and model SET @vendor_name = 'Cisco'; SET @model_name = 'Cisco-Generic'; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 1552d16a4c..f7f5c5da08 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2593,7 +2593,8 @@ INSERT INTO `tncm_script` VALUES (52,3,'sleep:1 capture:/system package print\n\r exit\n\r'), (53,4,'sleep:1 /system routerboard upgrade\n\r expect:Do yes\n\r exit\n\r'), (54,5,''), - (55,7,'sleep:1 capture:/system package print\n\r exit\n\r'); + (55,7,'sleep:1 capture:/system package print\n\r exit\n\r'), + (56,6,'snippet'); INSERT INTO `tncm_template_scripts`(`id_template`, `id_script`) VALUES (1,1), From 6fc6bead65c7d29276f12db5e6d115197bc46124 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 21 Nov 2023 16:17:41 +0100 Subject: [PATCH 087/157] #12483 Fixed custom fields view --- .../include/styles/custom_field.css | 85 +++++++++++++++++++ pandora_console/include/styles/pandora.css | 22 +---- .../custom_fields/custom_fields_view.php | 64 +++++--------- 3 files changed, 109 insertions(+), 62 deletions(-) create mode 100644 pandora_console/include/styles/custom_field.css diff --git a/pandora_console/include/styles/custom_field.css b/pandora_console/include/styles/custom_field.css new file mode 100644 index 0000000000..fcb12d492f --- /dev/null +++ b/pandora_console/include/styles/custom_field.css @@ -0,0 +1,85 @@ +/** + * + * Name: Default theme + * Pandora Stylesheet + * + * @category Stylesheet + * @package Pandora FMS + * @subpackage Community + * @version 1.0.0 + * @license See below + * + * ______ ___ _______ _______ ________ + * | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __| + * | __/| _ | | _ || _ | _| _ | | ___| |__ | + * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| + * + * ============================================================================ + * Copyright (c) 2005-2023 Pandora FMS + * Please see https://pandorafms.com for full contribution list + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation for version 2. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * ============================================================================ + */ + +.dt-buttons { + float: left; +} + +.dt-button.buttons-csv.buttons-html5 { + box-shadow: none; +} + +.dataTables_filter > label { + color: #000; +} + +.top { + background-color: #fff !important; + color: #000 !important; + border-radius: 5px !important; + border: 1px solid #e5e9ed !important; +} + +.bottom { + background-color: #fff !important; + color: #000 !important; + border-radius: 5px !important; + border: 1px solid #e5e9ed !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { + color: #000 !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.current, +.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { + color: #fff !important; + background: #14524f !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button { + background-color: #f6f7fb !important; + color: #000 !important; + border: 1px solid #cacaca; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button:hover { + background: #e2e2e2 !important; + color: #000 !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.next { + border: 1px solid #cacaca !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.previous { + border: 1px solid #cacaca !important; +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 7c740bba2b..e5e92fea81 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -12547,9 +12547,10 @@ form.cfv_status_agent input:checked + label:before { float: left; margin-left: 10px; padding-right: 10px; - max-height: 890px; + max-height: 760px; overflow: auto; background-color: #f9f9f9; + margin-bottom: 20px; } .agents_custom_fields { @@ -12558,15 +12559,6 @@ form.cfv_status_agent input:checked + label:before { margin-bottom: 15px; padding: 25px 5px; } -div.agents_custom_fields #datatables_wrapper div.top, -div.agents_custom_fields #datatables_wrapper div.bottom { - background-color: #414141; - color: #ffffff; - border: none; - padding: 5px; - height: 38px; - width: 99%; -} /*Horizontal tree*/ @@ -12597,16 +12589,6 @@ div.agents_custom_fields #datatables_wrapper div.bottom { margin-top: 15px; } -.custom_fields_view { - width: 30%; - float: left; - margin-left: 10px; - padding-right: 10px; - max-height: 890px; - overflow: auto; - background-color: #f9f9f9; -} - .agents_custom_fields { width: 100%; diff --git a/pandora_console/operation/custom_fields/custom_fields_view.php b/pandora_console/operation/custom_fields/custom_fields_view.php index bd95ab26fd..83d35533c7 100644 --- a/pandora_console/operation/custom_fields/custom_fields_view.php +++ b/pandora_console/operation/custom_fields/custom_fields_view.php @@ -67,12 +67,12 @@ $info_user = get_user_info($config['id_user']); $group = get_parameter('group', 0); $id_custom_fields = get_parameter('id_custom_fields', 0); $id_custom_fields_data = get_parameter('id_custom_fields_data', -1); -$id_status = get_parameter('id_status', AGENT_MODULE_STATUS_NOT_NORMAL); +$id_status = get_parameter('id_status', -1); $module_search = get_parameter('module_search', ''); $search = get_parameter('uptbutton', ''); $id_filter = get_parameter('id_name', 0); $recursion = get_parameter('recursion', 0); -$module_status = get_parameter('module_status', AGENT_MODULE_STATUS_NOT_NORMAL); +$module_status = get_parameter('module_status', -1); // ===================================================================== // Custom filter search @@ -304,21 +304,12 @@ $table->data[2][5] = html_print_submit_button( ); if (check_acl($config['id_user'], 0, 'PM')) { - // Pass the parameters to the page that generates the csv file (arrays) + // Pass the parameters to the page that generates the csv file (arrays). $decode_id_status = base64_encode(json_encode($id_status)); $decode_module_status = base64_encode(json_encode($module_status)); $decode_filters = base64_encode(json_encode($filters)); $table->data[3][5] = '
'; - /* - $table->data[3][5] .= html_print_button( - __('Export to CSV'), - 'csv_export', - false, - "blockResubmit($(this)); location.href='monitoring/custom_fields_csv.php?filters=$decode_filters&id_custom_field=$id_custom_fields&id_status=$decode_id_status&module_status=$decode_module_status'", - 'class="sub next"', - true - );*/ $table->data[3][5] .= '
'; } @@ -367,12 +358,13 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { $id_custom_field_array = $filters['id_custom_fields_data']; } - foreach ($id_custom_field_array as $value) { - /* - $table_agent = html_get_predefined_table(); - $table_agent->style = []; - $table_agent->class = 'tactical_view';*/ + $id_field = db_get_value_filter( + 'id_field', + 'tagent_custom_fields', + ['name' => $id_custom_fields] + ); + foreach ($id_custom_field_array as $value) { $table_agent = new StdClass(); $table_agent->width = '100%'; $table_agent->class = 'tactical_view'; @@ -388,7 +380,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true, ['title' => __('Agents critical')] ); - $agent_data[1] = "
"; + $agent_data[1] = ""; $agent_data[1] .= ""; $agent_data[1] .= format_numeric( $data['counters_name'][$value]['a_critical'] @@ -401,7 +393,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true, ['title' => __('Agents warning')] ); - $agent_data[3] = ""; + $agent_data[3] = ""; $agent_data[3] .= ""; $agent_data[3] .= format_numeric( $data['counters_name'][$value]['a_warning'] @@ -414,7 +406,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true, ['title' => __('Agents ok')] ); - $agent_data[5] = ""; + $agent_data[5] = ""; $agent_data[5] .= ""; $agent_data[5] .= format_numeric( $data['counters_name'][$value]['a_normal'] @@ -427,7 +419,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true, ['title' => __('Agents unknown')] ); - $agent_data[7] = ""; + $agent_data[7] = ""; $agent_data[7] .= ""; $agent_data[7] .= format_numeric( $data['counters_name'][$value]['a_unknown'] @@ -440,7 +432,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true, ['title' => __('Agents not init')] ); - $agent_data[9] = ""; + $agent_data[9] = ""; $agent_data[9] .= ""; $agent_data[9] .= format_numeric( $data['counters_name'][$value]['a_not_init'] @@ -455,12 +447,6 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { $m_unknown = ($data['counters_name'][$value]['m_unknown'] <= 0) ? '0' : $data['counters_name'][$value]['m_unknown']; $m_not_init = ($data['counters_name'][$value]['m_not_init'] <= 0) ? '0' : $data['counters_name'][$value]['m_not_init']; - // Modules by status table. - /* - $table_mbs = html_get_predefined_table(); - $table_mbs->class = 'tactical_view'; - $table_mbs->style = [];*/ - $table_mbs = new StdClass(); $table_mbs->width = '100%'; $table_mbs->class = 'tactical_view'; @@ -478,7 +464,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { false, true ); - $tdata[1] = ''.$m_critical.''; + $tdata[1] = ''.$m_critical.''; $tdata[2] = html_print_image( 'images/module_warning.png', @@ -489,7 +475,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { false, true ); - $tdata[3] = ''.$m_warning.''; + $tdata[3] = ''.$m_warning.''; $tdata[4] = html_print_image( 'images/module_ok.png', @@ -500,7 +486,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { false, true ); - $tdata[5] = ''.$m_normal.''; + $tdata[5] = ''.$m_normal.''; $tdata[6] = html_print_image( 'images/module_unknown.png', @@ -511,7 +497,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { false, true ); - $tdata[7] = ''.$m_unknown.''; + $tdata[7] = ''.$m_unknown.''; $tdata[8] = html_print_image( 'images/module_notinit.png', @@ -523,7 +509,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { true ); - $tdata[9] = ''.$m_not_init.''; + $tdata[9] = ''.$m_not_init.''; $table_mbs->data[] = $tdata; @@ -714,7 +700,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { echo '
'; echo "
"; - echo ""; + echo "
"; echo ''; echo ''; echo ''; @@ -755,6 +741,7 @@ if (isset($id_custom_fields_data) && is_array($id_custom_fields_data)) { echo ''; ui_require_css_file('datatables.min', 'include/styles/js/'); +ui_require_css_file('custom_field', 'include/styles/'); ui_require_javascript_file_enterprise('functions_csv'); ui_require_javascript_file('datatables.min'); ui_require_javascript_file('buttons.dataTables.min'); @@ -904,7 +891,6 @@ function dialog_filter_cf(title, type_form){ } function table_datatables(filters, indexed_descriptions, processing){ - console.log(indexed_descriptions); array_data = JSON.parse(filters); table = $('#datatables').DataTable({ processing: true, @@ -913,7 +899,6 @@ function table_datatables(filters, indexed_descriptions, processing){ searching: true, pageLength: Number(array_data.block_size), lengthMenu: [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100], - //buttons: [{ extend: 'csvHtml5', text: 'Save as csvHtml5' }], responsive: false, ajax: { type: "POST", @@ -933,21 +918,16 @@ function table_datatables(filters, indexed_descriptions, processing){ 'paging': true, 'ordering': true, 'scrollX': true, - 'scroller': true + 'scroller': true, }, }, language: { processing: processing, lengthMenu: "Show _MENU_ items per page", zeroRecords: "Nothing found. Please change your search term", - //info: "Page _PAGE_ of _PAGES_", infoEmpty: "No results", infoFiltered: "", search: "Search:", - /*paginate:{ - next: "Next", - previous: "Next" - }*/ }, sDom: '<"top"lfp>rt<"bottom"ip><"clear">', columns: [ From 0a9e1275765d39dc09094651754a6bbe4b230437 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 22 Nov 2023 16:12:37 +0100 Subject: [PATCH 088/157] #8365 NCM v3 snipets --- pandora_console/extras/mr/67.sql | 3 +++ pandora_console/pandoradb.sql | 1 + 2 files changed, 4 insertions(+) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 76a2619e00..565882214a 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -3,6 +3,9 @@ START TRANSACTION; ALTER TABLE `tncm_queue` ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`; +ALTER TABLE `tncm_queue` +ADD COLUMN `snipet` TEXT NULL AFTER `scheduled`; + CREATE TABLE IF NOT EXISTS `tncm_agent_data_template` ( `id` SERIAL, `name` TEXT, diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 334afe02b2..aeb33e9a10 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4270,6 +4270,7 @@ CREATE TABLE IF NOT EXISTS `tncm_queue` ( `id_agent_data` bigint unsigned, `utimestamp` INT UNSIGNED NOT NULL, `scheduled` INT UNSIGNED DEFAULT NULL, + `snipet` TEXT NULL, FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; From a277e56672b1875ddc8fefac9b2f9bb2d7f61af8 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 22 Nov 2023 16:47:13 +0100 Subject: [PATCH 089/157] #8365 NCM v3 rename snipet to snippet --- pandora_console/extras/mr/67.sql | 2 +- pandora_console/pandoradb.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 565882214a..00a357d18a 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -4,7 +4,7 @@ ALTER TABLE `tncm_queue` ADD COLUMN `id_agent_data` bigint unsigned AFTER `id_script`; ALTER TABLE `tncm_queue` -ADD COLUMN `snipet` TEXT NULL AFTER `scheduled`; +ADD COLUMN `snippet` TEXT NULL AFTER `scheduled`; CREATE TABLE IF NOT EXISTS `tncm_agent_data_template` ( `id` SERIAL, diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index aeb33e9a10..d009554cc6 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4270,7 +4270,7 @@ CREATE TABLE IF NOT EXISTS `tncm_queue` ( `id_agent_data` bigint unsigned, `utimestamp` INT UNSIGNED NOT NULL, `scheduled` INT UNSIGNED DEFAULT NULL, - `snipet` TEXT NULL, + `snippet` TEXT NULL, FOREIGN KEY (`id_agent`) REFERENCES `tagente`(`id_agente`) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (`id_script`) REFERENCES `tncm_script`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; From 81f938c5ca0abfc11633d64e71900c4c85fe963a Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Thu, 23 Nov 2023 09:12:49 +0100 Subject: [PATCH 090/157] #11494 Align text left --- pandora_console/include/lib/Dashboard/Widget.php | 1 + .../include/lib/Dashboard/Widgets/service_level.php | 3 +++ 2 files changed, 4 insertions(+) diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index df084d26b5..281c6c8804 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -454,6 +454,7 @@ class Widget case 'service_level': $className .= '\ServiceLevelWidget'; + break; case 'security_hardening': if (\enterprise_installed() === false) { diff --git a/pandora_console/include/lib/Dashboard/Widgets/service_level.php b/pandora_console/include/lib/Dashboard/Widgets/service_level.php index b63ff36518..7f3add7c08 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/service_level.php +++ b/pandora_console/include/lib/Dashboard/Widgets/service_level.php @@ -537,14 +537,17 @@ class ServiceLevelWidget extends Widget $table->head[5] = __('Warn. Events'); $table->head[6] = __('Last change'); $table->data = []; + $table->cellstyle = []; $row = 0; foreach ($visualData as $agent_id => $data) { foreach ($data['modules'] as $module_name => $module_data) { if (isset($module_data) === true) { if ($show_agents === 'on') { $table->data[$row][0] = $module_data['agent_alias'].' / '.$module_data['module_name']; + $table->cellstyle[$row][0] = 'text-align:left'; } else { $table->data[$row][0] = $module_data['module_name']; + $table->cellstyle[$row][0] = 'text-align:left'; } $table->data[$row][1] = $module_data['availability'].'%'; From 51e07930ed16d37bdb246c6a42266dccae54f00a Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Thu, 23 Nov 2023 09:51:12 +0100 Subject: [PATCH 091/157] #11495 Align text left --- pandora_console/include/functions_reporting_html.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 71bf7afbc3..e67bd2b173 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -2797,13 +2797,16 @@ function reporting_html_service_level($table, $item, $pdf=0) $table_info->head[5] = __('Warn. Events'); $table_info->head[6] = __('Last change'); $table_info->data = []; + $table_info->cellstyle = []; $row = 0; foreach ($item['data'] as $agentmodule_id => $module_data) { if ($show_agents === 'on') { $table_info->data[$row][0] = $module_data['agent_alias'].' / '.$module_data['module_name']; + $table_info->cellstyle[$row][0] = 'text-align:left; padding-left: 30px;'; } else { $table_info->data[$row][0] = $module_data['module_name']; + $table_info->cellstyle[$row][0] = 'text-align:left; padding-left: 30px;'; } $table_info->data[$row][1] = $module_data['availability'].'%'; From 1f51b0475e3c29f1bea806c2c8ef45f7f3d7946c Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Fri, 24 Nov 2023 13:12:12 +0100 Subject: [PATCH 092/157] #12201 Added configuration in the setup for easter egg --- pandora_console/godmode/setup/setup_general.php | 10 ++++++++++ pandora_console/include/functions_config.php | 8 ++++++++ pandora_console/index.php | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 2732568208..b7bcbcabf2 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -767,6 +767,16 @@ $table->data[$i][] = html_print_label_input_block( ) ); +$table->data[$i][] = html_print_label_input_block( + __('Eastern eggs disabled'), + html_print_checkbox_switch( + 'eastern_eggs_disabled', + 1, + $config['eastern_eggs_disabled'], + true + ) +); + echo ''; diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index c9e4aa2226..0c7d6039cd 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -371,6 +371,10 @@ function config_update_config() $error_update[] = __('show_experimental_features'); } + if (config_update_value('eastern_eggs_disabled', get_parameter('eastern_eggs_disabled'), true) === false) { + $error_update[] = __('eastern_eggs_disabled'); + } + if (config_update_value('console_log_enabled', get_parameter('console_log_enabled'), true) === false) { $error_update[] = __('Console log enabled'); } @@ -2449,6 +2453,10 @@ function config_process_config() config_update_value('show_experimental_features', 0); } + if (!isset($config['eastern_eggs_disabled'])) { + config_update_value('eastern_eggs_disabled', 1); + } + if (!isset($config['agent_vulnerabilities'])) { config_update_value('agent_vulnerabilities', 1); } diff --git a/pandora_console/index.php b/pandora_console/index.php index 4ca8f80a82..49bccd1b14 100755 --- a/pandora_console/index.php +++ b/pandora_console/index.php @@ -1515,6 +1515,15 @@ echo html_print_div( true ); +echo html_print_input_hidden( + 'flagEasternEgg', + $config['eastern_eggs_disabled'], + false, + '', + '', + 'flagEasternEgg' +); + // Connection lost alert. set_js_value('check_conexion_interval', $config['check_conexion_interval']); set_js_value('title_conexion_interval', __('Connection with console has been lost')); From 3d3cbd5e96a2b3404dacc1b439d2b63fcbfee290 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 27 Nov 2023 09:39:56 +0100 Subject: [PATCH 093/157] 9753 Fixed group list --- pandora_console/godmode/groups/modu_group_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/groups/modu_group_list.php b/pandora_console/godmode/groups/modu_group_list.php index 560de898e9..a8f7930b26 100644 --- a/pandora_console/godmode/groups/modu_group_list.php +++ b/pandora_console/godmode/groups/modu_group_list.php @@ -154,7 +154,7 @@ if ($is_management_allowed === true && $update_group === true) { $subcheck = db_get_value('name', 'tmodule_group', 'id_mg', $id_group); if ($name) { - if (!$check || $subcheck == $name) { + if ($check === false || strcasecmp($subcheck, $name) === 0) { $result = db_process_sql_update( 'tmodule_group', ['name' => $name], From 3f3e8e42bcc160b4b67202db61971c2963deef14 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 28 Nov 2023 08:13:00 +0100 Subject: [PATCH 094/157] move extension translate_string and file_repo pandora_enterprise#12333 --- pandora_console/extensions/files_repo.php | 286 ------------------ .../files_repo/files_repo_get_file.php | 68 ----- .../extensions/files_repo/files_repo_list.php | 168 ---------- .../files_repo/sql/files_repo.oracle.sql | 16 - .../files_repo/sql/files_repo.postgreSQL.sql | 2 - .../extensions/files_repo/sql/files_repo.sql | 15 - .../extras/delete_files/delete_files.txt | 4 + pandora_console/extras/mr/67.sql | 29 ++ .../godmode/files_repo/files_repo.php | 167 ++++++++++ .../files_repo/files_repo_form.php | 41 ++- .../godmode/files_repo/files_repo_list.php | 153 ++++++++++ pandora_console/godmode/menu.php | 2 + .../include/functions_extensions.php | 18 +- .../functions_files_repository.php} | 167 +++++++--- pandora_console/include/functions_io.php | 32 +- pandora_console/include/get_file.php | 3 +- pandora_console/operation/menu.php | 5 + pandora_console/pandoradb.sql | 24 +- 18 files changed, 555 insertions(+), 645 deletions(-) delete mode 100644 pandora_console/extensions/files_repo.php delete mode 100644 pandora_console/extensions/files_repo/files_repo_get_file.php delete mode 100644 pandora_console/extensions/files_repo/files_repo_list.php delete mode 100644 pandora_console/extensions/files_repo/sql/files_repo.oracle.sql delete mode 100644 pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql delete mode 100644 pandora_console/extensions/files_repo/sql/files_repo.sql create mode 100644 pandora_console/godmode/files_repo/files_repo.php rename pandora_console/{extensions => godmode}/files_repo/files_repo_form.php (76%) create mode 100644 pandora_console/godmode/files_repo/files_repo_list.php rename pandora_console/{extensions/files_repo/functions_files_repo.php => include/functions_files_repository.php} (69%) diff --git a/pandora_console/extensions/files_repo.php b/pandora_console/extensions/files_repo.php deleted file mode 100644 index a482a59669..0000000000 --- a/pandora_console/extensions/files_repo.php +++ /dev/null @@ -1,286 +0,0 @@ - 'files_repo_installed', - 'value' => 1, - ]; - db_process_sql_insert('tconfig', $values); - } - } -} - - -function pandora_files_repo_uninstall() -{ - global $config; - - switch ($config['dbtype']) { - case 'mysql': - db_process_sql('DROP TABLE `tfiles_repo_group`'); - db_process_sql('DROP TABLE `tfiles_repo`'); - db_process_sql( - 'DELETE FROM `tconfig` - WHERE `token` LIKE "files_repo_%"' - ); - break; - - case 'postgresql': - db_process_sql('DROP TABLE "tfiles_repo_group"'); - db_process_sql('DROP TABLE "tfiles_repo"'); - db_process_sql( - 'DELETE FROM "tconfig" - WHERE "token" LIKE \'files_repo_%\'' - ); - break; - - case 'oracle': - db_process_sql('DROP TRIGGER "tfiles_repo_group_inc"'); - db_process_sql('DROP SEQUENCE "tfiles_repo_group_s"'); - db_process_sql('DROP TABLE "tfiles_repo_group"'); - db_process_sql('DROP TRIGGER "tfiles_repo_inc"'); - db_process_sql('DROP SEQUENCE "tfiles_repo_s"'); - db_process_sql('DROP TABLE "tfiles_repo"'); - db_process_sql( - 'DELETE FROM tconfig - WHERE token LIKE \'files_repo_%\'' - ); - break; - } - - if (!empty($config['attachment_store'])) { - delete_dir($config['attachment_store'].'/files_repo'); - } -} - - -function pandora_files_repo_godmode() -{ - global $config; - - if (!isset($config['files_repo_installed']) || !$config['files_repo_installed']) { - ui_print_error_message(__('Extension not installed')); - } - - // ACL Check - check_login(); - if (! check_acl($config['id_user'], 0, 'PM')) { - db_pandora_audit( - AUDIT_LOG_ACL_VIOLATION, - 'Trying to access to Files repository' - ); - include 'general/noaccess.php'; - return; - } - - // Header tabs. - $godmode['text'] = ''.html_print_image('images/configuration@svg.svg', true, ['title' => __('Administration view'), 'class' => 'main_menu_icon invert_filter']).''; - $godmode['godmode'] = 1; - $godmode['active'] = 1; - - $operation['text'] = ''.html_print_image('images/see-details@svg.svg', true, ['title' => __('Operation view'), 'class' => 'main_menu_icon invert_filter']).''; - $operation['operation'] = 1; - - $onheader = [ - 'godmode' => $godmode, - 'operation' => $operation, - ]; - - // Header. - ui_print_standard_header( - __('Extensions'), - 'images/extensions.png', - false, - '', - true, - $onheader, - [ - [ - 'link' => '', - 'label' => __('Admin tools'), - ], - [ - 'link' => '', - 'label' => __('Extension manager'), - ], - [ - 'link' => '', - 'label' => __('Files repository manager'), - ], - ] - ); - - $full_extensions_dir = $config['homedir'].'/'.EXTENSIONS_DIR.'/'; - include_once $full_extensions_dir.'files_repo/functions_files_repo.php'; - - // Directory files_repo check. - if (!files_repo_check_directory(true)) { - return; - } - - $server_content_length = 0; - if (isset($_SERVER['CONTENT_LENGTH'])) { - $server_content_length = $_SERVER['CONTENT_LENGTH']; - } - - // Check for an anoying error that causes the $_POST and $_FILES arrays. - // were empty if the file is larger than the post_max_size. - if (intval($server_content_length) > 0 && empty($_POST)) { - ui_print_error_message(__('Problem uploading. Please check this PHP runtime variable values:
  post_max_size (currently '.ini_get('post_max_size').')
')); - } - - // GET and POST parameters. - $file_id = (int) get_parameter('file_id'); - $add_file = (bool) get_parameter('add_file'); - $update_file = (bool) get_parameter('update_file'); - $delete_file = (bool) get_parameter('delete'); - - // File add or update. - if ($add_file || ($update_file && $file_id > 0)) { - $groups = get_parameter('groups', []); - $public = (bool) get_parameter('public'); - $description = io_safe_output((string) get_parameter('description')); - if (mb_strlen($description, 'UTF-8') > 200) { - $description = mb_substr($description, 0, 200, 'UTF-8'); - } - - $description = io_safe_input($description); - - if ($add_file) { - $result = files_repo_add_file('upfile', $description, $groups, $public); - } else if ($update_file) { - $result = files_repo_update_file($file_id, $description, $groups, $public); - $file_id = 0; - } - - if ($result['status'] == false) { - ui_print_error_message($result['message']); - } - } - - // File delete. - if ($delete_file && $file_id > 0) { - $result = files_repo_delete_file($file_id); - if ($result !== -1) { - ui_print_result_message($result, __('Successfully deleted'), __('Could not be deleted')); - } - - $file_id = 0; - } - - // FORM. - include $full_extensions_dir.'files_repo/files_repo_form.php'; - if (!$file_id) { - // LIST. - $manage = true; - include $full_extensions_dir.'files_repo/files_repo_list.php'; - } -} - - -function pandora_files_repo_operation() -{ - global $config; - - // Header tabs. - $onheader = []; - if (check_acl($config['id_user'], 0, 'PM')) { - $godmode['text'] = ''.html_print_image('images/configuration@svg.svg', true, ['title' => __('Administration view'), 'class' => 'main_menu_icon invert_filter']).''; - $godmode['godmode'] = 1; - - $operation['text'] = ''.html_print_image('images/see-details@svg.svg', true, ['title' => __('Operation view'), 'class' => 'main_menu_icon invert_filter']).''; - $operation['operation'] = 1; - $operation['active'] = 1; - - $onheader = [ - 'godmode' => $godmode, - 'operation' => $operation, - ]; - } - - // Header. - ui_print_standard_header( - __('Files repository'), - 'images/extensions.png', - false, - '', - false, - $onheader, - [ - [ - 'link' => '', - 'label' => __('Admin tools'), - ], - [ - 'link' => '', - 'label' => __('Extension manager'), - ], - [ - 'link' => '', - 'label' => __('Files repository'), - ], - ] - ); - - $full_extensions_dir = $config['homedir'].'/'.EXTENSIONS_DIR.'/'; - include_once $full_extensions_dir.'files_repo/functions_files_repo.php'; - - // Directory files_repo check. - if (!files_repo_check_directory(true)) { - return; - } - - // LIST. - $full_extensions_dir = $config['homedir'].'/'.EXTENSIONS_DIR.'/'; - - include $full_extensions_dir.'files_repo/files_repo_list.php'; -} - - -extensions_add_operation_menu_option(__('Files repository'), null, null, 'v1r1'); -extensions_add_main_function('pandora_files_repo_operation'); -extensions_add_godmode_menu_option(__('Files repository manager'), 'PM', null, null, 'v1r1'); -extensions_add_godmode_function('pandora_files_repo_godmode'); - -pandora_files_repo_install(); diff --git a/pandora_console/extensions/files_repo/files_repo_get_file.php b/pandora_console/extensions/files_repo/files_repo_get_file.php deleted file mode 100644 index 6d6595a01f..0000000000 --- a/pandora_console/extensions/files_repo/files_repo_get_file.php +++ /dev/null @@ -1,68 +0,0 @@ - $file_hash]); -if (!$file) { - throw_error(10); - // ERROR -} - -// Case sensitive check -$check_hash = ($file['hash'] == $file_hash) ? true : false; -if (!$check_hash) { - throw_error(10); - // ERROR -} - -// Get the location -$files_repo_path = io_safe_output($config['attachment_store']).'/files_repo'; -$location = $files_repo_path.'/'.$file['id'].'_'.$file['name']; -if (!file_exists($location) || !is_readable($location) || !is_file($location)) { - throw_error(5); - // ERROR -} - -// All checks are fine. Download the file! -header('Content-type: aplication/octet-stream;'); -header('Content-Length: '.filesize($location)); -header('Content-Disposition: attachment; filename="'.$file['name'].'"'); -readfile($location); - - -function throw_error($time=15) -{ - sleep($time); - - $styleError = 'background:url("../images/err.png") no-repeat scroll 0 0 transparent; padding:4px 1px 6px 30px; color:#CC0000;'; - echo "

".__('Unreliable petition').'. '.__('Please contact the administrator').'

'; - exit; -} diff --git a/pandora_console/extensions/files_repo/files_repo_list.php b/pandora_console/extensions/files_repo/files_repo_list.php deleted file mode 100644 index 6c08b8f505..0000000000 --- a/pandora_console/extensions/files_repo/files_repo_list.php +++ /dev/null @@ -1,168 +0,0 @@ - 'id', - 'order' => 'DESC', -]; - -$files = files_repo_get_files($filter); - - -if (!empty($files)) { - if (!isset($manage)) { - $manage = false; - } - - // Pagination - if ($manage) { - $url = ui_get_full_url('index.php?sec=godmode/extensions&sec2=extensions/files_repo'); - } else { - $url = ui_get_full_url('index.php?sec=extensions&sec2=extensions/files_repo'); - } - - $total_files = files_repo_get_files(false, true); - ui_pagination($total_files, $url, $offset); - - $table = new stdClass(); - $table->width = '100%'; - $table->class = 'info_table'; - $table->style = []; - $table->style[1] = 'max-width: 200px;'; - $table->style[4] = 'text-align: center;'; - $table->head = []; - $table->head[0] = __('Name'); - $table->head[1] = __('Description'); - $table->head[2] = __('Size'); - $table->head[3] = __('Last modification'); - $table->head[4] = ''; - $table->data = []; - - foreach ($files as $file_id => $file) { - $data = []; - - // Prepare the filename for the get_file.php script - $document_root = str_replace( - '\\', - '/', - io_safe_output($_SERVER['DOCUMENT_ROOT']) - ); - $file['location'] = str_replace( - '\\', - '/', - io_safe_output($file['location']) - ); - $relative_path = str_replace($document_root, '', $file['location']); - $file_name = explode('/', $file['location']); - $file_decoded = $file_name[(count($file_name) - 1)]; - $file_path = base64_encode($file_decoded); - $hash = md5($file_path.$config['server_unique_identifier']); - $url = ui_get_full_url( - 'include/get_file.php?file='.urlencode($file_path).'&hash='.$hash - ); - $date_format = ($config['date_format']) ? io_safe_output($config['date_format']) : 'F j, Y - H:m'; - - $data[0] = "".$file['name'].''; - // Name - $data[1] = ui_print_truncate_text( - $file['description'], - 'description', - true, - true - ); - // Description - $data[2] = ui_format_filesize($file['size']); - // Size - $data[3] = date($date_format, $file['mtime']); - // Last modification - // Public URL - $data[4] = ''; - $table->cellclass[][4] = 'table_action_buttons'; - if (!empty($file['hash'])) { - $public_url = ui_get_full_url( - EXTENSIONS_DIR.'/files_repo/files_repo_get_file.php?file='.$file['hash'] - ); - $message = __('Copy to clipboard').': Ctrl+C -> Enter'; - $action = "window.prompt('$message', '$public_url');"; - $data[4] .= ""; - $data[4] .= html_print_image( - 'images/world.png', - true, - ['title' => __('Public link')] - ); - // Public link image - $data[4] .= ' '; - } - - $data[4] .= ""; - $data[4] .= html_print_image( - 'images/download.png', - true, - [ - 'title' => __('Download'), - 'style' => 'padding:3px', - ] - ); - // Download image - $data[4] .= ''; - - if ($manage) { - $config_url = ui_get_full_url( - 'index.php?sec=godmode/extensions&sec2=extensions/files_repo&file_id='.$file_id - ); - $data[4] .= ""; - $data[4] .= html_print_image( - 'images/edit.svg', - true, - [ - 'title' => __('Edit'), - 'class' => 'main_menu_icon invert_filter', - ] - ); - // Edit image - $data[4] .= ''; - - $delete_url = ui_get_full_url( - 'index.php?sec=godmode/extensions&sec2=extensions/files_repo&delete=1&file_id='.$file_id - ); - $data[4] .= " "; - $data[4] .= html_print_image( - 'images/delete.svg', - true, - [ - 'title' => __('Delete'), - 'class' => 'main_menu_icon invert_filter', - ] - ); - // Delete image - $data[4] .= ''; - } - - $table->data[] = $data; - } - - html_print_table($table); -} else { - ui_print_info_message(__('No items')); -} diff --git a/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql b/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql deleted file mode 100644 index d86b775920..0000000000 --- a/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE TABLE tfiles_repo ( - id NUMBER(5, 0) NOT NULL PRIMARY KEY, - name VARCHAR2(255) NOT NULL, - description VARCHAR2(500) NULL, - hash VARCHAR2(8) NULL -); -CREATE SEQUENCE tfiles_repo_s INCREMENT BY 1 START WITH 1; -CREATE OR REPLACE TRIGGER tfiles_repo_inc BEFORE INSERT ON tfiles_repo REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tfiles_repo_s.nextval INTO :NEW.ID FROM dual; END;; - -CREATE TABLE tfiles_repo_group ( - id NUMBER(10, 0) NOT NULL PRIMARY KEY, - id_file NUMBER(5, 0) NOT NULL REFERENCES tfiles_repo(id) ON DELETE CASCADE, - id_group NUMBER(4, 0) NOT NULL -); -CREATE SEQUENCE tfiles_repo_group_s INCREMENT BY 1 START WITH 1; -CREATE OR REPLACE TRIGGER tfiles_repo_group_inc BEFORE INSERT ON tfiles_repo_group REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tfiles_repo_group_s.nextval INTO :NEW.ID FROM dual; END;; \ No newline at end of file diff --git a/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql b/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql deleted file mode 100644 index 3f129e10cb..0000000000 --- a/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql +++ /dev/null @@ -1,2 +0,0 @@ -CREATE TABLE "tfiles_repo" ("id" SERIAL NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "description" VARCHAR(500) NULL default '', "hash" VARCHAR(8) NULL default ''); -CREATE TABLE "tfiles_repo_group" ("id" SERIAL NOT NULL PRIMARY KEY, "id_file" INTEGER NOT NULL REFERENCES tfiles_repo("id") ON DELETE CASCADE, "id_group" INTEGER NOT NULL); diff --git a/pandora_console/extensions/files_repo/sql/files_repo.sql b/pandora_console/extensions/files_repo/sql/files_repo.sql deleted file mode 100644 index d6dce31339..0000000000 --- a/pandora_console/extensions/files_repo/sql/files_repo.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE IF NOT EXISTS `tfiles_repo` ( - `id` int(5) unsigned NOT NULL auto_increment, - `name` varchar(255) NOT NULL, - `description` varchar(500) NULL default '', - `hash` varchar(8) NULL default '', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE IF NOT EXISTS `tfiles_repo_group` ( - `id` int(10) unsigned NOT NULL auto_increment, - `id_file` int(5) unsigned NOT NULL, - `id_group` int(4) unsigned NOT NULL, - PRIMARY KEY (`id`), - FOREIGN KEY (`id_file`) REFERENCES tfiles_repo(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 234ec4e997..6704356ae4 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1720,3 +1720,7 @@ include/functions_integriaims.php include/ajax/integria_incidents.ajax.php enterprise/operation/log/log_source.php enterprise/include/class/LogSource.class.php +enterprise/extensions/translate_string +enterprise/extensions/translate_string.php +extensions/files_repo +extensions/files_repo.php diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index a31ea6e670..2e04ab23c2 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -5,4 +5,33 @@ DROP TABLE tagent_access; ALTER TABLE treport_content ADD check_unknowns_graph tinyint DEFAULT 0 NULL; +DELETE FROM `tconfig` WHERE `token` LIKE 'translate_string_extension_installed'; + +CREATE TABLE IF NOT EXISTS `textension_translate_string` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `lang` VARCHAR(10) NOT NULL , + `string` TEXT , + `translation` TEXT , + PRIMARY KEY (`id`), + KEY `lang_index` (`lang`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + +DELETE FROM `tconfig` WHERE `token` LIKE 'files_repo_installed'; + +CREATE TABLE IF NOT EXISTS `tfiles_repo` ( + `id` int(5) unsigned NOT NULL auto_increment, + `name` varchar(255) NOT NULL, + `description` varchar(500) NULL default '', + `hash` varchar(8) NULL default '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tfiles_repo_group` ( + `id` int(10) unsigned NOT NULL auto_increment, + `id_file` int(5) unsigned NOT NULL, + `id_group` int(4) unsigned NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`id_file`) REFERENCES tfiles_repo(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + COMMIT; diff --git a/pandora_console/godmode/files_repo/files_repo.php b/pandora_console/godmode/files_repo/files_repo.php new file mode 100644 index 0000000000..cf22ee294c --- /dev/null +++ b/pandora_console/godmode/files_repo/files_repo.php @@ -0,0 +1,167 @@ +'; +$godmode['text'] .= html_print_image( + 'images/configuration@svg.svg', + true, + [ + 'title' => __('Administration view'), + 'class' => 'main_menu_icon invert_filter', + ] +); +$godmode['text'] .= ''; +$godmode['godmode'] = 1; + +$operation['text'] = ''; +$operation['text'] .= html_print_image( + 'images/see-details@svg.svg', + true, + [ + 'title' => __('Operation view'), + 'class' => 'main_menu_icon invert_filter', + ] +); +$operation['text'] .= ''; +$operation['operation'] = 1; + +$operation['active'] = 1; +$godmode['active'] = 0; +if ($tab === 'configuration') { + $godmode['active'] = 1; + $operation['active'] = 0; +} + +$onheader = [ + 'godmode' => $godmode, + 'operation' => $operation, +]; + +// Header. +ui_print_standard_header( + __('Extensions'), + 'images/extensions.png', + false, + '', + true, + $onheader, + [ + [ + 'link' => '', + 'label' => __('Tools'), + ], + [ + 'link' => '', + 'label' => __('Files repository'), + ], + ] +); + +require_once __DIR__.'/../../include/functions_files_repository.php'; + +// Directory files_repo check. +if (files_repo_check_directory() === false) { + return; +} + +$server_content_length = 0; +if (isset($_SERVER['CONTENT_LENGTH'])) { + $server_content_length = $_SERVER['CONTENT_LENGTH']; +} + +// Check for an anoying error that causes the $_POST and $_FILES arrays. +// were empty if the file is larger than the post_max_size. +if (intval($server_content_length) > 0 && empty($_POST)) { + ui_print_error_message( + __('Problem uploading. Please check this PHP runtime variable values:
  post_max_size (currently '.ini_get('post_max_size').')
') + ); +} + +// GET and POST parameters. +$file_id = (int) get_parameter('file_id'); +$add_file = (bool) get_parameter('add_file'); +$update_file = (bool) get_parameter('update_file'); +$delete_file = (bool) get_parameter('delete'); + +// File add or update. +if ($add_file === true || ($update_file === true && $file_id > 0)) { + $groups = get_parameter('groups', []); + $public = (bool) get_parameter('public'); + $description = io_safe_output((string) get_parameter('description')); + if (mb_strlen($description, 'UTF-8') > 200) { + $description = mb_substr($description, 0, 200, 'UTF-8'); + } + + $description = io_safe_input($description); + + if ($add_file === true) { + $result = files_repo_add_file('upfile', $description, $groups, $public); + } else if ($update_file === true) { + $result = files_repo_update_file($file_id, $description, $groups, $public); + $file_id = 0; + } + + if ($result['status'] == false) { + ui_print_error_message($result['message']); + } else { + if ($add_file === true) { + ui_print_success_message(__('Successfully created')); + } else if ($update_file === true) { + ui_print_success_message(__('Successfully updated')); + } + } +} + +// File delete. +if ($delete_file === true && $file_id > 0) { + $result = files_repo_delete_file($file_id); + if ($result !== -1) { + ui_print_result_message($result, __('Successfully deleted'), __('Could not be deleted')); + } + + $file_id = 0; +} + +$operation['active'] = 1; +if ($tab === 'configuration') { + include_once __DIR__.'/files_repo_form.php'; +} else { + include_once __DIR__.'/files_repo_list.php'; +} diff --git a/pandora_console/extensions/files_repo/files_repo_form.php b/pandora_console/godmode/files_repo/files_repo_form.php similarity index 76% rename from pandora_console/extensions/files_repo/files_repo_form.php rename to pandora_console/godmode/files_repo/files_repo_form.php index d8bf6c6836..bf1bc81ca7 100644 --- a/pandora_console/extensions/files_repo/files_repo_form.php +++ b/pandora_console/godmode/files_repo/files_repo_form.php @@ -1,20 +1,27 @@ 0) { 'file_id', $file_id, true + ).html_print_input_hidden( + 'update_file', + 1, + true ) ); } else { @@ -150,8 +161,8 @@ if ($file_id > 0) { $table->data[] = $row; -$url = ui_get_full_url('index.php?sec=godmode/extensions&sec2=extensions/files_repo'); -echo ""; +$url = ui_get_full_url('index.php?sec=extensions&sec2=godmode/files_repo/files_repo'); +echo ''; html_print_table($table); html_print_action_buttons($submit_button); echo ''; diff --git a/pandora_console/godmode/files_repo/files_repo_list.php b/pandora_console/godmode/files_repo/files_repo_list.php new file mode 100644 index 0000000000..f89b4b2d12 --- /dev/null +++ b/pandora_console/godmode/files_repo/files_repo_list.php @@ -0,0 +1,153 @@ + 'id', + 'order' => 'DESC', +]; + +$files = files_repo_get_files($filter); + +if (empty($files) === false) { + $url = ui_get_full_url('index.php?sec=extensions&sec2=godmode/files_repo/files_repo'); + + $total_files = files_repo_get_files(false, true); + ui_pagination($total_files, $url, $offset); + + $table = new stdClass(); + $table->width = '100%'; + $table->class = 'info_table'; + $table->style = []; + $table->style[1] = 'max-width: 200px;'; + $table->style[4] = 'text-align: center;'; + $table->head = []; + $table->head[0] = __('Name'); + $table->head[1] = __('Description'); + $table->head[2] = __('Size'); + $table->head[3] = __('Last modification'); + $table->head[4] = ''; + $table->data = []; + + foreach ($files as $file_id => $file) { + $data = []; + // Prepare the filename for the get_file.php script. + $document_root = str_replace( + '\\', + '/', + io_safe_output($_SERVER['DOCUMENT_ROOT']) + ); + $file['location'] = str_replace( + '\\', + '/', + io_safe_output($file['location']) + ); + $relative_path = str_replace($document_root, '', $file['location']); + $file_name = explode('/', $file['location']); + $file_decoded = $file_name[(count($file_name) - 1)]; + $file_path = base64_encode($file_decoded); + $hash = md5($file_path.$config['server_unique_identifier']); + $url_get_file = ui_get_full_url( + 'include/get_file.php?file='.urlencode($file_path).'&hash='.$hash + ); + + $date_format = (isset($config['date_format']) === true) ? io_safe_output($config['date_format']) : 'F j, Y - H:m'; + + $data[0] = ''.$file['name'].''; + // Name. + $data[1] = ui_print_truncate_text( + $file['description'], + 'description', + true, + true + ); + // Description. + $data[2] = ui_format_filesize($file['size']); + // Size. + $data[3] = date($date_format, $file['mtime']); + // Last modification. + // Public URL. + $data[4] = ''; + $table->cellclass[][4] = 'table_action_buttons'; + if (empty($file['hash']) === false) { + $message = __('Copy to clipboard').': Ctrl+C -> Enter'; + $action = 'window.prompt(\''.$message.'\', \''.$url_get_file.'\');'; + $data[4] .= ''; + $data[4] .= html_print_image( + 'images/world.png', + true, + ['title' => __('Public link')] + ); + // Public link image. + $data[4] .= ' '; + } + + $data[4] .= ''; + $data[4] .= html_print_image( + 'images/download.png', + true, + [ + 'title' => __('Download'), + 'style' => 'padding:3px', + ] + ); + // Download image. + $data[4] .= ''; + + $config_url = $url.'&tab=configuration&file_id='.$file_id; + $data[4] .= ''; + $data[4] .= html_print_image( + 'images/edit.svg', + true, + [ + 'title' => __('Edit'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + // Edit image. + $data[4] .= ''; + + $delete_url = $url.'&delete=1&file_id='.$file_id; + $data[4] .= ''; + $data[4] .= html_print_image( + 'images/delete.svg', + true, + [ + 'title' => __('Delete'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + // Delete image. + $data[4] .= ''; + + $table->data[] = $data; + } + + html_print_table($table); +} else { + ui_print_info_message(__('No items')); +} diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 171e16870b..bd041e098a 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -508,6 +508,8 @@ if ($access_console_node === true) { enterprise_hook('skins_submenu'); + enterprise_hook('translate_string_submenu'); + $menu_godmode['gsetup']['sub'] = $sub; } } diff --git a/pandora_console/include/functions_extensions.php b/pandora_console/include/functions_extensions.php index acecf194ec..f381484461 100755 --- a/pandora_console/include/functions_extensions.php +++ b/pandora_console/include/functions_extensions.php @@ -169,13 +169,21 @@ function extensions_get_extensions($enterprise=false, $rel_path='') $file = readdir($handle); } - // Load extensions in enterprise directory - if (! $enterprise && file_exists($master_dir)) { - return array_merge($extensions, extensions_get_extensions(true, $rel_path)); + if (isset($extensions['ipam.php']) === true) { + unset($extensions['ipam.php']); } - if (isset($extensions['ipam.php'])) { - unset($extensions['ipam.php']); + if (isset($extensions['translate_string.php']) === true) { + unset($extensions['translate_string.php']); + } + + if (isset($extensions['files_repo.php']) === true) { + unset($extensions['files_repo.php']); + } + + // Load extensions in enterprise directory. + if (! $enterprise && file_exists($master_dir)) { + return array_merge($extensions, extensions_get_extensions(true, $rel_path)); } return $extensions; diff --git a/pandora_console/extensions/files_repo/functions_files_repo.php b/pandora_console/include/functions_files_repository.php similarity index 69% rename from pandora_console/extensions/files_repo/functions_files_repo.php rename to pandora_console/include/functions_files_repository.php index 2989499350..18ac6ce8ad 100644 --- a/pandora_console/extensions/files_repo/functions_files_repo.php +++ b/pandora_console/include/functions_files_repository.php @@ -1,17 +1,34 @@

'; + $msg_error .= sprintf( + __('Please check that the web server has write rights on the %s directory'), + $attachment_path + ); + + // Attachment/ check. + if (is_writable($attachment_path) === false) { $messages .= ui_print_error_message( [ - 'message' => __('Attachment directory is not writable by HTTP Server').''.'

'.sprinf(__('Please check that the web server has write rights on the %s directory'), $attachment_path), + 'message' => $msg_error, 'no_close' => true, 'force_style' => 'color: #000000 !important', ], @@ -33,17 +57,17 @@ function files_repo_check_directory($print_messages=false) true ); } else { - // attachment/agent_packages/ check - if (!file_exists($files_repo_path) || !is_writable($files_repo_path)) { - // Create the directoty if not exist - if (!file_exists($files_repo_path)) { + // Attachment/agent_packages/ check. + if (file_exists($files_repo_path) === false || is_writable($files_repo_path) === false) { + // Create the directoty if not exist. + if (file_exists($files_repo_path) === false) { mkdir($files_repo_path); } - if (!is_writable($files_repo_path)) { + if (is_writable($files_repo_path) === false) { $messages .= ui_print_error_message( [ - 'message' => __('Attachment directory is not writable by HTTP Server').''.'

'.sprintf(__('Please check that the web server has write rights on the %s directory'), $attachment_path), + 'message' => $msg_error, 'no_close' => true, 'force_style' => 'color: #000000 !important', ], @@ -58,48 +82,60 @@ function files_repo_check_directory($print_messages=false) } } - if ($print_messages) { - echo $messages; - } + echo $messages; return $result; } -function files_repo_check_file_acl($file_id, $user_id=false, $file_groups=false, $user_groups=false) -{ +/** + * Check acl file + * + * @param integer $file_id ID. + * @param boolean $user_id Users. + * @param boolean $file_groups File Groups. + * @param boolean $user_groups User Groups. + * + * @return boolean + */ +function files_repo_check_file_acl( + $file_id, + $user_id=false, + $file_groups=false, + $user_groups=false +) { global $config; $result = false; - if (!$user_id) { + if (empty($user_id) === true) { $user_id = $config['id_user']; } - if (is_user_admin($user_id)) { + if (is_user_admin($user_id) === true) { return true; } if (!$file_groups) { $file_groups = files_repo_get_file_groups($file_id); - if (empty($file_groups)) { + if (empty($file_groups) === true) { $file_groups = []; } } - if (in_array(0, $file_groups)) { + if (in_array(0, $file_groups) === true) { return true; } if (!$user_groups) { $user_groups = users_get_groups($user_id, false, true); - if (empty($user_groups)) { + if (empty($user_groups) === true) { $user_groups = []; } } foreach ($file_groups as $group_id) { - // $user_groups has the id in the array keys - if (in_array($group_id, $user_groups)) { + // $user_groups has the id in the array keys. + if (in_array($group_id, $user_groups) === true) { $result = true; break; } @@ -109,13 +145,19 @@ function files_repo_check_file_acl($file_id, $user_id=false, $file_groups=false, } +/** + * File groups. + * + * @param integer $file_id File. + * + * @return array + */ function files_repo_get_file_groups($file_id) { $groups = []; $filter = ['id_file' => $file_id]; $result = db_get_all_rows_filter('tfiles_repo_group', $filter, 'id_group'); - - if (!empty($result)) { + if (empty($result) === false) { foreach ($result as $key => $value) { $groups[] = $value['id_group']; } @@ -125,13 +167,19 @@ function files_repo_get_file_groups($file_id) } +/** + * File user groups. + * + * @param string $user_id User id. + * + * @return array + */ function files_repo_get_user_groups($user_id) { $groups = []; $filter = ['id_usuario' => $user_id]; $result = db_get_all_rows_filter('tusuario_perfil', $filter, 'id_grupo'); - - if (!empty($result)) { + if (empty($result) === false) { foreach ($result as $key => $value) { $groups[] = $value['id_grupo']; } @@ -141,7 +189,15 @@ function files_repo_get_user_groups($user_id) } -function files_repo_get_files($filter=false, $count=false) +/** + * Get files. + * + * @param array $filter Filters. + * @param boolean $count Count. + * + * @return array + */ +function files_repo_get_files($filter=[], $count=false) { global $config; @@ -171,9 +227,9 @@ function files_repo_get_files($filter=false, $count=false) $data['name'] = $file['name']; $data['description'] = $file['description']; $data['location'] = $files_repo_path.'/'.$file['id'].'_'.$data['name']; - // Size in bytes + // Size in bytes. $data['size'] = filesize($data['location']); - // Last modification time in unix timestamp + // Last modification time in unix timestamp. $data['mtime'] = filemtime($data['location']); $data['groups'] = $file_groups; $data['hash'] = $file['hash']; @@ -188,6 +244,16 @@ function files_repo_get_files($filter=false, $count=false) } +/** + * Add file. + * + * @param string $file_input_name Name. + * @param string $description Description. + * @param array $groups Groups. + * @param boolean $public Mode. + * + * @return array + */ function files_repo_add_file($file_input_name='upfile', $description='', $groups=[], $public=false) { global $config; @@ -210,10 +276,10 @@ function files_repo_add_file($file_input_name='upfile', $description='', $groups $invalid_extensions = '/^(php|php1|php2|php3|php4|php5|php7|php8|phar|phptml|phps)$/i'; if (preg_match($invalid_extensions, $extension) === 0) { - // Replace conflictive characters + // Replace conflictive characters. $filename = str_replace([' ', '=', '?', '&'], '_', $filename); $filename = filter_var($filename, FILTER_SANITIZE_URL); - // The filename should not be larger than 200 characters + // The filename should not be larger than 200 characters. if (mb_strlen($filename, 'UTF-8') > 200) { $filename = mb_substr($filename, 0, 200, 'UTF-8'); } @@ -267,6 +333,16 @@ function files_repo_add_file($file_input_name='upfile', $description='', $groups } +/** + * Update file. + * + * @param string $file_id File Name. + * @param string $description Description. + * @param array $groups Groups. + * @param boolean $public Mode. + * + * @return array + */ function files_repo_update_file($file_id, $description='', $groups=[], $public=false) { global $config; @@ -308,6 +384,13 @@ function files_repo_update_file($file_id, $description='', $groups=[], $public=f } +/** + * Delete File + * + * @param string $file_id File Name. + * + * @return mixed + */ function files_repo_delete_file($file_id) { global $config; diff --git a/pandora_console/include/functions_io.php b/pandora_console/include/functions_io.php index 6283fdbaed..5b93341a56 100755 --- a/pandora_console/include/functions_io.php +++ b/pandora_console/include/functions_io.php @@ -410,32 +410,14 @@ function __($string /*, variable arguments */) global $config; - if (defined('METACONSOLE')) { - enterprise_include_once('meta/include/functions_meta.php'); + enterprise_include_once('include/functions_setup.php'); + $tranlateString = call_user_func_array( + 'get_defined_translation', + array_values(func_get_args()) + ); - $tranlateString = call_user_func_array( - 'meta_get_defined_translation', - array_values(func_get_args()) - ); - - if ($tranlateString !== false) { - return $tranlateString; - } - } else if (enterprise_installed() - && isset($config['translate_string_extension_installed']) - && $config['translate_string_extension_installed'] == 1 - && array_key_exists('translate_string.php', $extensions) - ) { - enterprise_include_once('extensions/translate_string/functions.php'); - - $tranlateString = call_user_func_array( - 'get_defined_translation', - array_values(func_get_args()) - ); - - if ($tranlateString !== false) { - return $tranlateString; - } + if ($tranlateString !== false) { + return $tranlateString; } if ($string == '') { diff --git a/pandora_console/include/get_file.php b/pandora_console/include/get_file.php index 679fdad5ad..435ac8dded 100644 --- a/pandora_console/include/get_file.php +++ b/pandora_console/include/get_file.php @@ -82,10 +82,9 @@ if (empty($file) === true || empty($hash) === true || $hash !== md5($file_raw.$c $downloadable_file = $_SERVER['DOCUMENT_ROOT'].'/pandora_console/'.$file; break; - case 'extensions/files_repo': + case 'godmode/files_repo/files_repo': $attachment_path = io_safe_output($config['attachment_store']); $downloadable_file = $attachment_path.'/files_repo/'.$file; - // $downloadable_file = $_SERVER['DOCUMENT_ROOT'].'/pandora_console/attachment/files_repo/'.$file; break; case 'godmode/servers/plugin': diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index c800d9b372..011d0a6581 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -752,6 +752,11 @@ if ($access_console_node === true) { $sub['godmode/agentes/planned_downtime.list']['id'] = 'Scheduled_downtime'; } + if ((bool) check_acl($config['id_user'], 0, 'PM') === true) { + $sub['godmode/files_repo/files_repo']['text'] = __('File Repository'); + $sub['godmode/files_repo/files_repo']['id'] = 'File_repository'; + } + foreach ($config['extensions'] as $extension) { // If no operation_menu is a godmode extension. if ($extension['operation_menu'] == '') { diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 4c527345c0..6887710bcb 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -4532,4 +4532,26 @@ CREATE TABLE IF NOT EXISTS `tpandora_cve` ( `cvss_score` DOUBLE DEFAULT NULL, `cvss_vector` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`cve_id`) -) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + +-- --------------------------------------------------------------------- +-- Table `tfiles_repo` +-- --------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tfiles_repo` ( + `id` int(5) unsigned NOT NULL auto_increment, + `name` varchar(255) NOT NULL, + `description` varchar(500) NULL default '', + `hash` varchar(8) NULL default '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- --------------------------------------------------------------------- +-- Table `tfiles_repo_group` +-- --------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tfiles_repo_group` ( + `id` int(10) unsigned NOT NULL auto_increment, + `id_file` int(5) unsigned NOT NULL, + `id_group` int(4) unsigned NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`id_file`) REFERENCES tfiles_repo(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file From 6eefd38f65d844a3c60ecfdef10f7eb4a60ceab0 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 28 Nov 2023 08:49:58 +0100 Subject: [PATCH 095/157] move extension translate_string and file_repo pandora_enterprise#12333 --- .../extras/delete_files/delete_files.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 6704356ae4..a57328e54f 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1720,7 +1720,18 @@ include/functions_integriaims.php include/ajax/integria_incidents.ajax.php enterprise/operation/log/log_source.php enterprise/include/class/LogSource.class.php -enterprise/extensions/translate_string enterprise/extensions/translate_string.php -extensions/files_repo +enterprise/extensions/translate_string/functions.php +enterprise/extensions/translate_string/translate_string.oracle.sql +enterprise/extensions/translate_string/translate_string.postgresql.sql +enterprise/extensions/translate_string/translate_string.sql +enterprise/extensions/translate_string extensions/files_repo.php +extensions/files_repo/files_repo_form.php +extensions/files_repo/files_repo_get_file.php +extensions/files_repo/files_repo_list.php +extensions/files_repo/functions_files_repo.php +extensions/files_repo/sql/files_repo.oracle.sql +extensions/files_repo/sql/files_repo.postgreSQL.sql +extensions/files_repo/sql/files_repo.sql +extensions/files_repo \ No newline at end of file From e7ebbedabc2f6188def055435810ad5f020eb770 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 28 Nov 2023 09:34:10 +0100 Subject: [PATCH 096/157] #12176 formatted error --- .../wizards/DiscoveryTaskList.class.php | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index e831022c23..0872b52e88 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -1474,13 +1474,20 @@ class DiscoveryTaskList extends HTML } else if ((int) $task['type'] === DISCOVERY_EXTENSION) { // Content. $countSummary = 1; + $countErrors = 1; + $tableErrors = new StdClasS(); + $tableErrors->class = 'databox data'; + $tableErrors->width = '75%'; + $tableErrors->styleTable = 'margin: 2em auto 0;border: 1px solid #ddd;background: white;'; + $tableErrors->rowid = []; + $tableErrors->data = []; if (is_array($task['stats']) === true && count(array_filter(array_keys($task['stats']), 'is_numeric')) === count($task['stats'])) { foreach ($task['stats'] as $key => $summary) { - $table->data[$i][0] = ''.__('Summary').' '.$countSummary.''; - $table->data[$i][1] = ''; - $countSummary++; - $i++; if (is_array($summary) === true) { + $table->data[$i][0] = ''.__('Summary').' '.$countSummary.''; + $table->data[$i][1] = ''; + $countSummary++; + $i++; if (empty($summary['summary']) === true && empty($summary['info']) === true) { $table->data[$i][0] = json_encode($summary, JSON_PRETTY_PRINT); $table->data[$i][1] = ''; @@ -1517,8 +1524,12 @@ class DiscoveryTaskList extends HTML $i++; } } else { - $table->data[$i][0] = $summary; - $table->data[$i][1] = ''; + $tableErrors->data[$i][0] = ''.__('Error %s', $countErrors).''; + $tableErrors->data[$i][1] = ''; + $i++; + $tableErrors->data[$i][0] = $summary; + $tableErrors->data[$i][1] = ''; + $countErrors++; $i++; } } @@ -1565,7 +1576,15 @@ class DiscoveryTaskList extends HTML } $output = '

'.__('Summary').'
'; - $output .= html_print_table($table, true).''; + if (is_array($table->data) === true && count($table->data) > 0) { + $output .= html_print_table($table, true); + } + + if (is_array($tableErrors->data) === true && count($tableErrors->data) > 0) { + $output .= html_print_table($tableErrors, true); + } + + $output .= ''; } return $output; From 4ce47cec8ebb2870c2ae8aa5c07d36edefc80eed Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 28 Nov 2023 09:56:51 +0100 Subject: [PATCH 097/157] #12176 control error legacy --- .../wizards/DiscoveryTaskList.class.php | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 0872b52e88..d088e8c84f 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -1422,6 +1422,14 @@ class DiscoveryTaskList extends HTML $table->rowid = []; $table->data = []; + $countErrors = 1; + $tableErrors = new StdClasS(); + $tableErrors->class = 'databox data'; + $tableErrors->width = '75%'; + $tableErrors->styleTable = 'margin: 2em auto 0;border: 1px solid #ddd;background: white;'; + $tableErrors->rowid = []; + $tableErrors->data = []; + if ($task['review_mode'] == DISCOVERY_RESULTS) { $agents_review = db_get_all_rows_filter( 'tdiscovery_tmp_agents', @@ -1474,13 +1482,6 @@ class DiscoveryTaskList extends HTML } else if ((int) $task['type'] === DISCOVERY_EXTENSION) { // Content. $countSummary = 1; - $countErrors = 1; - $tableErrors = new StdClasS(); - $tableErrors->class = 'databox data'; - $tableErrors->width = '75%'; - $tableErrors->styleTable = 'margin: 2em auto 0;border: 1px solid #ddd;background: white;'; - $tableErrors->rowid = []; - $tableErrors->data = []; if (is_array($task['stats']) === true && count(array_filter(array_keys($task['stats']), 'is_numeric')) === count($task['stats'])) { foreach ($task['stats'] as $key => $summary) { if (is_array($summary) === true) { @@ -1571,7 +1572,13 @@ class DiscoveryTaskList extends HTML $table->data[$i++][1] .= ''; } } else { - $table->data[$i][0] = $task['stats']['summary']; + $tableErrors->data[$i][0] = ''.__('Error %s', $countErrors).''; + $tableErrors->data[$i][1] = ''; + $i++; + $tableErrors->data[$i][0] = $task['stats']['summary']; + $tableErrors->data[$i][1] = ''; + $countErrors++; + $i++; } } From 5bd689500c3c65fbb4e10f06df950cda0693b9c6 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 28 Nov 2023 11:06:39 +0100 Subject: [PATCH 098/157] move extension translate_string and file_repo pandora_enterprise#12333 --- pandora_console/extras/mr/67.sql | 4 +- .../files_repo/files_repo_get_file.php | 81 +++++++++++++++++++ .../godmode/files_repo/files_repo_list.php | 6 +- pandora_console/godmode/menu.php | 20 +++-- pandora_console/operation/menu.php | 78 +++++------------- pandora_console/pandoradb_data.sql | 4 +- 6 files changed, 127 insertions(+), 66 deletions(-) create mode 100644 pandora_console/godmode/files_repo/files_repo_get_file.php diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index 2e04ab23c2..ded4d9d9bb 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -24,7 +24,7 @@ CREATE TABLE IF NOT EXISTS `tfiles_repo` ( `description` varchar(500) NULL default '', `hash` varchar(8) NULL default '', PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; CREATE TABLE IF NOT EXISTS `tfiles_repo_group` ( `id` int(10) unsigned NOT NULL auto_increment, @@ -32,6 +32,6 @@ CREATE TABLE IF NOT EXISTS `tfiles_repo_group` ( `id_group` int(4) unsigned NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`id_file`) REFERENCES tfiles_repo(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; COMMIT; diff --git a/pandora_console/godmode/files_repo/files_repo_get_file.php b/pandora_console/godmode/files_repo/files_repo_get_file.php new file mode 100644 index 0000000000..b9a5b4c821 --- /dev/null +++ b/pandora_console/godmode/files_repo/files_repo_get_file.php @@ -0,0 +1,81 @@ + $file_hash]); +if (!$file) { + throw_error(10); +} + +// Case sensitive check. +$check_hash = ($file['hash'] == $file_hash) ? true : false; +if (!$check_hash) { + throw_error(10); +} + +// Get the location. +$files_repo_path = io_safe_output($config['attachment_store']).'/files_repo'; +$location = $files_repo_path.'/'.$file['id'].'_'.$file['name']; +if (!file_exists($location) || !is_readable($location) || !is_file($location)) { + throw_error(5); +} + +// All checks are fine. Download the file! +header('Content-type: aplication/octet-stream;'); +header('Content-Length: '.filesize($location)); +header('Content-Disposition: attachment; filename="'.$file['name'].'"'); +readfile($location); + + +/** + * Show errors + * + * @param integer $time Sleep. + * + * @return void + */ +function throw_error($time=15) +{ + sleep($time); + + $styleError = 'background:url("../images/err.png") no-repeat scroll 0 0 transparent; padding:4px 1px 6px 30px; color:#CC0000;'; + echo "

".__('Unreliable petition').'. '.__('Please contact the administrator').'

'; + exit; +} diff --git a/pandora_console/godmode/files_repo/files_repo_list.php b/pandora_console/godmode/files_repo/files_repo_list.php index f89b4b2d12..bc2fb4e1bf 100644 --- a/pandora_console/godmode/files_repo/files_repo_list.php +++ b/pandora_console/godmode/files_repo/files_repo_list.php @@ -94,8 +94,12 @@ if (empty($files) === false) { $data[4] = ''; $table->cellclass[][4] = 'table_action_buttons'; if (empty($file['hash']) === false) { + $url_get_public_file = ui_get_full_url( + 'godmode/files_repo/files_repo_get_file.php?file='.$file['hash'] + ); + $message = __('Copy to clipboard').': Ctrl+C -> Enter'; - $action = 'window.prompt(\''.$message.'\', \''.$url_get_file.'\');'; + $action = 'window.prompt(\''.$message.'\', \''.$url_get_public_file.'\');'; $data[4] .= ''; $data[4] .= html_print_image( 'images/world.png', diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index bd041e098a..da029bc11e 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -712,15 +712,25 @@ if ($access_console_node === true) { } if ($access_console_node === true) { - // Tools + // Tools. $menu_godmode['tools']['text'] = __('Tools'); $menu_godmode['tools']['sec2'] = 'operation/extensions'; $menu_godmode['tools']['id'] = 'oper-extensions'; $sub = []; - $sub['operation/agentes/exportdata']['text'] = __('Export data'); - $sub['operation/agentes/exportdata']['id'] = 'export_data'; - $sub['extensions/files_repo']['text'] = __('File repository'); - $sub['extensions/files_repo']['id'] = 'file_repository'; + + if (check_acl($config['id_user'], 0, 'RR') + || check_acl($config['id_user'], 0, 'RW') + || check_acl($config['id_user'], 0, 'RM') + ) { + $sub['operation/agentes/exportdata']['text'] = __('Export data'); + $sub['operation/agentes/exportdata']['id'] = 'export_data'; + } + + if ((bool) check_acl($config['id_user'], 0, 'PM') === true) { + $sub['godmode/files_repo/files_repo']['text'] = __('File repository'); + $sub['godmode/files_repo/files_repo']['id'] = 'file_repository'; + } + $menu_godmode['tools']['sub'] = $sub; // About. diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 011d0a6581..f0777a61f1 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -734,29 +734,8 @@ if ($access_console_node === true) { } if ($access_console_node === true) { - // Rest of options, all with AR privilege (or should events be with incidents?) - // ~ if (check_acl ($config['id_user'], 0, "AR")) { // Extensions menu additions. if (is_array($config['extensions'])) { - $sub = []; - $sub2 = []; - - if (check_acl($config['id_user'], 0, 'RR') || check_acl($config['id_user'], 0, 'RW') || check_acl($config['id_user'], 0, 'RM')) { - $sub['operation/agentes/exportdata']['text'] = __('Export data'); - $sub['operation/agentes/exportdata']['id'] = 'Export_data'; - $sub['operation/agentes/exportdata']['subsecs'] = ['operation/agentes/exportdata']; - } - - if (check_acl($config['id_user'], 0, 'AR') || check_acl($config['id_user'], 0, 'AD') || check_acl($config['id_user'], 0, 'AW')) { - $sub['godmode/agentes/planned_downtime.list']['text'] = __('Scheduled downtime'); - $sub['godmode/agentes/planned_downtime.list']['id'] = 'Scheduled_downtime'; - } - - if ((bool) check_acl($config['id_user'], 0, 'PM') === true) { - $sub['godmode/files_repo/files_repo']['text'] = __('File Repository'); - $sub['godmode/files_repo/files_repo']['id'] = 'File_repository'; - } - foreach ($config['extensions'] as $extension) { // If no operation_menu is a godmode extension. if ($extension['operation_menu'] == '') { @@ -777,39 +756,19 @@ if ($access_console_node === true) { continue; } - // Check if was displayed inside other menu. - if ($extension['operation_menu']['fatherId'] == '') { - if ($extension_menu['name'] == 'Update manager') { - continue; - } - - $sub[$extension_menu['sec2']]['text'] = $extension_menu['name']; - $sub[$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); - $sub[$extension_menu['sec2']]['refr'] = 0; - } else { - if (array_key_exists('fatherId', $extension_menu)) { - // Check that extension father ID exists previously on the menu. - if ((strlen($extension_menu['fatherId']) > 0)) { - if (array_key_exists('subfatherId', $extension_menu) && empty($extension_menu['subfatherId']) === false) { - if ((strlen($extension_menu['subfatherId']) > 0)) { - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['text'] = __($extension_menu['name']); - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['refr'] = 0; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['icon'] = $extension_menu['icon']; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['sec'] = 'extensions'; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['extension'] = true; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['enterprise'] = $extension['enterprise']; - $menu_operation[$extension_menu['fatherId']]['hasExtensions'] = true; - } else { - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['text'] = __($extension_menu['name']); - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['refr'] = 0; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['icon'] = $extension_menu['icon']; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['sec'] = 'extensions'; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['extension'] = true; - $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['enterprise'] = $extension['enterprise']; - $menu_operation[$extension_menu['fatherId']]['hasExtensions'] = true; - } + if (array_key_exists('fatherId', $extension_menu)) { + // Check that extension father ID exists previously on the menu. + if ((strlen($extension_menu['fatherId']) > 0)) { + if (array_key_exists('subfatherId', $extension_menu) && empty($extension_menu['subfatherId']) === false) { + if ((strlen($extension_menu['subfatherId']) > 0)) { + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['text'] = __($extension_menu['name']); + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['refr'] = 0; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['icon'] = $extension_menu['icon']; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['sec'] = 'extensions'; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['extension'] = true; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['subfatherId']]['sub2'][$extension_menu['sec2']]['enterprise'] = $extension['enterprise']; + $menu_operation[$extension_menu['fatherId']]['hasExtensions'] = true; } else { $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['text'] = __($extension_menu['name']); $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); @@ -820,13 +779,20 @@ if ($access_console_node === true) { $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['enterprise'] = $extension['enterprise']; $menu_operation[$extension_menu['fatherId']]['hasExtensions'] = true; } + } else { + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['text'] = __($extension_menu['name']); + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['id'] = str_replace(' ', '_', $extension_menu['name']); + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['refr'] = 0; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['icon'] = $extension_menu['icon']; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['sec'] = 'extensions'; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['extension'] = true; + $menu_operation[$extension_menu['fatherId']]['sub'][$extension_menu['sec2']]['enterprise'] = $extension['enterprise']; + $menu_operation[$extension_menu['fatherId']]['hasExtensions'] = true; } } } } } - - // ~ } } $menu_operation['about_operation']['text'] = __('About'); diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index bfb1d0ee96..87ced3e421 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -125,10 +125,10 @@ INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_report_front_logo', 'images/pandora_logo_white.jpg'), ('custom_report_front_header', ''), ('custom_report_front_footer', ''), -('MR', 66), +('MR', 67), ('identification_reminder', 1), ('identification_reminder_timestamp', 0), -('current_package', 774), +('current_package', 775), ('post_process_custom_values', '{"0.00000038580247":"Seconds to months","0.00000165343915":"Seconds to weeks","0.00001157407407":"Seconds to days","0.01666666666667":"Seconds to minutes","0.00000000093132":"Bytes to Gigabytes","0.00000095367432":"Bytes to Megabytes","0.00097656250000":"Bytes to Kilobytes","0.00000001653439":"Timeticks to weeks","0.00000011574074":"Timeticks to days"}'), ('custom_docs_logo', 'default_docs.png'), ('custom_support_logo', 'default_support.png'), From deff8a3bce38b6ae67cab21d0985b4aed8642396 Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Tue, 28 Nov 2023 10:21:15 -0600 Subject: [PATCH 099/157] Change some defaults on pandora_agent.conf --- pandora_agents/pc/Linux/pandora_agent.conf | 32 +++++++++++++++---- pandora_agents/pc/Win32/pandora_agent.conf | 26 ++++++++++++++- .../shellscript/linux/pandora_agent.conf | 27 ++++++++++++++-- .../shellscript/mac_osx/pandora_agent.conf | 31 ++++++++++++++---- pandora_agents/unix/Linux/pandora_agent.conf | 14 +++++--- 5 files changed, 109 insertions(+), 21 deletions(-) diff --git a/pandora_agents/pc/Linux/pandora_agent.conf b/pandora_agents/pc/Linux/pandora_agent.conf index 4ad837f943..ee63d8b6a0 100644 --- a/pandora_agents/pc/Linux/pandora_agent.conf +++ b/pandora_agents/pc/Linux/pandora_agent.conf @@ -234,6 +234,21 @@ module_description Number of cron task files module_unit files module_end +# This module /var/log/syslog file, under the module name "syslog" +# And search for "ssh" string into it, sending only that information. +# module_begin +# module_name Syslog +# module_description Search for ssh string into /var/log/syslog file +# module_type log +# module_regexp /var/log/syslog +# module_pattern ssh +# module_end + +#Hardening plugin for security compliance analysis. Enable to use it. +#module_begin +#module_plugin /usr/share/pandora_agent/plugins/pandora_hardening -t 150 +#module_absoluteinterval 7d +#module_end # Plugin example @@ -241,11 +256,6 @@ module_end module_plugin pandora_df -# This parses /var/log/syslog file, under the module name "syslog" -# And search for "ssh" string into it, sending only that information. - -module_plugin grep_log /var/log/syslog Syslog ssh - # Get disk space free in MB #module_begin #module_name disk_root_free @@ -270,7 +280,6 @@ module_plugin grep_log /var/log/syslog Syslog ssh #module_end # Plugin for inventory on the agent. - # module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users process ip route # Example of preconditions @@ -303,4 +312,13 @@ module_plugin grep_log /var/log/syslog Syslog ssh # This plugin runs several security checks in a Linux system -#module_plugin pandora_security_check \ No newline at end of file +#module_plugin pandora_security_check + +# Extraction module example +#module_begin +#module_name Collector +#module_description Logs extraction module +#module_type log +#module_regexp /var/log/logfile.log +#module_pattern .* +#module_end \ No newline at end of file diff --git a/pandora_agents/pc/Win32/pandora_agent.conf b/pandora_agents/pc/Win32/pandora_agent.conf index 621c1d24ac..9d938c256b 100644 --- a/pandora_agents/pc/Win32/pandora_agent.conf +++ b/pandora_agents/pc/Win32/pandora_agent.conf @@ -1,6 +1,6 @@ # Base config file for Pandora FMS Windows Agent # (c) 2006-2023 Pandora FMS -# Version 7.0NG.774 +# Version 7.0NG.774 # This program is Free Software, you can redistribute it and/or modify it # under the terms of the GNU General Public Licence as published by the Free Software # Foundation; either version 2 of the Licence or any later version @@ -219,6 +219,21 @@ module_plugin cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\df.vbs" # module_description Free space on drive D: (%) # module_end +# Hardening plugin for security compliance analysis. +# module_begin +# module_plugin "%PROGRAMFILES%\Pandora_Agent\util\pandora_hardening.exe -t 150" +# module_absoluteinterval 7d +# module_end + +# Logs extraction +#module_begin +#module_name X_Server_log +#module_description Logs extraction module +#module_type log +#module_regexp C:\server\logs\xserver.log +#module_pattern .* +#module_end + # Sample of Windows inventory module (ONLY ENTERPRISE)! #module_begin #module_name Inventory @@ -344,4 +359,13 @@ module_plugin cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\df.vbs" #module_condition (3,8) cmd.exe /c echo range >> c:\log.txt #module_exec echo 5 #module_description Postcondition test module +#module_end + +# Example of collector module +#module_begin +#module_name Collector +#module_description Logs extraction module +#module_type log +#module_regexp /var/log/logfile.log +#module_pattern .* #module_end \ No newline at end of file diff --git a/pandora_agents/shellscript/linux/pandora_agent.conf b/pandora_agents/shellscript/linux/pandora_agent.conf index 98c137741e..fa0e0f9ff8 100644 --- a/pandora_agents/shellscript/linux/pandora_agent.conf +++ b/pandora_agents/shellscript/linux/pandora_agent.conf @@ -157,12 +157,33 @@ module_exec last | head -1 module_description Last Login module_end -# Plugin example +#Hardening plugin for security compliance analysis. Enable to use it. +#module_begin +#module_plugin /usr/share/pandora_agent/plugins/pandora_hardening -t 150 +#module_absoluteinterval 7d +#module_end -# This parses /var/log/syslog file, under the module name "syslog" +# This module parses /var/log/syslog file, under the module name "syslog" # And search for "ssh" string into it, sending only that information. -module_plugin grep_log /var/log/syslog Syslog ssh +module_begin +module_name Syslog +module_description Search for ssh string into /var/log/syslog file +module_type log +module_regexp /var/log/syslog +module_pattern ssh +module_end + +# Plugin example # Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software + +# Extraction module example +#module_begin +#module_name Collector +#module_description Logs extraction module +#module_type log +#module_regexp /var/log/logfile.log +#module_pattern .* +#module_end \ No newline at end of file diff --git a/pandora_agents/shellscript/mac_osx/pandora_agent.conf b/pandora_agents/shellscript/mac_osx/pandora_agent.conf index b4b3c35ac8..190f12a3da 100644 --- a/pandora_agents/shellscript/mac_osx/pandora_agent.conf +++ b/pandora_agents/shellscript/mac_osx/pandora_agent.conf @@ -372,13 +372,32 @@ module_end #module_description XGrid #module_end +#Hardening plugin for security compliance analysis. Enable to use it. +#module_begin +#module_plugin /usr/share/pandora_agent/plugins/pandora_hardening -t 150 +#module_absoluteinterval 7d +#module_end + +# This module parses /var/log/syslog file, under the module name "syslog" +# And search for "ssh" string into it, sending only that information. +#module_begin +#module_name Syslog +#module_description Log collection modules +#module_type log +#module_regexp /var/log/syslog +#module_pattern ssh +#module_end + # Plugin example -# This parses /var/log/syslog file, under the module name "syslog" -# And search for "ssh" string into it, sending only that information. - -#module_plugin grep_log /var/log/syslog Syslog ssh - # Plugin for inventory on the agent. - # module_plugin inventory 1 cpu ram video nic hd cdrom software + +# Extraction module example +#module_begin +#module_name Collector +#module_description Logs extraction module +#module_type log +#module_regexp /var/log/logfile.log +#module_pattern .* +#module_end \ No newline at end of file diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index 10458ddba5..1a4678da28 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -271,11 +271,17 @@ module_plugin pandora_netusage module_plugin autodiscover --default # Plugin for inventory on the agent. -#module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route +# module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route # Log collection modules. This will collect log files for forensic analysis and store everything # This is for LOG monitoring. Different than log monitoring. -#module_plugin grep_log_module /var/log/messages Syslog \.\* +#module_begin +#module_name Syslog +#module_description Log collection modules +#module_type log +#module_regexp /var/log/messages +#module_pattern .* +#module_end # Another samples of monitoring modules @@ -317,9 +323,9 @@ module_plugin autodiscover --default #module_absoluteinterval 7d #module_end -# Logs extraction +# Extraction module example #module_begin -#module_name Syslog +#module_name Collector #module_description Logs extraction module #module_type log #module_regexp /var/log/logfile.log From 64b612faea0c5ff58e1dacd9e2e692cf2980e93e Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Wed, 29 Nov 2023 09:40:34 +0100 Subject: [PATCH 100/157] #11494 Add tip and fix MTRS bug --- pandora_console/include/functions_modules.php | 4 ++++ .../include/lib/Dashboard/Widgets/service_level.php | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 4104d2660f..12fc5ec828 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4871,6 +4871,10 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtrs_array[] = 0; } else { foreach ($normal_event as $key => $value) { + if (isset($failed_event[$key]) === false) { + $failed_event[$key] = end($failed_event); + } + if (($failed_event[$key] - $normal_event[$key]) < 0) { $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); } else { diff --git a/pandora_console/include/lib/Dashboard/Widgets/service_level.php b/pandora_console/include/lib/Dashboard/Widgets/service_level.php index 7f3add7c08..8184495587 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/service_level.php +++ b/pandora_console/include/lib/Dashboard/Widgets/service_level.php @@ -533,8 +533,8 @@ class ServiceLevelWidget extends Widget $table->head[1] = __('% Av.'); $table->head[2] = __('MTBF'); $table->head[3] = __('MTRS'); - $table->head[4] = __('Crit. Events'); - $table->head[5] = __('Warn. Events'); + $table->head[4] = __('Crit. Events').ui_print_help_tip(__('Counted only critical events generated automatic by the module'), true); + $table->head[5] = __('Warn. Events').ui_print_help_tip(__('Counted only warning events generated automatic by the module'), true); $table->head[6] = __('Last change'); $table->data = []; $table->cellstyle = []; From 63945df5fdfbd7263fc33bbe94e2e27e974df8e6 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Wed, 29 Nov 2023 09:44:25 +0100 Subject: [PATCH 101/157] #11495 Add tip and fix MTRS bug --- pandora_console/include/functions_modules.php | 4 ++++ pandora_console/include/functions_reporting_html.php | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 52ce97df12..c3a1eb1ff4 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4872,6 +4872,10 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtrs_array[] = 0; } else { foreach ($normal_event as $key => $value) { + if (isset($failed_event[$key]) === false) { + $failed_event[$key] = end($failed_event); + } + if (($failed_event[$key] - $normal_event[$key]) < 0) { $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); } else { diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index e67bd2b173..e7eef0ae46 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -2793,8 +2793,8 @@ function reporting_html_service_level($table, $item, $pdf=0) $table_info->head[1] = __('% Av.'); $table_info->head[2] = __('MTBF'); $table_info->head[3] = __('MTRS'); - $table_info->head[4] = __('Crit. Events'); - $table_info->head[5] = __('Warn. Events'); + $table_info->head[4] = __('Crit. Events').ui_print_help_tip(__('Counted only critical events generated automatic by the module'), true); + $table_info->head[5] = __('Warn. Events').ui_print_help_tip(__('Counted only warning events generated automatic by the module'), true); $table_info->head[6] = __('Last change'); $table_info->data = []; $table_info->cellstyle = []; From 892048554e60fb688281297ffd825a23d295585e Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 29 Nov 2023 10:27:55 +0100 Subject: [PATCH 102/157] #12468 Fixed instructions --- pandora_console/include/functions_events.php | 7 +++---- pandora_console/operation/events/events.php | 14 +------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 2a91641315..253749ce8e 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -5775,7 +5775,7 @@ function events_get_field_value_by_event_id( } -function events_get_instructions($event) +function events_get_instructions($event, $max_text_length=300) { if (is_array($event) === false) { return ''; @@ -5823,17 +5823,17 @@ function events_get_instructions($event) return ''; } - $max_text_length = 300; $over_text = io_safe_output($value); if (strlen($over_text) > ($max_text_length + 3)) { $over_text = substr($over_text, 0, $max_text_length).'...'; + } else { + return $value; } $output = '
'; $output .= ''; $output .= ''; @@ -5842,7 +5842,6 @@ function events_get_instructions($event) true, ['title' => $over_text] ).''; - $output .= ''; return $output; } diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 4bddd880c5..467f8dafd8 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -644,19 +644,7 @@ if (is_ajax() === true) { $tmp->data = ui_print_truncate_text($tmp->data, 10); } - $tmp->instructions = events_get_instructions($item); - if (strlen($tmp->instructions) >= 20) { - $tmp->instructions = ui_print_truncate_text( - $tmp->instructions, - 20, - false, - true, - false, - '…', - true, - true, - ); - } + $tmp->instructions = events_get_instructions($item, 15); $tmp->user_comment = ui_print_comments( event_get_last_comment( From db89c72be577bf4fcae03d7c717e6f337c9256cb Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 29 Nov 2023 16:00:46 +0100 Subject: [PATCH 103/157] fix error empty clusters pandora_enterprise#12511 --- .../godmode/agentes/agent_manager.php | 27 +++++++++++++++-- pandora_console/include/functions_agents.php | 29 +++++++++++++++++-- pandora_console/include/lib/Cluster.php | 4 +++ pandora_console/views/cluster/view.php | 6 +++- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index 557b855e09..a7f979180a 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -1104,11 +1104,24 @@ if ($new_agent === false) { $actionButtons .= html_print_input_hidden('id_agente', $id_agente); if (is_management_allowed() === true) { + $clusters = agents_get_agent_belongs_cluster($id_agente); + $cluster_belongs = ''; + if (empty($clusters) === false) { + $clusters = array_reduce( + $clusters, + function ($carry, $item) { + $carry[] = $item['name']; + return $carry; + } + ); + $cluster_belongs = implode(', ', $clusters); + } + $actionButtons .= html_print_button( __('Delete agent'), 'deleteAgent', false, - 'deleteAgentDialog('.$id_agente.')', + 'deleteAgentDialog('.$id_agente.', "'.$cluster_belongs.'")', [ 'icon' => 'delete', 'mode' => 'secondary dialog_opener', @@ -1156,10 +1169,18 @@ ui_require_jquery_file('bgiframe'); } } - function deleteAgentDialog($idAgente) { + function deleteAgentDialog($idAgente, cluster) { + var msg_cluster = ''; + if(cluster) { + msg_cluster = ""; + msg_cluster += ': '; + msg_cluster += cluster; + msg_cluster += '. '; + } + confirmDialog({ title: "", - message: "", + message: msg_cluster + "", onAccept: function() { window.location.assign('index.php?sec=gagente&sec2=godmode/agentes/modificar_agente&borrar_agente='+$idAgente); } diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 2d6803ccd4..32dc0a9312 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -4976,13 +4976,38 @@ function get_resume_agent_concat($id_agente, $all_groups, $agent) } +/** + * agent belongs to the clusters. + * + * @param integer $idAgent + * + * @return array Names clusters. + */ +function agents_get_agent_belongs_cluster(int $idAgent): array +{ + $sql = sprintf( + 'SELECT tcluster.name + FROM tcluster + INNER JOIN tcluster_agent + ON tcluster.id = tcluster_agent.id_cluster + WHERE tcluster_agent.id_agent = %d', + $idAgent + ); + + $result = db_get_all_rows_sql($sql); + if ($result === false) { + $result = []; + } + + return $result; +} + + /** * Return an array with a list of status agents * * @return array. */ - - function agents_status_list() { $status_list = []; diff --git a/pandora_console/include/lib/Cluster.php b/pandora_console/include/lib/Cluster.php index b7bd21d929..46e7ba4324 100644 --- a/pandora_console/include/lib/Cluster.php +++ b/pandora_console/include/lib/Cluster.php @@ -213,6 +213,10 @@ class Cluster extends Entity public function getCounters() :array { $id_agent_modules = $this->getIdsModulesInvolved(); + if (empty($id_agent_modules) === true) { + return []; + } + $sql = sprintf( 'SELECT SUM( IF(estado = 1, 1, 0) ) AS critical, SUM( IF(estado = 2, 1, 0) ) AS warning, diff --git a/pandora_console/views/cluster/view.php b/pandora_console/views/cluster/view.php index 32bcdb0736..93894ba7e5 100644 --- a/pandora_console/views/cluster/view.php +++ b/pandora_console/views/cluster/view.php @@ -151,7 +151,11 @@ $agentCountModules = html_print_div( true ); -$alive_animation = agents_get_starmap(0, 180, 30, $module_involved_ids); +$alive_animation = ''; +if (empty($module_involved_ids) === false) { + $alive_animation = agents_get_starmap(0, 180, 30, $module_involved_ids); +} + $output = '
'; $output .= '
'; From 7a5201db4ff30baf0cd826319317127ff5bdd22a Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 29 Nov 2023 16:31:06 +0100 Subject: [PATCH 104/157] #8365 NCM V3 Minor fix --- pandora_console/include/javascript/pandora_ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index 80ddfd06f5..00ece1a178 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -514,7 +514,7 @@ function load_modal(settings) { if (settings.cleanup != undefined) { settings.cleanup(); } - $("#modal_overlay").removeClass("ui-widget-overlay"); + $("#modal_overlay").remove(); }, beforeClose: settings.beforeClose() }); From 8940e2b9aa8fe73dc794e3175922fda40048c84a Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Wed, 29 Nov 2023 11:13:09 -0600 Subject: [PATCH 105/157] Automatically apply log collection --- pandora_agents/pc/Linux/pandora_agent.conf | 14 +++++++------- pandora_agents/pc/Win32/pandora_agent.conf | 9 --------- .../shellscript/linux/pandora_agent.conf | 1 - .../shellscript/mac_osx/pandora_agent.conf | 14 +++++++------- pandora_agents/unix/Linux/pandora_agent.conf | 14 +++++++------- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/pandora_agents/pc/Linux/pandora_agent.conf b/pandora_agents/pc/Linux/pandora_agent.conf index ee63d8b6a0..e25a82a517 100644 --- a/pandora_agents/pc/Linux/pandora_agent.conf +++ b/pandora_agents/pc/Linux/pandora_agent.conf @@ -236,13 +236,13 @@ module_end # This module /var/log/syslog file, under the module name "syslog" # And search for "ssh" string into it, sending only that information. -# module_begin -# module_name Syslog -# module_description Search for ssh string into /var/log/syslog file -# module_type log -# module_regexp /var/log/syslog -# module_pattern ssh -# module_end +module_begin +module_name Syslog +module_description Search for ssh string into /var/log/syslog file +module_type log +module_regexp /var/log/syslog +module_pattern ssh +module_end #Hardening plugin for security compliance analysis. Enable to use it. #module_begin diff --git a/pandora_agents/pc/Win32/pandora_agent.conf b/pandora_agents/pc/Win32/pandora_agent.conf index 9d938c256b..eb891d5866 100644 --- a/pandora_agents/pc/Win32/pandora_agent.conf +++ b/pandora_agents/pc/Win32/pandora_agent.conf @@ -225,15 +225,6 @@ module_plugin cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\df.vbs" # module_absoluteinterval 7d # module_end -# Logs extraction -#module_begin -#module_name X_Server_log -#module_description Logs extraction module -#module_type log -#module_regexp C:\server\logs\xserver.log -#module_pattern .* -#module_end - # Sample of Windows inventory module (ONLY ENTERPRISE)! #module_begin #module_name Inventory diff --git a/pandora_agents/shellscript/linux/pandora_agent.conf b/pandora_agents/shellscript/linux/pandora_agent.conf index fa0e0f9ff8..49e8866f9a 100644 --- a/pandora_agents/shellscript/linux/pandora_agent.conf +++ b/pandora_agents/shellscript/linux/pandora_agent.conf @@ -165,7 +165,6 @@ module_end # This module parses /var/log/syslog file, under the module name "syslog" # And search for "ssh" string into it, sending only that information. - module_begin module_name Syslog module_description Search for ssh string into /var/log/syslog file diff --git a/pandora_agents/shellscript/mac_osx/pandora_agent.conf b/pandora_agents/shellscript/mac_osx/pandora_agent.conf index 190f12a3da..ba9c0079a3 100644 --- a/pandora_agents/shellscript/mac_osx/pandora_agent.conf +++ b/pandora_agents/shellscript/mac_osx/pandora_agent.conf @@ -380,13 +380,13 @@ module_end # This module parses /var/log/syslog file, under the module name "syslog" # And search for "ssh" string into it, sending only that information. -#module_begin -#module_name Syslog -#module_description Log collection modules -#module_type log -#module_regexp /var/log/syslog -#module_pattern ssh -#module_end +module_begin +module_name Syslog +module_description Log collection modules +module_type log +module_regexp /var/log/syslog +module_pattern ssh +module_end # Plugin example diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index 1a4678da28..42fddd39f5 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -275,13 +275,13 @@ module_plugin autodiscover --default # Log collection modules. This will collect log files for forensic analysis and store everything # This is for LOG monitoring. Different than log monitoring. -#module_begin -#module_name Syslog -#module_description Log collection modules -#module_type log -#module_regexp /var/log/messages -#module_pattern .* -#module_end +module_begin +module_name Syslog +module_description Log collection modules +module_type log +module_regexp /var/log/messages +module_pattern .* +module_end # Another samples of monitoring modules From dbd7de857ba1899d3b4b6fb3a37ce180c5745caa Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Wed, 29 Nov 2023 11:44:02 -0600 Subject: [PATCH 106/157] Capture security and system events on windows. --- pandora_agents/pc/Win32/pandora_agent.conf | 15 +++++----- pandora_agents/win32/bin/pandora_agent.conf | 32 ++++++++++----------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/pandora_agents/pc/Win32/pandora_agent.conf b/pandora_agents/pc/Win32/pandora_agent.conf index eb891d5866..b064eba730 100644 --- a/pandora_agents/pc/Win32/pandora_agent.conf +++ b/pandora_agents/pc/Win32/pandora_agent.conf @@ -147,22 +147,23 @@ module_max_critical 20 module_end # Log events + +# Get logs from System source. module_begin module_name System Events (TermService) -module_type async_string -module_logevent module_description Log Events coming from Terminal Service +module_type log +module_logevent module_source System -module_application TermService module_end +# Get logs from Security source. module_begin -module_name Security Events (Invalid Login) -module_type async_string -module_description Security log events for invalid login attempt +module_name Security Events +module_description Security log events +module_type log module_logevent module_source Security -module_eventcode 529 module_end # Check if Dhcp service is enabled diff --git a/pandora_agents/win32/bin/pandora_agent.conf b/pandora_agents/win32/bin/pandora_agent.conf index bae2841fd5..c0a1560b38 100644 --- a/pandora_agents/win32/bin/pandora_agent.conf +++ b/pandora_agents/win32/bin/pandora_agent.conf @@ -179,6 +179,22 @@ module_description Total number of TCP connections active module_group Networking module_end +# Get logs from System source. +module_begin +module_name Eventlog_System +module_type log +module_logevent +module_source System +module_end + +# Get logs from Security source. +module_begin +module_name Eventlog_Security +module_type log +module_logevent +module_source Security +module_end + # Example plugin to retrieve drive usage module_plugin cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\df_percent_used.vbs" @@ -273,22 +289,6 @@ module_plugin "%PROGRAMFILES%\Pandora_Agent\util\autodiscover.exe" --default #module_type generic_data_string #module_end -# Get logs from System source. Need enterprise version. -#module_begin -#module_name Eventlog_System -#module_type log -#module_logevent -#module_source System -#module_end - -# Get logs from Security source. Need enterprise version. -#module_begin -#module_name Eventlog_Security -#module_type log -#module_logevent -#module_source Security -#module_end - # Get logs from Application source. Need enterprise version. #module_begin #module_name Eventlog_Application From 817811ffac2ce997e93fdfc16f225bec7c7b2d1c Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 30 Nov 2023 10:13:18 +0100 Subject: [PATCH 107/157] fix error update manager pandora_enterprise#12447 --- pandora_console/include/functions_menu.php | 3 ++- .../update_manager_client/lib/UpdateManager/Client.php | 7 ------- .../resources/javascript/umc_offline.js | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 1df84f6025..3b4c092680 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -983,7 +983,8 @@ if (is_ajax()) {

'.$product_name.'

'.__('Version').' '.$pandora_version.$lts_name.' - '.(enterprise_installed() ? 'Enterprise' : 'Community').'

-

'.__('MR version').' MR'.$config['MR'].'

+

'.__('Current package').' '.$config['current_package'].'

+

'.__('MR version').' MR'.$config['MR'].'

Build'.$build_version.'

'; if (enterprise_installed() === true) { $dialog .= '

'.__('Support expires').''.$license_expiry_date.'

'; diff --git a/pandora_console/update_manager_client/lib/UpdateManager/Client.php b/pandora_console/update_manager_client/lib/UpdateManager/Client.php index a0ca625009..8abe5f2f83 100644 --- a/pandora_console/update_manager_client/lib/UpdateManager/Client.php +++ b/pandora_console/update_manager_client/lib/UpdateManager/Client.php @@ -1829,13 +1829,6 @@ class Client } } else { // Manually uploaded package. - if (is_numeric($package['version']) !== true) { - $this->lastError = 'Version does not match required format (numeric)'; - $this->notify(10, $this->lastError, false); - $this->unlock(); - return false; - } - $classic_open_packages = false; $nextUpdate = [ 'version' => $package['version'] ]; $file_path = $package['file_path']; diff --git a/pandora_console/update_manager_client/resources/javascript/umc_offline.js b/pandora_console/update_manager_client/resources/javascript/umc_offline.js index a32dfc1e5c..ad2432a306 100644 --- a/pandora_console/update_manager_client/resources/javascript/umc_offline.js +++ b/pandora_console/update_manager_client/resources/javascript/umc_offline.js @@ -487,7 +487,6 @@ function updateOfflineProgress(url, auth) { * Cancel update. */ function cancelUpdate(reason = "") { - console.error(reason); var taskStatusLogContainer = $("#result li"); taskStatusLogContainer.addClass("error"); taskStatusLogContainer.find("p").text(texts.rejectedUpdate + " " + reason); From 1e4c5563d3dfa37369c65a363e780ac2eda92d7a Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Thu, 30 Nov 2023 14:44:27 +0100 Subject: [PATCH 108/157] #12416 fixed encryption_passphrase in metaconsole --- pandora_console/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/index.php b/pandora_console/index.php index 4ca8f80a82..27f84d53fb 100755 --- a/pandora_console/index.php +++ b/pandora_console/index.php @@ -1234,7 +1234,7 @@ if (has_metaconsole() === true [ 'dbhost' => $config['replication_dbhost'], 'dbuser' => $config['replication_dbuser'], - 'dbpass' => io_output_password($config['replication_dbpass']), + 'dbpass' => $config['replication_dbpass'], 'dbname' => $config['replication_dbname'], ] ); From 741c8d40b30a7e952c2c640be383f4c3b99b6b86 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Thu, 30 Nov 2023 15:24:34 +0100 Subject: [PATCH 109/157] #12530 Validation is added to the SLA report, the data of the SLA report item is not painted if the agent is not informed --- pandora_console/include/functions_reporting_html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 6699d2c74d..0f9ae0f68c 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -1275,7 +1275,7 @@ function reporting_html_SLA($table, $item, $mini, $pdf=0) $table3->headstyle[5] = 'text-align: right'; foreach ($item['data'] as $sla) { - if (isset($sla) === true) { + if (isset($sla) === true && empty($sla['agent']) === false) { // First_table. $row = []; $row[] = $sla['agent']; From 3c99a2e49a4fbfd09e5a27fd0d7f03a00d1f5f2b Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Fri, 1 Dec 2023 13:29:51 +0100 Subject: [PATCH 110/157] #11494 Fix Av. bug --- pandora_console/include/functions_modules.php | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 12fc5ec828..e85029064e 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4869,7 +4869,7 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtrs_array[] = ($current_time - $failed_event[0]); } else if (empty($failed_event) === true) { $mtrs_array[] = 0; - } else { + } else if (count($normal_event) >= count($failed_event)) { foreach ($normal_event as $key => $value) { if (isset($failed_event[$key]) === false) { $failed_event[$key] = end($failed_event); @@ -4881,6 +4881,16 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtrs_array[] = ($failed_event[$key] - $normal_event[$key]); } } + } else { + foreach ($normal_event as $key => $value) { + if (($failed_event[$key] - $normal_event[$key]) < 0) { + $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); + } else { + $mtrs_array[] = ($failed_event[$key] - $normal_event[$key]); + } + } + + $mtrs_array[] = ($current_time - end($failed_event)); } $mtbf_array = []; @@ -4891,16 +4901,16 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtbf_array[] = ($failed_event[($i - 1)] - $failed_event[$i]); } } else { - $mtbf_array[] = ($current_time - $failed_event[0]); + $mtbf_array[] = 0; } } else { $mtbf_array[] = 0; } - $total_time_failed = array_sum($mtbf_array); + $total_time_failed = array_sum($mtrs_array); $total_time_ok = ($interval_time - $total_time_failed); if (count($events_time) === 1) { - if ((string) $first_utimestamp !== '0') { + if ((int) $first_utimestamp !== 0) { $availability = round((($total_time_ok / $interval_time) * 100), 2); } } else { @@ -4908,14 +4918,14 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule } if ($critical_events > 1) { - $mtbf = round(( $total_time_failed / $critical_events)); + $mtbf = round(array_sum($mtbf_array) / count($mtbf_array)); } else { $mtbf = false; } - if (count($mtrs_array) === 1 && (string) $first_utimestamp !== '0' && $type === 0) { + if (count($mtrs_array) === 1 && (int) $first_utimestamp !== 0) { $mtrs = round($total_time_failed / count($mtrs_array)); - } else if (count($mtrs_array) > 1 && (string) $first_utimestamp !== '0') { + } else if (count($mtrs_array) > 1 && (int) $first_utimestamp !== 0) { $mtrs = round((array_sum($mtrs_array) / count($mtrs_array))); } else { $mtrs = false; From 5609bc2313523fde08ced806a18b1746cbc637a1 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Fri, 1 Dec 2023 13:45:17 +0100 Subject: [PATCH 111/157] #12581 fixed strong size in visual console --- pandora_console/include/visual-console-client/vc.main.css | 3 +++ pandora_console/include/visual-console-client/vc.main.css.map | 2 +- visual_console_client/src/main.css | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/visual-console-client/vc.main.css b/pandora_console/include/visual-console-client/vc.main.css index 98d39f6cad..f146c0fc94 100644 --- a/pandora_console/include/visual-console-client/vc.main.css +++ b/pandora_console/include/visual-console-client/vc.main.css @@ -743,6 +743,9 @@ p { margin-block-end: 1em; } +strong { + font-size: inherit; +} /* Styles for the solid icons */ .fa { diff --git a/pandora_console/include/visual-console-client/vc.main.css.map b/pandora_console/include/visual-console-client/vc.main.css.map index b801994300..fcf332155e 100644 --- a/pandora_console/include/visual-console-client/vc.main.css.map +++ b/pandora_console/include/visual-console-client/vc.main.css.map @@ -1 +1 @@ -{"version":3,"file":"vc.main.css","mappings":"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","sources":["webpack://pandora-fms-visual-console/./src/main.css","webpack://pandora-fms-visual-console/./src/lib/FontAwesomeIcon.styles.css","webpack://pandora-fms-visual-console/./src/lib/autocomplete.css","webpack://pandora-fms-visual-console/./src/items/Clock/styles.css"],"sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n background-position: center;\n margin-top: 5px;\n}\n\n.is-maintenance {\n background-image: url(./lib/maintenanceMode.png) !important;\n}\n\n.is-maintenance :nth-child(1) {\n display: none;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n user-select: text;\n z-index: 1;\n}\n\n.visual-console-item.is-on-top {\n z-index: 2;\n}\n\n.visual-console-item * {\n overflow: visible;\n font-family: inherit;\n line-height: inherit;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n\n.visual-console-item.is-editing {\n border: 2px dashed #b2b2b2;\n transform: translateX(-2px) translateY(-2px);\n user-select: none;\n}\n\n.visual-console-item.is-editing:hover {\n border-color: #2b2b2b;\n}\n\n.visual-console-item.is-editing.is-selected {\n border: 2px dashed #82b92e;\n cursor: move;\n z-index: 10;\n}\n.visual-console-item.is-editing > .resize-draggable {\n float: right;\n position: absolute;\n right: 0;\n bottom: 0;\n width: 15px;\n height: 15px;\n background: url(./resize-handle.svg);\n cursor: se-resize;\n z-index: 10;\n}\n\n.visual-console-item.is-editing :first-child {\n pointer-events: none;\n}\n\n@keyframes spinner-loading {\n 0% {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(1turn);\n }\n}\n\n.visual-console-item.is-alert-triggered {\n border: 3px solid #f36201;\n}\n\n.visual-console-spinner {\n background-color: transparent;\n margin: 0px auto;\n border-top: 5px solid rgb(82, 85, 87);\n border-right: 5px solid rgb(82, 85, 87);\n border-bottom: 5px solid rgb(82, 85, 87);\n border-left: 5px solid rgba(82, 85, 87, 0.2);\n\n animation-name: spinner-loading;\n animation-duration: 0.8s;\n animation-iteration-count: infinite;\n animation-timing-function: linear;\n}\n\n.visual-console-spinner,\n.visual-console-spinner :after {\n display: block;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n}\n\n.visual-console-spinner.small,\n.visual-console-spinner.small :after {\n width: 12px;\n height: 12px;\n}\n\n.div-visual-console-spinner {\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n opacity: 0.7;\n background: rgb(212, 215, 218);\n z-index: 10;\n}\n\n.show-elements {\n display: inline-block;\n}\n\n.hide-elements {\n display: none;\n}\n\n/*Forms*/\n.div-input-group label {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n font-size: 12pt;\n font-weight: 600;\n color: #343434;\n margin-right: 10px;\n}\n.div-input-group label img {\n margin-left: 4px;\n}\n\n.div-input-group input[type=\"text\"],\n.div-input-group input[type=\"number\"] {\n height: 25px;\n font-size: 10pt;\n background-color: transparent;\n border: none;\n border-radius: 0;\n border-bottom: 1px solid #ccc;\n font-weight: lighter;\n padding: 0px 0px 2px 0px;\n box-sizing: border-box;\n margin-right: 10px;\n padding-left: 2px;\n}\n\n.div-input-group input[type=\"radio\"] {\n margin-right: 10px;\n width: 17px;\n height: 17px;\n}\n\n.div-input-group select {\n font-weight: lighter;\n font-size: 10pt;\n}\n\n.input-groups {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n}\n\n.input-group {\n width: 100%;\n margin-bottom: 25px;\n padding-left: 20px;\n}\n\n.div-ranges-input-group {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: flex-start;\n}\n\n.div-ranges-input-group > div {\n padding-left: 20px;\n margin-top: 10px;\n}\n\n.div-input-group,\n.div-input-group div div {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.div-input-group h3 {\n text-transform: initial;\n text-align: center;\n font-style: italic;\n text-decoration: underline;\n margin: 0 auto;\n}\n\n.div-input-group div div a {\n margin-left: 10px;\n}\n\n.div-input-group-autocomplete-agent {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n height: 70px;\n}\n\n.div-input-group-inside {\n padding-left: 20px;\n}\n\n.input-group-link-console {\n height: 70px;\n}\n\n.show-elements > div.div-input-group-autocomplete-agent {\n margin-left: 20px;\n}\n\n.img-vc-elements {\n margin-left: 10px;\n}\n\ninput.error-input-validate[type=\"number\"],\ninput.error-input-validate[type=\"text\"],\nselect.error-input-validate {\n border: 1px solid #c00;\n}\n\nselect.error-input-validate:focus {\n outline-color: #c00;\n}\n\np.error-p-validate {\n width: 100%;\n color: #c00;\n}\n\n#modalVCItemForm #textarea_label_ifr {\n background-color: #c9cfcd;\n}\n\n/* Styles for the solid icons */\n\n.fa {\n display: inline-block;\n margin: 0;\n}\n\n.fa,\n.fa > svg,\n.fa.medium,\n.fa.medium > svg {\n width: 28px;\n height: 28px;\n}\n\n.fa.fa-small,\n.fa.fa-small > svg {\n width: 14px;\n height: 14px;\n}\n\n.fa.fa-large,\n.fa.fa-large > svg {\n width: 44px;\n height: 44px;\n}\n\n.fa-spin {\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.autocomplete {\n /*the container must be positioned relative:*/\n position: relative;\n display: inline-block;\n}\n.autocomplete input {\n /*background: pink;*/\n}\n.autocomplete-items {\n border: 1px solid #d4d4d4;\n border-bottom: none;\n border-top: none;\n /*position the autocomplete items to be the same width as the container:*/\n position: absolute;\n z-index: 1;\n overflow: auto;\n max-height: 150px;\n max-width: 250px;\n}\n.autocomplete-items div {\n width: 100%;\n padding: 10px;\n cursor: pointer;\n background-color: #fff;\n border-bottom: 1px solid #d4d4d4;\n border-top: 1px solid #d4d4d4;\n}\n.autocomplete-items div:hover {\n width: 100%;\n background-color: #e9e9e9;\n}\n.autocomplete-active {\n /*when navigating through the items using the arrow keys:*/\n background-color: DodgerBlue !important;\n color: #ffffff;\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n /* To improve legibility */\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.time {\n font-size: 50px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock {\n text-align: center;\n}\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n\n#html-tabs .ui-widget-header {\n background-color: #ffffff;\n border: 0px;\n}\n\n#html-tabs .ui-tabs-anchor {\n float: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n}\n\n#html-tabs .ui-tabs-anchor img {\n margin-right: 10px;\n}\n\n#html-tabs .ui-tabs-nav li {\n border-radius: 5px 5px 0px 0px;\n}\n\nli.interval-color-ranges > label,\nli#li-default-ranges > label {\n margin-right: 15px;\n}\n\nli.interval-color-ranges > input[type=\"number\"],\nli#li-default-ranges > input[type=\"number\"] {\n width: 80px;\n}\n\nli.interval-color-ranges > label:not(:first-child),\nli#li-default-ranges > label:not(:first-child),\nli#li-size-item > label:not(:first-child),\nli#li-position-item > label:not(:first-child) {\n width: initial;\n margin-left: 15px;\n}\n\nli#li-image-item label {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n}\n\nli#li-image-item label img {\n flex: initial;\n}\n\n.discovery.modal * {\n font-weight: normal;\n color: #343434;\n}\n\n.discovery.modal select {\n width: 100px;\n}\n\n.discovery.modal div#period_manual select,\n.discovery.modal div#period_manual input,\n.discovery.modal div#period_default select,\n.discovery.modal div#cacheExpiration_manual select,\n.discovery.modal div#cacheExpiration_manual input,\n.discovery.modal div#cacheExpiration_default select {\n font-size: inherit !important;\n}\n.discovery.modal div#period_default select#period_select,\n.discovery.modal div#cacheExpiration_default select#cacheExpiration_select {\n max-width: 230px;\n width: inherit;\n}\n\nli#li-timeZone-item > label:not(:first-child),\n.discovery.modal li#div-textarea-label > label {\n flex: inherit;\n}\n\nli#li-timeZone-item > select:not(:first-child) {\n margin-left: 10px;\n}\n\n.discovery.modal li#div-textarea-label table tbody td.mceIframeContainer {\n background-color: #ededed;\n}\n\n/*style item group show statistic*/\n.group-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n.group-container .group-item-title {\n width: 100%;\n height: 30%;\n background-color: #9d9ea0;\n color: black;\n font-weight: bold;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n.group-container .group-item-info {\n width: 100%;\n height: 70%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n padding: 2%;\n align-items: center;\n}\n\n.group-container .group-item-info .group-item-info-container {\n flex: 1 1 20%;\n display: flex;\n flex-direction: row;\n border-radius: 2px;\n max-height: 50px;\n min-height: 35px;\n margin: 1%;\n}\n\n.group-container .group-item-info .group-item-info-container .value-style {\n flex: 1;\n color: #fff;\n font-size: 100%;\n padding: 0%;\n width: 100%;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\n.group-container .group-item-info .group-item-info-container .name-style {\n flex: 1;\n background-color: white;\n color: black;\n font-size: 100%;\n padding: 0%;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\ndiv.label,\ndiv.simple-value {\n min-width: fit-content;\n min-height: fit-content;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\ndiv.simple-value > div {\n max-height: -webkit-fill-available;\n}\n\ndiv.module-graph .parent_graph p table tr {\n height: 25px;\n}\n\ndiv.module-graph {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n}\n\ndiv.basic-chart {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-end;\n justify-content: center;\n}\n\n.basic-chart-header {\n height: 40%;\n width: 100%;\n display: flex;\n}\n\n.basic-chart-header-name {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 80%;\n display: flex;\n align-items: center;\n font-size: 2.5vmin;\n margin-left: 3%;\n}\n\n.basic-chart-header-value {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 20%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 2.5vmin;\n}\n\ndiv.module-graph .gauge_d3_class {\n flex: 1 1 100px;\n float: none !important;\n overflow: inherit !important;\n text-align: center;\n}\n\n.textDecorationNone:hover {\n text-decoration: none;\n}\n\n.vc-item-nl-label {\n border-radius: 5px;\n background-color: #fff;\n padding: 5px;\n padding-left: 1em;\n font-size: 14px;\n}\n\n.odometer {\n overflow: hidden !important;\n}\n\n.odometer-container {\n width: 100%;\n height: 100%;\n overflow: hidden;\n text-align: center;\n display: flex;\n align-items: flex-end;\n}\n\n.odometer-a {\n z-index: 5;\n position: absolute;\n width: 65%;\n height: 65%;\n left: calc(17.5%);\n border-radius: 1000px 1000px 0px 0px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-direction: column;\n line-height: 0px;\n}\n\n.odometer-b {\n z-index: 4;\n position: relative;\n width: 95%;\n height: 95%;\n border-radius: 0px 0px 1000px 1000px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n top: calc(95%);\n left: calc(2.5%);\n}\n\n.odometer-c {\n z-index: 3;\n position: absolute;\n width: 96%;\n height: 96%;\n left: calc(2%);\n background-color: #202226;\n margin-left: auto;\n margin-right: auto;\n border-radius: 1000px 1000px 0px 0px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n}\n\n.odometer-d {\n z-index: 0;\n position: absolute;\n width: 100%;\n height: 100%;\n background-color: #82b92e;\n margin-left: auto;\n margin-right: auto;\n border-radius: 1000px 1000px 0px 0px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n}\n\n.gauge-data {\n z-index: 4;\n color: #fff;\n font-size: 1.5em;\n width: 100%;\n height: 100%;\n transition: all 1s ease-out;\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: flex-end;\n}\n\n.svg_warning {\n fill: #f3b200;\n}\n\n.svg_warning_hide {\n fill: #fff !important;\n}\n\n.gauge-data #percent {\n color: #000;\n}\n\n.orange_background {\n background: #ffa631;\n}\n.red_background {\n background: #e63c52;\n}\n.yellow_background {\n background: #f3b200;\n}\n.grey_background {\n background: #b2b2b2;\n}\n.blue_background {\n background: #4a83f3;\n}\n.green_background {\n background: #82b92e;\n}\n\n#box-rectangle-selection {\n position: absolute;\n width: 0px;\n height: 0px;\n border: 2px solid #002f33;\n}\n\np {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n","/* Styles for the solid icons */\n\n.fa {\n display: inline-block;\n margin: 0;\n}\n\n.fa,\n.fa > svg,\n.fa.medium,\n.fa.medium > svg {\n width: 28px;\n height: 28px;\n}\n\n.fa.fa-small,\n.fa.fa-small > svg {\n width: 14px;\n height: 14px;\n}\n\n.fa.fa-large,\n.fa.fa-large > svg {\n width: 44px;\n height: 44px;\n}\n\n.fa-spin {\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n",".autocomplete {\n /*the container must be positioned relative:*/\n position: relative;\n display: inline-block;\n}\n.autocomplete input {\n /*background: pink;*/\n}\n.autocomplete-items {\n border: 1px solid #d4d4d4;\n border-bottom: none;\n border-top: none;\n /*position the autocomplete items to be the same width as the container:*/\n position: absolute;\n z-index: 1;\n overflow: auto;\n max-height: 150px;\n max-width: 250px;\n}\n.autocomplete-items div {\n width: 100%;\n padding: 10px;\n cursor: pointer;\n background-color: #fff;\n border-bottom: 1px solid #d4d4d4;\n border-top: 1px solid #d4d4d4;\n}\n.autocomplete-items div:hover {\n width: 100%;\n background-color: #e9e9e9;\n}\n.autocomplete-active {\n /*when navigating through the items using the arrow keys:*/\n background-color: DodgerBlue !important;\n color: #ffffff;\n}\n","/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: space-evenly;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.time {\n font-size: 50px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock {\n text-align: center;\n}\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"vc.main.css","mappings":"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","sources":["webpack://pandora-fms-visual-console/./src/main.css","webpack://pandora-fms-visual-console/./src/lib/FontAwesomeIcon.styles.css","webpack://pandora-fms-visual-console/./src/lib/autocomplete.css","webpack://pandora-fms-visual-console/./src/items/Clock/styles.css"],"sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n background-position: center;\n margin-top: 5px;\n}\n\n.is-maintenance {\n background-image: url(./lib/maintenanceMode.png) !important;\n}\n\n.is-maintenance :nth-child(1) {\n display: none;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n user-select: text;\n z-index: 1;\n}\n\n.visual-console-item.is-on-top {\n z-index: 2;\n}\n\n.visual-console-item * {\n overflow: visible;\n font-family: inherit;\n line-height: inherit;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n\n.visual-console-item.is-editing {\n border: 2px dashed #b2b2b2;\n transform: translateX(-2px) translateY(-2px);\n user-select: none;\n}\n\n.visual-console-item.is-editing:hover {\n border-color: #2b2b2b;\n}\n\n.visual-console-item.is-editing.is-selected {\n border: 2px dashed #82b92e;\n cursor: move;\n z-index: 10;\n}\n.visual-console-item.is-editing > .resize-draggable {\n float: right;\n position: absolute;\n right: 0;\n bottom: 0;\n width: 15px;\n height: 15px;\n background: url(./resize-handle.svg);\n cursor: se-resize;\n z-index: 10;\n}\n\n.visual-console-item.is-editing :first-child {\n pointer-events: none;\n}\n\n@keyframes spinner-loading {\n 0% {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(1turn);\n }\n}\n\n.visual-console-item.is-alert-triggered {\n border: 3px solid #f36201;\n}\n\n.visual-console-spinner {\n background-color: transparent;\n margin: 0px auto;\n border-top: 5px solid rgb(82, 85, 87);\n border-right: 5px solid rgb(82, 85, 87);\n border-bottom: 5px solid rgb(82, 85, 87);\n border-left: 5px solid rgba(82, 85, 87, 0.2);\n\n animation-name: spinner-loading;\n animation-duration: 0.8s;\n animation-iteration-count: infinite;\n animation-timing-function: linear;\n}\n\n.visual-console-spinner,\n.visual-console-spinner :after {\n display: block;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n}\n\n.visual-console-spinner.small,\n.visual-console-spinner.small :after {\n width: 12px;\n height: 12px;\n}\n\n.div-visual-console-spinner {\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n opacity: 0.7;\n background: rgb(212, 215, 218);\n z-index: 10;\n}\n\n.show-elements {\n display: inline-block;\n}\n\n.hide-elements {\n display: none;\n}\n\n/*Forms*/\n.div-input-group label {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n font-size: 12pt;\n font-weight: 600;\n color: #343434;\n margin-right: 10px;\n}\n.div-input-group label img {\n margin-left: 4px;\n}\n\n.div-input-group input[type=\"text\"],\n.div-input-group input[type=\"number\"] {\n height: 25px;\n font-size: 10pt;\n background-color: transparent;\n border: none;\n border-radius: 0;\n border-bottom: 1px solid #ccc;\n font-weight: lighter;\n padding: 0px 0px 2px 0px;\n box-sizing: border-box;\n margin-right: 10px;\n padding-left: 2px;\n}\n\n.div-input-group input[type=\"radio\"] {\n margin-right: 10px;\n width: 17px;\n height: 17px;\n}\n\n.div-input-group select {\n font-weight: lighter;\n font-size: 10pt;\n}\n\n.input-groups {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n}\n\n.input-group {\n width: 100%;\n margin-bottom: 25px;\n padding-left: 20px;\n}\n\n.div-ranges-input-group {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: flex-start;\n}\n\n.div-ranges-input-group > div {\n padding-left: 20px;\n margin-top: 10px;\n}\n\n.div-input-group,\n.div-input-group div div {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.div-input-group h3 {\n text-transform: initial;\n text-align: center;\n font-style: italic;\n text-decoration: underline;\n margin: 0 auto;\n}\n\n.div-input-group div div a {\n margin-left: 10px;\n}\n\n.div-input-group-autocomplete-agent {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n height: 70px;\n}\n\n.div-input-group-inside {\n padding-left: 20px;\n}\n\n.input-group-link-console {\n height: 70px;\n}\n\n.show-elements > div.div-input-group-autocomplete-agent {\n margin-left: 20px;\n}\n\n.img-vc-elements {\n margin-left: 10px;\n}\n\ninput.error-input-validate[type=\"number\"],\ninput.error-input-validate[type=\"text\"],\nselect.error-input-validate {\n border: 1px solid #c00;\n}\n\nselect.error-input-validate:focus {\n outline-color: #c00;\n}\n\np.error-p-validate {\n width: 100%;\n color: #c00;\n}\n\n#modalVCItemForm #textarea_label_ifr {\n background-color: #c9cfcd;\n}\n\n/* Styles for the solid icons */\n\n.fa {\n display: inline-block;\n margin: 0;\n}\n\n.fa,\n.fa > svg,\n.fa.medium,\n.fa.medium > svg {\n width: 28px;\n height: 28px;\n}\n\n.fa.fa-small,\n.fa.fa-small > svg {\n width: 14px;\n height: 14px;\n}\n\n.fa.fa-large,\n.fa.fa-large > svg {\n width: 44px;\n height: 44px;\n}\n\n.fa-spin {\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.autocomplete {\n /*the container must be positioned relative:*/\n position: relative;\n display: inline-block;\n}\n.autocomplete input {\n /*background: pink;*/\n}\n.autocomplete-items {\n border: 1px solid #d4d4d4;\n border-bottom: none;\n border-top: none;\n /*position the autocomplete items to be the same width as the container:*/\n position: absolute;\n z-index: 1;\n overflow: auto;\n max-height: 150px;\n max-width: 250px;\n}\n.autocomplete-items div {\n width: 100%;\n padding: 10px;\n cursor: pointer;\n background-color: #fff;\n border-bottom: 1px solid #d4d4d4;\n border-top: 1px solid #d4d4d4;\n}\n.autocomplete-items div:hover {\n width: 100%;\n background-color: #e9e9e9;\n}\n.autocomplete-active {\n /*when navigating through the items using the arrow keys:*/\n background-color: DodgerBlue !important;\n color: #ffffff;\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n /* To improve legibility */\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.time {\n font-size: 50px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock {\n text-align: center;\n}\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n\n#html-tabs .ui-widget-header {\n background-color: #ffffff;\n border: 0px;\n}\n\n#html-tabs .ui-tabs-anchor {\n float: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n}\n\n#html-tabs .ui-tabs-anchor img {\n margin-right: 10px;\n}\n\n#html-tabs .ui-tabs-nav li {\n border-radius: 5px 5px 0px 0px;\n}\n\nli.interval-color-ranges > label,\nli#li-default-ranges > label {\n margin-right: 15px;\n}\n\nli.interval-color-ranges > input[type=\"number\"],\nli#li-default-ranges > input[type=\"number\"] {\n width: 80px;\n}\n\nli.interval-color-ranges > label:not(:first-child),\nli#li-default-ranges > label:not(:first-child),\nli#li-size-item > label:not(:first-child),\nli#li-position-item > label:not(:first-child) {\n width: initial;\n margin-left: 15px;\n}\n\nli#li-image-item label {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n}\n\nli#li-image-item label img {\n flex: initial;\n}\n\n.discovery.modal * {\n font-weight: normal;\n color: #343434;\n}\n\n.discovery.modal select {\n width: 100px;\n}\n\n.discovery.modal div#period_manual select,\n.discovery.modal div#period_manual input,\n.discovery.modal div#period_default select,\n.discovery.modal div#cacheExpiration_manual select,\n.discovery.modal div#cacheExpiration_manual input,\n.discovery.modal div#cacheExpiration_default select {\n font-size: inherit !important;\n}\n.discovery.modal div#period_default select#period_select,\n.discovery.modal div#cacheExpiration_default select#cacheExpiration_select {\n max-width: 230px;\n width: inherit;\n}\n\nli#li-timeZone-item > label:not(:first-child),\n.discovery.modal li#div-textarea-label > label {\n flex: inherit;\n}\n\nli#li-timeZone-item > select:not(:first-child) {\n margin-left: 10px;\n}\n\n.discovery.modal li#div-textarea-label table tbody td.mceIframeContainer {\n background-color: #ededed;\n}\n\n/*style item group show statistic*/\n.group-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n.group-container .group-item-title {\n width: 100%;\n height: 30%;\n background-color: #9d9ea0;\n color: black;\n font-weight: bold;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n.group-container .group-item-info {\n width: 100%;\n height: 70%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n padding: 2%;\n align-items: center;\n}\n\n.group-container .group-item-info .group-item-info-container {\n flex: 1 1 20%;\n display: flex;\n flex-direction: row;\n border-radius: 2px;\n max-height: 50px;\n min-height: 35px;\n margin: 1%;\n}\n\n.group-container .group-item-info .group-item-info-container .value-style {\n flex: 1;\n color: #fff;\n font-size: 100%;\n padding: 0%;\n width: 100%;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\n.group-container .group-item-info .group-item-info-container .name-style {\n flex: 1;\n background-color: white;\n color: black;\n font-size: 100%;\n padding: 0%;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\ndiv.label,\ndiv.simple-value {\n min-width: fit-content;\n min-height: fit-content;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\ndiv.simple-value > div {\n max-height: -webkit-fill-available;\n}\n\ndiv.module-graph .parent_graph p table tr {\n height: 25px;\n}\n\ndiv.module-graph {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n}\n\ndiv.basic-chart {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-end;\n justify-content: center;\n}\n\n.basic-chart-header {\n height: 40%;\n width: 100%;\n display: flex;\n}\n\n.basic-chart-header-name {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 80%;\n display: flex;\n align-items: center;\n font-size: 2.5vmin;\n margin-left: 3%;\n}\n\n.basic-chart-header-value {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 20%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 2.5vmin;\n}\n\ndiv.module-graph .gauge_d3_class {\n flex: 1 1 100px;\n float: none !important;\n overflow: inherit !important;\n text-align: center;\n}\n\n.textDecorationNone:hover {\n text-decoration: none;\n}\n\n.vc-item-nl-label {\n border-radius: 5px;\n background-color: #fff;\n padding: 5px;\n padding-left: 1em;\n font-size: 14px;\n}\n\n.odometer {\n overflow: hidden !important;\n}\n\n.odometer-container {\n width: 100%;\n height: 100%;\n overflow: hidden;\n text-align: center;\n display: flex;\n align-items: flex-end;\n}\n\n.odometer-a {\n z-index: 5;\n position: absolute;\n width: 65%;\n height: 65%;\n left: calc(17.5%);\n border-radius: 1000px 1000px 0px 0px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-direction: column;\n line-height: 0px;\n}\n\n.odometer-b {\n z-index: 4;\n position: relative;\n width: 95%;\n height: 95%;\n border-radius: 0px 0px 1000px 1000px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n top: calc(95%);\n left: calc(2.5%);\n}\n\n.odometer-c {\n z-index: 3;\n position: absolute;\n width: 96%;\n height: 96%;\n left: calc(2%);\n background-color: #202226;\n margin-left: auto;\n margin-right: auto;\n border-radius: 1000px 1000px 0px 0px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n}\n\n.odometer-d {\n z-index: 0;\n position: absolute;\n width: 100%;\n height: 100%;\n background-color: #82b92e;\n margin-left: auto;\n margin-right: auto;\n border-radius: 1000px 1000px 0px 0px;\n transform-origin: center top;\n transition: all 1.3s ease-in-out;\n}\n\n.gauge-data {\n z-index: 4;\n color: #fff;\n font-size: 1.5em;\n width: 100%;\n height: 100%;\n transition: all 1s ease-out;\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: flex-end;\n}\n\n.svg_warning {\n fill: #f3b200;\n}\n\n.svg_warning_hide {\n fill: #fff !important;\n}\n\n.gauge-data #percent {\n color: #000;\n}\n\n.orange_background {\n background: #ffa631;\n}\n.red_background {\n background: #e63c52;\n}\n.yellow_background {\n background: #f3b200;\n}\n.grey_background {\n background: #b2b2b2;\n}\n.blue_background {\n background: #4a83f3;\n}\n.green_background {\n background: #82b92e;\n}\n\n#box-rectangle-selection {\n position: absolute;\n width: 0px;\n height: 0px;\n border: 2px solid #002f33;\n}\n\np {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n\nstrong {\n font-size: inherit;\n}","/* Styles for the solid icons */\n\n.fa {\n display: inline-block;\n margin: 0;\n}\n\n.fa,\n.fa > svg,\n.fa.medium,\n.fa.medium > svg {\n width: 28px;\n height: 28px;\n}\n\n.fa.fa-small,\n.fa.fa-small > svg {\n width: 14px;\n height: 14px;\n}\n\n.fa.fa-large,\n.fa.fa-large > svg {\n width: 44px;\n height: 44px;\n}\n\n.fa-spin {\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n",".autocomplete {\n /*the container must be positioned relative:*/\n position: relative;\n display: inline-block;\n}\n.autocomplete input {\n /*background: pink;*/\n}\n.autocomplete-items {\n border: 1px solid #d4d4d4;\n border-bottom: none;\n border-top: none;\n /*position the autocomplete items to be the same width as the container:*/\n position: absolute;\n z-index: 1;\n overflow: auto;\n max-height: 150px;\n max-width: 250px;\n}\n.autocomplete-items div {\n width: 100%;\n padding: 10px;\n cursor: pointer;\n background-color: #fff;\n border-bottom: 1px solid #d4d4d4;\n border-top: 1px solid #d4d4d4;\n}\n.autocomplete-items div:hover {\n width: 100%;\n background-color: #e9e9e9;\n}\n.autocomplete-active {\n /*when navigating through the items using the arrow keys:*/\n background-color: DodgerBlue !important;\n color: #ffffff;\n}\n","/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: space-evenly;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.time {\n font-size: 50px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock {\n text-align: center;\n}\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/visual_console_client/src/main.css b/visual_console_client/src/main.css index cd8b00e93f..c77bf658c8 100644 --- a/visual_console_client/src/main.css +++ b/visual_console_client/src/main.css @@ -742,3 +742,7 @@ p { margin-block-start: 1em; margin-block-end: 1em; } + +strong { + font-size: inherit; +} From 7125fd9a8fb0e8fd6f4e2d53c251109ca21eece2 Mon Sep 17 00:00:00 2001 From: rafael Date: Mon, 4 Dec 2023 11:26:50 +0100 Subject: [PATCH 112/157] change package links --- .../pandora_deploy_community_ubuntu_2204.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extras/deploy-scripts/pandora_deploy_community_ubuntu_2204.sh b/extras/deploy-scripts/pandora_deploy_community_ubuntu_2204.sh index 5f240b0a41..c5c8edbb34 100644 --- a/extras/deploy-scripts/pandora_deploy_community_ubuntu_2204.sh +++ b/extras/deploy-scripts/pandora_deploy_community_ubuntu_2204.sh @@ -520,18 +520,18 @@ execute_cmd "systemctl restart mysql" "Configuring and restarting database engin #Define packages if [ "$PANDORA_LTS" -eq '1' ] ; then - [ "$PANDORA_SERVER_PACKAGE" ] || PANDORA_SERVER_PACKAGE="http://firefly.pandorafms.com/pandorafms/latest/Tarball/LTS/pandorafms_server-7.0NG.tar.gz" - [ "$PANDORA_CONSOLE_PACKAGE" ] || PANDORA_CONSOLE_PACKAGE="http://firefly.pandorafms.com/pandorafms/latest/Tarball/LTS/pandorafms_console-7.0NG.tar.gz" + [ "$PANDORA_SERVER_PACKAGE" ] || PANDORA_SERVER_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/LTS/pandorafms_server-7.0NG.tar.gz" + [ "$PANDORA_CONSOLE_PACKAGE" ] || PANDORA_CONSOLE_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/LTS/pandorafms_console-7.0NG.tar.gz" [ "$PANDORA_AGENT_PACKAGE" ] || PANDORA_AGENT_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_agent_linux-7.0NG.x86_64.tar.gz" elif [ "$PANDORA_LTS" -ne '1' ] ; then - [ "$PANDORA_SERVER_PACKAGE" ] || PANDORA_SERVER_PACKAGE="http://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_server-7.0NG.tar.gz" - [ "$PANDORA_CONSOLE_PACKAGE" ] || PANDORA_CONSOLE_PACKAGE="http://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_console-7.0NG.tar.gz" + [ "$PANDORA_SERVER_PACKAGE" ] || PANDORA_SERVER_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_server-7.0NG.tar.gz" + [ "$PANDORA_CONSOLE_PACKAGE" ] || PANDORA_CONSOLE_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_console-7.0NG.tar.gz" [ "$PANDORA_AGENT_PACKAGE" ] || PANDORA_AGENT_PACKAGE=" https://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_agent_linux-7.0NG.x86_64.tar.gz" fi if [ "$PANDORA_BETA" -eq '1' ] ; then - PANDORA_SERVER_PACKAGE="http://firefly.pandorafms.com/pandora_enterprise_nightlies/pandorafms_server-latest.tar.gz" - PANDORA_CONSOLE_PACKAGE="http://firefly.pandorafms.com/pandora_enterprise_nightlies/pandorafms_console-latest.tar.gz" + PANDORA_SERVER_PACKAGE="https://firefly.pandorafms.com/pandora_enterprise_nightlies/pandorafms_server-latest.tar.gz" + PANDORA_CONSOLE_PACKAGE="https://firefly.pandorafms.com/pandora_enterprise_nightlies/pandorafms_console-latest.tar.gz" PANDORA_AGENT_PACKAGE="https://firefly.pandorafms.com/pandorafms/latest/Tarball/pandorafms_agent_linux-7.0NG.x86_64.tar.gz" fi @@ -837,7 +837,7 @@ echo "@hourly root bash -c /etc/cron.hourly/pandora_db" >> /etc/cront ## Enabling agent adn configuring Agente sed -i "s/^remote_config.*$/remote_config 1/g" $PANDORA_AGENT_CONF &>> "$LOGFILE" -execute_cmd "/etc/init.d/pandora_agent_daemon start" "Starting PandoraFSM Agent" +execute_cmd "/etc/init.d/pandora_agent_daemon restart" "Starting PandoraFSM Agent" systemctl enable pandora_agent_daemon &>> "$LOGFILE" #fix path phantomjs From ea474ecd89d639e5f97cd0ea06e9de2cfca631d8 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 4 Dec 2023 15:05:01 +0100 Subject: [PATCH 113/157] #12566 changes in events table --- pandora_console/include/functions_ui.php | 23 ++++++--------------- pandora_console/operation/events/events.php | 14 +++---------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 5c9a7e90fc..3f9146e7d9 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -7170,32 +7170,21 @@ function ui_print_comments($comment, $truncate_limit=255) } // Only show the last comment. If commment its too long,the comment will short with ... - // If $config['prominent_time'] is timestamp the date show Month, day, hour and minutes. + // Forced time commentary to use copact date for optimize space in table. // Else show comments hours ago if ($comment['action'] != 'Added comment') { $comment['comment'] = $comment['action']; } + $comment['comment'] = io_safe_output($comment['comment']); + $short_comment = substr($comment['comment'], 0, 20); - if ($config['prominent_time'] == 'timestamp') { - $comentario = ''.date($config['date_format'], $comment['utimestamp']).' ('.$comment['id_user'].'): '.$comment['comment'].''; + $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$comment['comment'].''; - if (strlen($comentario) > '200px' && $truncate_limit >= 255) { - $comentario = ''.date($config['date_format'], $comment['utimestamp']).' ('.$comment['id_user'].'): '.$short_comment.'...'; - } - } else { - $rest_time = (time() - $comment['utimestamp']); - $time_last = (($rest_time / 60) / 60); - - $comentario = ''.number_format($time_last, 0, $config['decimal_separator'], ($config['thousand_separator'] ?? ',')).'  Hours  ('.$comment['id_user'].'): '.$comment['comment'].''; - - if (strlen($comentario) > '200px' && $truncate_limit >= 255) { - $comentario = ''.number_format($time_last, 0, $config['decimal_separator'], ($config['thousand_separator'] ?? ',')).'  Hours  ('.$comment['id_user'].'): '.$short_comment.'...'; - } + if (strlen($comentario) > '200px' && $truncate_limit >= 255) { + $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$short_comment.'...'; } - $comentario = io_safe_output($comentario); - if (strlen($comentario) >= $truncate_limit) { $comentario = ui_print_truncate_text( $comentario, diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index be5f6047e3..e019d12ab1 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -899,7 +899,7 @@ if (is_ajax() === true) { true, [ 'title' => __('Unknown'), - 'class' => 'forced-title', + 'class' => 'forced-title main_menu_icon', ] ); $state = 0; @@ -1199,10 +1199,10 @@ if (is_ajax() === true) { } $tmp->custom_data = $custom_data_str; - if (strlen($tmp->custom_data) >= 20) { + if (strlen($tmp->custom_data) >= 50) { $tmp->custom_data = ui_print_truncate_text( $tmp->custom_data, - 20, + 50, false, true, false, @@ -2595,14 +2595,6 @@ try { } - foreach ($fields as $key => $field) { - if (is_array($field) === false) { - $fields[$key] = [ - 'text' => $field, - 'class' => 'mw100px', - ]; - } - } // Always add options column. $fields = array_merge( From 1d36d8a436c7b686dc7658b1822f58b145104303 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 5 Dec 2023 09:14:02 +0100 Subject: [PATCH 114/157] fix error 500 and warnings pandora_enterprise#12605 --- .../extensions/agents_modules_csv.php | 10 ++--- pandora_console/general/header.php | 2 +- pandora_console/godmode/menu.php | 5 ++- .../include/ajax/alert_list.ajax.php | 16 +++---- pandora_console/include/ajax/module.php | 1 + pandora_console/include/functions_modules.php | 45 ++++++++++++++++--- .../agentes/estado_generalagente.php | 7 ++- 7 files changed, 63 insertions(+), 23 deletions(-) diff --git a/pandora_console/extensions/agents_modules_csv.php b/pandora_console/extensions/agents_modules_csv.php index e4a331338f..35893b4414 100644 --- a/pandora_console/extensions/agents_modules_csv.php +++ b/pandora_console/extensions/agents_modules_csv.php @@ -34,11 +34,11 @@ if ((bool) $config['metaconsole']) { include_once $config['homedir'].'/include/functions_modules.php'; include_once $config['homedir'].'/include/functions_users.php'; } else { - include_once '../include/config.php'; - include_once '../include/functions_agents.php'; - include_once '../include/functions_reporting.php'; - include_once '../include/functions_modules.php'; - include_once '../include/functions_users.php'; + include_once __DIR__.'/../include/config.php'; + include_once __DIR__.'/../include/functions_agents.php'; + include_once __DIR__.'/../include/functions_reporting.php'; + include_once __DIR__.'/../include/functions_modules.php'; + include_once __DIR__.'/../include/functions_users.php'; } diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 28311371bf..5783964cda 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -35,7 +35,7 @@ echo sprintf('
', $menuTypeClass); $notifications_numbers['last_id'] ).'
'; $header_welcome = ''; - if (check_acl($config['id_user'], $group, 'AW')) { + if (check_acl($config['id_user'], 0, 'AW')) { $header_welcome .= '
'; $header_welcome .= html_print_image( 'images/wizard@svg.svg', diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 171e16870b..601dc797c2 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -575,12 +575,13 @@ if ($access_console_node === true) { continue; } + $extmenu = []; if ($extension['godmode_menu']['name'] !== __('DB Schema check') && $extension['godmode_menu']['name'] !== __('DB interface')) { $extmenu = $extension['godmode_menu']; } // Check the ACL for this user. - if ((bool) check_acl($config['id_user'], 0, $extmenu['acl']) === false) { + if ((bool) check_acl($config['id_user'], 0, ($extmenu['acl'] ?? '')) === false) { continue; } @@ -732,7 +733,7 @@ if ((bool) $config['pure'] === false) { echo '
'; // Need to be here because the translate string. -if (check_acl($config['id_user'], $group, 'AW')) { +if (check_acl($config['id_user'], 0, 'AW')) { ?> '; + + if ($not_defined_only === true) { + // Case: search for those extensions defined in metadata CSV which are not in database. + $short_names_list = array_column($rows, 'short_name'); + + // Traverse apps in CSV metadata file and set properly those that do not exist in database. + foreach ($sectionMetadata as $short_name => $val) { + if (in_array($short_name, $short_names_list) === false) { + $logo = $this->path.'/'.$short_name.'/'.$val['image']; + if (file_exists($config['homedir'].$logo) === false) { + $logo = $this->defaultLogo; + } + + $error_msgs = []; + + $url = ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz='.$this->section.'&mode='.$extension['short_name'] + ); + + if (self::iniFileExists($short_name) === false) { + // Set ghost mode and display not found message if ini file does not exist for extension. + $error_msgs[] = NOT_FOUND_MSG; + } + + if (enterprise_installed() === false && ((bool) $val['enterprise'] === true)) { + // Display enterprise message if console is open and extension is enterprise. + $error_msgs[] = ENTERPRISE_MSG; + } + + $url_href = false; + if (isset($val['url']) === true && $val['url'] !== '') { + $url_href = $val['url']; + // Display URL message if an URL is defined in the metadata. + $error_msgs[] = URL_MSG; + } + + if (empty($error_msgs) === false) { + $json_errors = json_encode($error_msgs); + // Display messages dialog if there are some. + $url = 'javascript: showExtensionMsg(\''.$json_errors.'\', \''.$url_href.'\');'; + } + + $extensions[] = [ + 'icon' => $logo, + 'label' => io_safe_input($val['name']), + 'url' => $url, + 'ghost_mode' => true, + 'mark_as_enterprise' => (bool) $val['enterprise'], + 'defined' => false, + ]; + } + } + } else { + foreach ($rows as $key => $extension) { + $error_msgs = []; + $logo = $this->path.'/'.$extension['short_name'].'/'.$this->icon; + if (file_exists($config['homedir'].$logo) === false) { + $logo = $this->defaultLogo; + } + + $mark_as_enterprise = false; + $ghostMode = false; + $url = ui_get_full_url( 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz='.$this->section.'&mode='.$extension['short_name'] - ), - ]; + ); + $url_href = false; + + // Access metadata for current extension. + if (isset($sectionMetadata[$extension['short_name']]) === true) { + $itemData = $sectionMetadata[$extension['short_name']]; + $mark_as_enterprise = (bool) $itemData['enterprise']; + if (isset($itemData['url']) === true && $itemData['url'] !== '') { + $url_href = $itemData['url']; + // Display URL message if an URL is defined in the metadata. + $error_msgs[] = URL_MSG; + } + } + + if (self::iniFileExists($extension['short_name']) === false) { + // Set ghost mode and display not found message if ini file does not exist for extension. + $error_msgs[] = NOT_FOUND_MSG; + $ghostMode = true; + } + + if (enterprise_installed() === false && ((bool) $itemData['enterprise'] === true)) { + // Set ghost mode and display enterprise message if console is open and extension is enterprise. + $error_msgs[] = ENTERPRISE_MSG; + $ghostMode = true; + } + + if (empty($error_msgs) === false) { + $json_errors = json_encode($error_msgs); + // Display messages dialog if there are some. + $url = 'javascript: showExtensionMsg(\''.$json_errors.'\', \''.$url_href.'\');'; + } + + $extensions[] = [ + 'icon' => $logo, + 'label' => $extension['name'], + 'url' => $url, + 'ghost_mode' => $ghostMode, + 'mark_as_enterprise' => $mark_as_enterprise, + 'defined' => true, + ]; + } } return $extensions; @@ -2553,4 +2705,69 @@ class ExtensionsDiscovery extends Wizard } + /** + * Read metadata CSV from system and store data structure in memory. + * + * @return array Data structure. + */ + private static function loadDiscoveryAppsMetadata() + { + global $config; + + // Open the CSV file for reading. + $fileHandle = fopen($config['homedir'].'/extras/discovery/DiscoveryApps.csv', 'r'); + + // Check if the file was opened successfully. + if ($fileHandle !== false) { + $csvData = []; + + // Loop through each line in the CSV file. + while (($data = fgetcsv($fileHandle)) !== false) { + $csvData[] = explode(';', $data[0]); + } + + // Close the file handle. + fclose($fileHandle); + } + + $groupedArray = []; + + foreach ($csvData as $item) { + $key = $item[2]; + if (isset($groupedArray[$key]) === false) { + $groupedArray[$key] = []; + } + + $itemShortName = $item[0]; + unset($item[0]); + unset($item[2]); + + $itemIns = [ + 'name' => $item[1], + 'enterprise' => $item[3], + 'image' => $item[4], + 'url' => $item[5], + ]; + + $groupedArray[$key][$itemShortName] = $itemIns; + } + + return $groupedArray; + } + + + /** + * Check if ini file exists for extension. + * + * @param string $shortName Extension short name. + * + * @return boolean Whether or not ini file exists. + */ + public static function iniFileExists($shortName) + { + global $config; + + $path = $config['homedir'].'/attachment/discovery/'.$shortName.'/discovery_definition.ini'; + return file_exists($path); + } } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 0879c38f88..5317dee67d 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -8159,6 +8159,10 @@ div.graph div.legend table { height: auto; } +.height_auto_important { + height: auto !important; +} + .mx_height50px { max-height: 50px; } From 433ce7971fcf63cea6ce1f5beed2b431aa23450b Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 5 Dec 2023 11:38:11 +0100 Subject: [PATCH 116/157] minor change --- .../godmode/wizards/Custom.class.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pandora_console/godmode/wizards/Custom.class.php b/pandora_console/godmode/wizards/Custom.class.php index 41a177b3e3..69e30dd86c 100644 --- a/pandora_console/godmode/wizards/Custom.class.php +++ b/pandora_console/godmode/wizards/Custom.class.php @@ -135,6 +135,27 @@ class Custom extends Wizard Wizard::printBigButtonsList($wiz_data); + $not_defined_extensions = $extensions->loadExtensions(true); + + $output = html_print_div( + [ + 'class' => 'agent_details_line', + 'content' => ui_toggle( + Wizard::printBigButtonsList($not_defined_extensions, true), + ''.__('Not defined applications').'', + 'not_defined_apps', + 'not_defined_apps', + false, + true, + '', + '', + 'box-flat white_table_graph w100p' + ), + ], + ); + + echo $output; + echo '
*'.__('All company names used here are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.').'
'; return $result; } From d601103df30d19373d7a0a08b9d619f634e16f07 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 5 Dec 2023 11:49:43 +0100 Subject: [PATCH 117/157] fix url --- pandora_console/godmode/menu.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 94509ab820..2376669cf4 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -476,8 +476,8 @@ if ($access_console_node === true) { } } - $sub2['godmode/setup/setup§ion=ehorus']['text'] = __('Pandora RC'); - $sub2['godmode/setup/setup§ion=ehorus']['refr'] = 0; + $sub2['godmode/setup/setup§ion=pandorarc']['text'] = __('Pandora RC'); + $sub2['godmode/setup/setup§ion=pandorarc']['refr'] = 0; $sub2['godmode/setup/setup§ion=ITSM']['text'] = __('ITSM'); $sub2['godmode/setup/setup§ion=ITSM']['refr'] = 0; From 1a473d3846a7100a0ad9dd630e6470339bf3712f Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Tue, 5 Dec 2023 12:33:42 +0100 Subject: [PATCH 118/157] Added applications images --- .../images/discovery/pandorafms.aws.ec2.png | Bin 0 -> 5274 bytes .../images/discovery/pandorafms.aws.rds.png | Bin 0 -> 5546 bytes .../images/discovery/pandorafms.aws.s3.png | Bin 0 -> 7270 bytes .../images/discovery/pandorafms.azure.mc.png | Bin 0 -> 6668 bytes .../images/discovery/pandorafms.db2.png | Bin 0 -> 11023 bytes .../images/discovery/pandorafms.gcp.ce.png | Bin 0 -> 9135 bytes .../images/discovery/pandorafms.kubernetes.png | Bin 0 -> 245084 bytes .../images/discovery/pandorafms.mongodb.png | Bin 0 -> 7782 bytes .../images/discovery/pandorafms.mssql.png | Bin 0 -> 19898 bytes .../images/discovery/pandorafms.mysql.png | Bin 0 -> 12952 bytes .../images/discovery/pandorafms.oracle.png | Bin 0 -> 9142 bytes .../images/discovery/pandorafms.ovh.png | Bin 0 -> 4361 bytes .../images/discovery/pandorafms.postgresql.png | Bin 0 -> 16440 bytes .../images/discovery/pandorafms.proxmox.png | Bin 0 -> 13246 bytes .../images/discovery/pandorafms.sap.deset.png | Bin 0 -> 13481 bytes .../images/discovery/pandorafms.vmware.png | Bin 0 -> 6039 bytes .../images/discovery/pandorafms.vulnscan.png | Bin 0 -> 17397 bytes .../images/discovery/pandorafms.xenserver.png | Bin 0 -> 8732 bytes 18 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pandora_console/images/discovery/pandorafms.aws.ec2.png create mode 100644 pandora_console/images/discovery/pandorafms.aws.rds.png create mode 100644 pandora_console/images/discovery/pandorafms.aws.s3.png create mode 100644 pandora_console/images/discovery/pandorafms.azure.mc.png create mode 100644 pandora_console/images/discovery/pandorafms.db2.png create mode 100644 pandora_console/images/discovery/pandorafms.gcp.ce.png create mode 100644 pandora_console/images/discovery/pandorafms.kubernetes.png create mode 100644 pandora_console/images/discovery/pandorafms.mongodb.png create mode 100644 pandora_console/images/discovery/pandorafms.mssql.png create mode 100644 pandora_console/images/discovery/pandorafms.mysql.png create mode 100644 pandora_console/images/discovery/pandorafms.oracle.png create mode 100644 pandora_console/images/discovery/pandorafms.ovh.png create mode 100644 pandora_console/images/discovery/pandorafms.postgresql.png create mode 100644 pandora_console/images/discovery/pandorafms.proxmox.png create mode 100644 pandora_console/images/discovery/pandorafms.sap.deset.png create mode 100644 pandora_console/images/discovery/pandorafms.vmware.png create mode 100644 pandora_console/images/discovery/pandorafms.vulnscan.png create mode 100644 pandora_console/images/discovery/pandorafms.xenserver.png diff --git a/pandora_console/images/discovery/pandorafms.aws.ec2.png b/pandora_console/images/discovery/pandorafms.aws.ec2.png new file mode 100644 index 0000000000000000000000000000000000000000..46ae12b2661e3ea0944963a98b552af89c040c65 GIT binary patch literal 5274 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 Rv%MnV9@OYgjjluVe*rNyCNls4 literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.aws.rds.png b/pandora_console/images/discovery/pandorafms.aws.rds.png new file mode 100644 index 0000000000000000000000000000000000000000..b118945b8373ae685c170a2a1778913cae0693a9 GIT binary patch literal 5546 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 E0d4cJO#lD@ literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.aws.s3.png b/pandora_console/images/discovery/pandorafms.aws.s3.png new file mode 100644 index 0000000000000000000000000000000000000000..2a52510ca47467fe300f21510f3298011f738e63 GIT binary patch literal 7270 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 V)}#D*D5^(@rlO!BUkSDd|380H3;zHB literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.azure.mc.png b/pandora_console/images/discovery/pandorafms.azure.mc.png new file mode 100644 index 0000000000000000000000000000000000000000..562cd52c664fb0345dbbd288cfa69631df17b67d GIT binary patch literal 6668 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 X^MD!q-Rb?8l`12lC|)gU6#Tyc$bfYw literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.gcp.ce.png b/pandora_console/images/discovery/pandorafms.gcp.ce.png new file mode 100644 index 0000000000000000000000000000000000000000..a971abc4917d5d1f1b4bee46713f396ce75061a2 GIT binary patch literal 9135 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 `@3-a@ekx^r=z$88fEcM6e3_e_L(a7u$ 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

9*cik<}}OmlnX^es|Wt zol7e@howzh?ub$f#u$Uwzh)Hgxptzu23)3_Gqn0n#@mV|rz~WEjEiNCV8j+@SL1tz z35Mh)L(XOv3@?v14GX@F#k;N^$J(hv<$>gf2GfR@yiN-kB#gvM<@0yW;=qyegz?e> z`1seS@%+KQx>F;sbB^|j=A|(PAH04N>sA%7NVz0B|LMC|W5*`t;WNey{^?0wMxdQr zOA0_|7A!vgjp=HNe`B&`93HqxM z@H_8cjZN$MtrI(!ypA%8+!zN);h52zB|V2XejCIMav?LdDLtpIy!~H&)+zS z!klnan8fYm1Z0_@Fy+|8$TM)2v^@QI&BPBjY9}yxw9O|6>CYhq?{;xJIzbq zU;$WbrU85h`mrwVC#J5o`X=~P;GmtbO7*AfwkNn!bCXH?HgLK6COon~8sM7X8+nKO`U3?PmNTSQ4h^o@G$YDYB;Po%dX5+j3dyP7^bR{ z^8uyKl0|P?IlNr#TYTYrv*-N$~~4FU};`8$If`UwXoQE?g-A? z*sbxKc)oFf%X1{u9H?FWxnWho0>v0~r5&L1I_vWbx7% zgAcxO662$MteyFa(aKYO+uUTVn}esoa65TE%cU(@M%i%;A#BQZvNvW#Eh zp>{_rvm*ZaS;0AQK3U6n$sWG9*0%*3B%Bx@{2sD?ERvrvhrlP;Fc#m@@N2?prtuO% zW##uL1~Lm zqbWzHHU`+W=4bPIjzhw8JaVj)!pjsQ`CTjA$#27884#rU$T2k7RKO<3X?rFy7jVhz zR7Bmh>*K#a^sz0l7B|CI^vy8`>_W zGml4}>(ybL(~)vs2u5aac|YEsa#pqPbbaGxV|dTC)HaKtF&>wQmnJ^(LKR3 zd)ANu#MwR*Wf6@_3yjxqSi+p0H%oh)8T2UR+iT7PRT9^KW$ zm+y|By*ZJ*9F)K(zghjLY09CNjMiJjd>eRaoGWjP=Zj@H ziI>LprK5w!<0WU>h_NEhxEBO4d8T`htrvY-g_k}wpze-ljrV@u#(G}VP1b2%CV2Uy zvNT7LcH}kRRZE6zeya=;pwwyo`M7Q9Nztv1EtB>TaGFmmHv?onMB9qur55nC*_n}L zDg9H?+ER9gWJv`lIe5Y=1t3)?>B;rg;2sB19d{GflAVBc*Fw1&ro__zZm48NGx|(8 z6cV`)!6Kuq_lQaoKUbt+N-Kv~(4wJC7S=~jK?xZ7Xc3k~Mwc#i=WS*2a&EEO^;zua zv$yfkY3ERbGe)GMnalxjp^Cww0&PS`kI7YI-=2G1rNlAh3o>GP} zT$4$*ypPYE1A*^pKAyF_XpK)>@4(fQh9m%gA4fn zV~aKVb9`xnI}yAb8v)*b{RFz5SB6{yz%>_+;=^y6Kv9_E!pn$iCVN_tLojlOlCBR= zm-vfs&LGOf+xSHi5iiA$M+cW$&>sDZc#2dIXcDx7}z zkL|hye#X0O_4%-Hfx*#Ow9Ds%33Hm4O}vCfX)XTt#~<5F5w~{Q2dpg>Ftqg}b9HTf z$>oldqFp=X!~+QF!^?JARtzt-;Gij}kVWE<5nof$CORxl%k9Hy2I^aMsX8cqwE7zU zL1|~L#m&{F%xA>6rSaM!C=+>1P4y3?5r;Nfy@qW}NBumg<}j$UQD`SRi{P^hGYgNo8s9XW5{?(bb;pAXcydo4mggh20dQ zJld)AFibkwT)8c)b~v0AGMV6Vd776kcnRERVg2*hiIVaGf%ZxF+)=Kjlwo{Q-j?%Q zmr{n^1UV(V9Cko$cV;O;M^n+pS<23k?3==&1t+Db&u!<)qQORi)=SfX1^%Tu|yI^O`I;KG8b$?(k=gIE(;B1y{!#dNA5?9&*zrLFZbLh;2s(K1t< zSg#vNCnka!8GNF4RbPTy#&(7Ba(2PuZ@)W>`Nc{kQ;tsP7n~#QXbN|-HGFahLZ4$O zZ@6d-zkJhF_3QCIo(uN?Tm34VXiV+D9~a>}@5AeAGJ$Yhf()qT-h|cUh#xPiXqcLC zuR>Ow?32OETqd6Potd}zlfRorIXE@Ey!WX^eCz)C8V~4uju$7BmuIXg@WxBV+~i#S z%TO*yM}Xh{nbp{FPI!yk@!};flD9b?bGU;?OMLp)nc$al{u$0G_&P8?(mc5iBwb(C zSq}r(Ke+X@7VL-=_n*n7H(+bQctG=vm_<56A3-r)jt)COzYn=T) zNNA_AJPoIL*~m-S+XiLwhf8yhNAP;hnb(eD$$IU`mMk(spX;j~7nAh!-4NN{xVjkK|vU}T#-gV=;473^q2LZvA{ltB{!6nj3kr5u!a z9Kg*!+2KksCIA`Py2HZj$Os7>GP4$;VC`ISNG0N6t+)<^_yKG5@Ne4ucpnP#6q6`u zt^uf!dW#W+FxnK_A&k2ZLaD9RM|`eeUf%KG0`7UdI%1RyLTcl%B9E@{`qU8_39t3- zb__o9)+xO4lCcoavEV%7h;f!Sk_{pIKAp!6x{dqT&@aeIXf!tTp`#P^J~4q;?HI+j zv%0l;o=je9FdV0~7PtL)9uGd#J7v7I*5cE*PGgUIdsk{VMw`#c zwKxixKYj3HTjB@H^dxta-cg51Q!2OM5(*!a{x$mMBXHuDlU+xYhthdsH}1h4tPO*=fxDXBna zxhJxgf@4MTa+vM3HU#B@m{f$93pASQn#wTDZlXO$Q|cI8c8mu8{o`X1Ubm4Nf*!^`hKwt#QlHy=4bP3P|;5=6hYZ5m$9 zx!rzt7r*`f)mS@aT!PU03_Is_xJGmxKVKybt!0oFE})HZTXl8x`zO#-)t`H27gt{} z>gT7;IimLj^HS?umKIF?Y$<~VQXxuzX|Og7q>NrQx3UC9;Wi>0}g`-FNfuFL4l5>0~V27p5|qS zmlliG;*Sm-HSwEP(q$OGwao@Y8^1YMm!m=UTaJId)Uk)fc|v(9&%`wmr7^C}S-)Iq z^W0FXPNQ=e=BJL_Y4b}3ZmGV+3mN1^bq{`Q^P;u*zX7XTd@A0?8N?6#v+u&@kTR=3 zUlLBhT3de>L>977#wis38f=fz8h)kv>wdRel56ESVZ55L<*LiXicAk+s$R(u!MZGx z!aIqJyAoiu<;+Emk`=_u#ev0Ne|rW8jtruJM>~!p1EMz1kNA0+`q&!0mQB84=NSI+ zJ6B<(Tk(aSX)rWLnx}Q<*3}tUdY(3ZT|5~?W^{>{##TWvXRRN{8}{(VB=;nTKYl^; z=@^6eT|41_8%3M<$>t@mBiLv6_wlK3&A2+8a$X)dTH*_L&0@ebZR%(gpZCe;Lu5@TesF7T zIFcxosBpzLjRzJaSJv1dm#2A|<)wxBk_CRS=Tn=Pa)K#WQjc03ujIb$+cd^-r@=512dR zmkik2cgz0RSetmI6f^=;R0s+V2+nr(04^fcWtDMjX3}tVg!)!H@8rS4gN)uO5U@3S zY@I=6B>5oDvOeU2sKpUyWgQW2J^y?Y@sshAoE8u191M<_=cy`?mCwt^p6}z!-=C{y z*7DejJPyQRWbh>W^LAOMwRH;M7jB%yyI(gBQ@8*QftUVecE$vr_%HO8&C9?Cx+M3Z zUwBZ~AdF=U8Qu7ybbsF5ts&98VReDGT{*7u=v4BO*YyY04~QN(GFVZ({Oa9vxc}+& z>#bJ;FW0Xs@TSYgg6=dHD_Jf(9fO~H({9 zbO@Ud$q>nzWjN~r2MZz$uRG1lCSC$&)>`|&A2=E%pPP6qByf(#oooKaNa5O`D! znG3?=Lw3UH=V?s}+6;%6bg<$z84pzWglwdVjnUw|6=3y*zw$P!4VD-e@z8%75s?_q z3mVQuk;}`0m!++a7(KD4?`hUb%2~{1WbGg{qfR$xFI^WLFPg_#XXO>B`~d zv001HeW&`JDak9XoC;nVWAL8WPgF<7*sFV2s$AZ%a}59Fr>D?Oi=?1o>AcJZsT@Ya z-ShY&zIFeCpQq=gu`cfvcxUK4@iNL5(N0Eitm`V(tr#V~2q)uZ70g->Uzq{U*RV#0 zYzN0l6j^=%(XyovaAA#^jbQy@gHK>+ZnW0IS0M8xcTG<7Qs-sG5Bxb`9@z7#ElWAE zl!K`~(=F;{9hCaqSUDfGiQeVx&ZKzMbSi7b@G^x+1U)dMwKF8K?GGMu_9&*QBoCvp~U7tc@#+pDgupX&e6O39=E-qKQzw{B0om%Yq{t z&4(KUMy=191%BXV$jkjlN_^(l8Iso^zZy-1=1o{+C}~ zi}TO!fJ|$+J>vTW*03e6_(QTEXQ8Wplr{I@evwErSbo)n=Q&~-tiDf;8~pr@ljszt zHvg5v%f-IMXK$auu{m-hRu(UBePABnesDe-W2NzO>seh~v3(@UqOU|=Uc9A?|LGUk zV9jLbr0`M;o_Nt{)PLS{PUpcxefjbJ_#VY%FOvXbksTM;?*m zrRTM{$Bl{WDm7{l9`+ad*tj*as2^b_x(tOf#7o24!KA=?{8duTO@YX-wm~YnF+%oE z^D@Cp`;4{tgZn?aIpbeD?NPOwX0I`L7gSj&y*Zzi|pk9n-N7mt- z^$HqyIE7^Srdx z3k`nv{*P`x=rC*kU@9p-?2bupH%8k?NcoT{+;W_@MIIMxJC4?t3sP1TFSX-sZFVcD zO-`ign3q~iN{JatT-Y>1i#8?pw zA3J6d2ZP}_gyahSE=0r^ZOy$S=?u7acG(7w(`QitA9~{iCdcZuOP-u6UQW+fyFI;r zpbeBMUO~LP|LH}1?T2%!1HKY?X^g?8+eUE7))7zhO5)|}34`DJrM0-|+-{8zCyJNa zE^%%*$QXks_Vn>rx6NP>zgRHfAeY<*zFE(spisGLrRG3u^~V_amrT_3GFu30ic^Os z=zklxR!biELX;RFeu)6pN6{{q3_6Booax|w890-h*rvF(;PU}a^HSlZoA)P6m@hyt z(kBG!&yy_Y=vFSFp7ari94{3xX@0vLKh>|z=`2}R951z?qYbk-(x%e1^_0S~)P7BE zsj=iPj}~zQ^@U6A63JaKIhMo)07Yr>H4FTqwdmKJKQ&kpMb`sCA29?q$DOhx(h(4s zk*-XRYimv3P)5i&k*3~eOii!Gw8X@PH>@{*&LU(Fi5`yAt)U5b zfTxYq7_GfqYbRO;j+Y$PT5LI^gX?#Wt8-0d*R?sHC|+7?aoYp)xcA9LPj;C5%Hrjq z1U`4?EM7cXSLG{#mjJMO!r+}(kB1Osh46BG#NfaC;2K=NbIiZYAhpADJb5W$G(PgW zUf<%A-<-zYLnSCPPpUB5IdVLpCm@XvBm*x2us3AdijOA1o6sq^(sXT@UU$5tQ(Igv z`AM#-igqZ7UQ2_q`2<^J=&gNG48Z6onX!RJn#2Fk-n)lcauj!>zdYSNJ@1it2+@rZ z!pmc2BxEkai;)4ZZG16agMl@yefL{q7Wgi*%?iV1S+6h4^4ZwF>*q2f5C+SZz!;2p zgAhmvA)XdOGkPE-83`c`qt|FO{q8=e;{H(?nUPVES#`R59^KO^^;A`6WJF|CROT-- zv+9J=-?IxKp05$@zhTRETLQScs_>S5yNh3Olla)0*w5_+S;^bH6VQW>KWX8*HU)I zJF?4fl?lyIGs-ew^VGA)R^t4T5rAU)+vfuWmsy{*ky(s&2f8hTkAFu^{ff zEKIkeJDhvQI3B&LS8SUu*Gqm8fTmy2|@U9I3! z(j?dW_DoJ!75)Ig*9dW70>C>Ne9~P?pi+4}W6~U$BPVNsD+N}HQub;M_M(Rq`Zl7l&uDku)@J*l>=p;oz%yj0a&~QXc;Pu)%#RwB z+EZ#{qU{Q8NksVEx94!%{(i6g~lxLmsL&;alM!ZhX zkz{G5!#ZzMW*C~T0okxd$wh!AIXY0uEgxEus^%eSHH|E*_U@Uun~2^5qC54NTaSb3 zU?lgxhHglLc_;e{kq5RI(nOxMPmU_eV(Hq8wGyn zS9ahbXN4K=D@(Lwt^k&v|2V;6SkCK-pc25ou_HL%4$o)M2}r$ z4a+CD64Nuzr5vU$tzPAp=rqs3V}23eAh@>@xx=#Wi5&*wASoX7WJ^|(VyD$8NqSU0 zholEX&DEK7jg(YmKoIL`zG>$R8~l@4f;Yv>F26YtJHsY2^k~{j(zS#0wP?$#0^WPs zH152&p8%hfGzCn#tw8!*AG-oDO9$s1wvPAk#+UBI3!bq#thNMxq3x+{>N8;=o`npv zk39HO_%-tg26%vv!~NJO@RDb5#gxrk1;;hrhj+reTfEPStGtPhUPHY=bS72E8qv@Bj zzAWSV-@Ii3pZLZs235S{jEj@i13x+A_;+AH9>=<17inn-JF$I3&!}t={g6Zz;e(>B z0g7{dz9*#a2?V{+jRiXY)iKCb2#?g`J&rP%z_BfpV*l*$K}@!7*wVCR1>llFMSp(7 z?uqgeax-<^7FNQzrOEFu_1n@)`K`7-E0uFZZP{f{Uv9a`I$uueV%#Hn14`S~tW}=U z%8?FWkf~P+q5{n=@0|qTE+ycd1oVOM3SdYYCMQFWm?f0mm|PVCjKQqIN3~X6OTeOY zlN^`Q5-D2!at=};5SGS8Cm&UpgKV2FlmLHS>gS*u&DIP1vU84ug~dx{6t0gKTRu2d z;jcb9h51D?fm2(uW`_05xt>jyM~gPcf9KX7-u&`i_=TU`9N%kj+$zW+6sawJ+a1DZ zQF#WG2m1O3>bXX?Wj#!v{+Llb<6mtu+aYz;$F6Cmw!HBNOZeQi^B&8@S>psu7%{P! zNX5~zWsSq+etzKL8N$U^%wRB}V{S`}cI$ZkgQm_MeOo#Q{Onodc+0=vg&kX)@8sx! z?MV7%8xQ9k4o(g5zdtpF>3K?RK@|G!;FqGjuJ2`d|KRdwf6X922H52NDd@+32DV9D zM{r4b^h@?l{-A(!V7M>rOM#wwh3#YF$EMS9i|L(^mxA~BJW!wmYX5N9uw}`Xek{DI zBKm`UdnTumrnc85bjnSt=kjv(k4Ca4=-X(m)b@G{RM~NF%iK1%VHjIH^gBU-y{g3d zrI(VH^Zt$%oRny~1a(&6qW2M6L64SM+FRLphv@ouJ$A9GXb*skNPOSk++t9d82L{2 zp`p{{D@v{;B(VoE7iLvzk_12nInBT#S&K@Lc7#4UE|7d&>>&+ZomnT*CFpFuUY(|9 z*b}=_#HOb_i~w>i+wz*5>Y3S!QovLiL zg^s2z`vbyda3gp0l~jobG3Md;_@X#m!8 z6k}Vt#Fnv7jJ71tBj$^CNEWt&@WwIvrc<$@(0u;rYt&G}5b?b|bXxFWnA zz}31kWv}8n@hq>OC8;~BFn<%f8`&Fjho}d>Fss6dnLJ=8_%-iFzY~6&BJlFFMh$Rb z1qW(%ilUwj6OyW2CT638YzBQ?Ndz2?)fxc~xhsyd!I4d3OVPgdU`wj%-}brfo_=;F z*P2OYKv;S=K+@&%b#T+h=j81pc=OA4;srms8Kb?_1hVCgVOsKZ(IDivRKy@buJ_dz zd*sd@Uii$d==IX}=C%-7?bT(gY0GbYZvkJvVIgJ&zpmS5t{{s?hnVIl*pf&-w-WjQ z3roO7U!1{WpRyoZ+e6bFNx$5=rH6BWVslE*O~dNja>UgE_kVxoE}XnQ4Y;&!N6Rmz zTr2Mzw=Ccz*UX}-A_Ncg#O>EGU#xN^eKHbThT#qIx+V_;LQ)3LDsGE%K~@|SYa;2F zp-U#Q0^!fO50-gI&Qo~^vN(_J5%s6Q+w@)#v=H;?9>RL67L3 z>eT>ISETyWk^;oXPml$jWC}~ul4t0@9rx~f$d5FTP`jU zF1~UGvkMBv2tT#74E(6}(c1SViz8#pq!}_e@Bruf?=RxAYv&sJ9uIywGUD)(XK%%} z&6$8=6>T{(QvZI?@4s>vPTrwbnGC->T7GHKuzemlT;YFRdKim+K%2PkS7oE+N|{(s z@T(AkmTf7!`OrKD`$?oAbfw^z@-76w6#ZzFhtMa7{ssk8h zq*q9+G9Zudt@1Tz%bcM~%Vhf83QD>JRBge4wQa1cUOAb%OgokiSb%m%8730dJf#j$ z*A4s3FJT`MUPpw*0AK(B&i_)liycmmDmD-CSx*IVd=3ehyrK#O5-sVOxId z)&=~-RkP?bjRnSZo>kwX)pd4mbvXZ5cjBc#y%i%pZyRr=)DW?qVrZ_9 zesw}q1~#t#r1r1<%vNj~P3>o`PUTh>^l>$9`GxPy;XD7b*ld4{*b|?U8pfDE_2naF zOP--lFq@ahV5cJB{a={Iyz!~^Ep&Omr!WCL?6~f(Uv4>1W^F!Vg<6ni2HHR zGhl3i+?#%rwntvY^-UK5zld~Lu|j(UjTn12Y-!uluXDYBP+`x$JrfqL<78nsjSsDI zoo8Xl+=__C$QH)6>gr_Gvv}vQaSs1#I^CW%Z%a!cE7=zDl~yxyG`R?`6sgLUp^Q(%1D2AomTd`#4_-Bcuii9o zfGtITE&X&09z>A-~HEqT!+H#}^{QGma;>|DLh3#8<=IV-k4s!N5 zQhurJMpU=%^WUDsC%-WpRtM4-_Z4vUmLX9VMN-Tcev<@{(v;y|QifK`);fu@hP>1- z<#I{-Z@Sei@{0Bgd~^_+j9c-KKpVC!*wX8H6;<>HH|&|1MT#9YmTbEQnmDsW3stU< zCAroyx0=!>&yr=)TD+`33x}^+Tb3fjE+9P@T(qqa=|CkXs}xz5Qf_r zzfsSj`HQ52CK)_j+V4WwlfcT!2&pXJGs$m@S%0>iT_F7RC#Uek2L?f&1-eSt4Q&b_ zvKDUxF{_?6%e{G153l~k?Re8mcVhFXSS?E0sh$L8yJ`BHuQj5x@?wWe{Rys4Z2qqL3b zm}B?%i9QtDuwl!hE$^<#ows+-Wg(XXqWA zM!zCDAE2)_et1(PV;2JeYhbrJ++mZh(d1xK-gozNaC7RGHixVDyUjU zt>x7?K5Y4e`v&;Sj~~X&{PMere6VN-FY>%pH&-^=173FSR{YU#o{UHA7(qH?iR2g+ zi9@~|l;!m)yLx!hIa}&sSgj1S>9krY$Nz!D16+K?4E)ceq%*!~t}#H+>2SHxCOClP zYT?Rlnac6Dq}mq)rHj7#z~KrPeQ`Sc4$Nw#)$+?tqYgj&^v$bk%N<)B{@btZ!f*ck zc8sa-80b|VeQwGm&d10)%r; zSXR)GSWScXNJ{-uzVNRHjpXHh?H@{xDrkH-z`m$?$SmjdQ?p^q#zzO%=ihyIKI^#hwRcsc1%Pe z&;CkS-T7GHhIlF|AaEC}X~lFWruXS4S3-A5M(`c3nCY?5KlAoLDl;mmHX@bh>&N}n z+HeTlIwGs}WXo9lD>p9Sk}GF0sM49{VN&Tm9gD85tSunwIpDcxj^qD(^+`DGlu^GQ z-3|=N7jSqG<`tcs4F#U{lyU6Z*6R!+b(^i@YS@y9@DEqb;K8XXv?tD#rt`eSKFT0M z!6NCM;hYV`HCDlv+B*S=&*>7vOVTdt_UUiV;r9JYjnxi59xJ~DfR~@U6+5@|uo|{J z_2eG@=YQOV7d>l>|4jSprq%XKrd{k4-go&lZv4R#WQ*7nYr=KI zmMykCzan?lcQ2gG;Yw>;RPMCc-oW)+U_bTo<~f z0N)D$`&c<_;ae2BtSOT<@kMkjn+&Ph=o07pT%zF_-0VesHKMtPD?6vv%#3cejgN4(B#NmS2ZR|I_U%QN`mcjgUx1X_7) za1}GrZQF7rPsvx)TCx&e0M35mCj8lJPR2P;-sA&SInVY- zV>PF1aB{T$vLeD~zBP+Wzd9@Ey^s0!F<^JG(C>^S;gn8O+Rk zIPF{rb^{=$j&z?1oKY7*3IP(c($!|ny*{oYBKslOz2>{pLx`_9DZW@aL zenvoC_d)Qtx9%^49>lBa-Y>(s;|gYA#;X~Q^C|jJ^f_M^I??n!8ObaB!P6qn%MysUf(Wf}Zb>Y+2e0euNKQtn+)9$Su46eC z3P&xk6j53R&+)Vzvy>7Z`}Ry!gNojb`eO&t7X0!b&!RMDPa_Dj2gYwgiCh{L3Of|LwUjGs-~)18Q!Hm`_#nxYqjtPSi=uOjR3Fug>CrnuiS;l zJ!+(ryj(iken~{Q>;69e@)L(~|HD*Q3~~+|wk+E6b|U=W`}Ry8+JA9li<^ZXH7?ZH zQsdejj;qvP4wts^w{+y|o>>J^Jm+Nja+hTJ{xEec zeR9w2Fg#^jE5vbI8r>l^SPyYpL(-+=e)C9*hva1?Sy$JQ@*Du%_s@Ucf6O^=yw*8) z794)uamNSvj+Fe8bVgdDzNd%t+ccW>0)PpJdY`ZptU`CJ2it@18{yX|!kZ zmu-{sbh2j6b2_)>5fSDW34i{vDcm8xNp4O^D@bm77IvkQc8+_E5aFWd4FJ9>E2OLyXx&)bG=oAd9F zuK@RuK-!neM+n6%G@Ki9~IQO17hAXc=DI@YmtuJh9VjNc_o$B#&p zyLT?si}~`2B2$jt1}($(`wd%0IUskC2>lXkt1i=rq34IL{e*UFAU4 zkw>e(MQ6#jYeND<7p5p<#Gh$%;aAM?SY~ zRf@9pd7BJNPKl=4yL<9LMR+p^wSXrPxVaN&o7qcrkJQ%q*qsS zwoLTU&l|Us;g3{{qF?s=z&~C+i-S|us@Zb2{PLI1*@DNMJkrUQPdjZ4@BGb^@GJjj zE5_uf*E9Z7(&Je8!Iv#r5-^pO*)5@6^#su??Cp3IjkR^^A zG=<_R{Z&AC^*~9VWWP+tAgOcGL8tGBQ9_4C{)R16TN1f>B6`RC5?zjTr9iJ9aI#hf zG*GwbV3hTc$9y@t)_JLJSKNt?`gBz zF1d0BpZVvxY~T@i87nfSm6^6JY?8ihOOhpv(~~B~@U~yyg;)K;cI?_NZ6gz5^SHyW zKYyFKpw?w&K%427T=`1)hacp zr2(+_jwL+habw}V1paH=ilevIv~95|@yqck$z__&n|gT0zuJV;PaVS#?(5^=RQ&1@ zxAmD%+Jsj;ce}Emtw$G~azUFeFWHi){I#CNe}YS-2A z%bi<$_~P~RSX`opEg$=c5xo9IJMddC*nwT!MiRM}EImn*lX*1#5&*8gVIF_=@hMEr z@#+MrdyROX9Z;{li-{WUYj{P3g9A7?;?0=p02{Hp?E7N9`paJ~(s4e^aPmDk;f`!; zzVIiZIs`+Kbse1Z+eZCY$G|}gNn6N)Dcx=?pI2#%4O=#C3E=Y;x%2n#o;W1LaHA_J zI&wd#UQS=;tJP1h#R(oILZiJTkuJg%yM3jtgNa#cEC1VApShfL8GI_XhK zO_A3GU*!L50QKZN=?c@Mg8)2{JmPs>$CCtkr1Dr7@9)i~BrVeA&X7e!i5^xUl<2r# zY#9bcvF##^!F8pFrYro>KR%2*@9l?e3KCf5wi;;=C1=!iJ*(W}qk&wGUh6c{b9nxl zoAD>FIvKzGQ(LfQ+`km;97cM;OP;+o(L<)vYFBACUDnC9EoVz2!hwed`0!U|BM=IH z83WT=HlS~w5!x$#t+v)aEB(_s7eBQwz*-%k5IEvuTh@e5$m3IL`YlveXd4p0yyL(C zANyLp;;_j-kYqP}tV-&oZR@_c!cEdvgAK|c4B z0>KeoI1d50KQii; zR&$_eyI!~Dm1O7Iq*tDFzU;d6k{+pYX%8pL$l$5%rR&T4BhPd90Qdg$pD#V;nQy$- zIrozQo>+I5u6_yL&z!^+4hAy*n&Qj#4PeBba?&&bfEvw&0A#WZ@ZYfnZ_P;n6H}@g z>G&@RDUu#>)+p5Te*w(PHpQSP)iIVO^VKeWbu(JP=eRigwk~bSzuBM$b$Gp|<|^E9 zXCKcyb2GM%%K<#jvU46Et*w3*pzBgk(}Z>x_**=8Z5zRJ&KSq!BS&!Oy?s19LwNk7 zNARYX?Lx0H7^i@;ZB;;?w*gNJd`nvnD&T`x&ESf?^TGF|e+F40KLQK>jI8vO5RZs^ z&MPVbmYm~=z4jdfdSx?@CN9~l~?CEAp zUACHjx!4E3cJl%%sy|@xAOGz(yx}D~G5N@mEdLzOoZo9*Y8xF{zr5$c0shAa4&nO; z1}qWcMm74p&?6;$DU^j?$;BQl3We{d<0@d?Cx>1<@yuor&EtR=IQ5VqKLF&Sx3gb5 z*W3pnd(-sUkwng*7dH2jl6wav&&`G{L)m>5=)AqVC%>j7I&m(wA(f{!)>ukoHc6v* z?BtT>tsf+*r$c^~MDvs9Qb*_`=dg*k+*pe&h)edCxt(AwaNd^km>P3!kZUsc< zX6Md}TskN$mgO6yy5kSo>&2F700!sk->owSuydZY34i+Pld)rq zF_Red%WpL*fxEUXO1YG)*S0n8z`;H)ylfheeZ&Y}^MCFbN{6o7?v|rF5#hG|ef;jb z58}RuD=>Uwe+oyg+v>CO{`yhQ`R$Dj1mds5p{8qoI5MRRyd&CDd|~>VylS>5^~+y+ z<`(?Fzi|>ajSla3ZRN}L%bEEKul?%>v3*Mq=l${yzXIfn^_Js1N7FAKo~iKW_dSGf z-@XVDg^K%&0C?rUK-@M3A5;e)3QppMIIk-JIOoN9I^{od3!#*aq>oY^n{e3ZR~&4( z2G77JX&Zrqh=eEkHgRAXCc2xro;Oz7EKi@fg%sK1~10EFg4xNpia^O5)!6T=ZIvR_a08h#86a&bCrCS6r zL>uLxQ?}d6?366J7!lPj(eZFCAerhd6&a}R&|TPNXJPZ{rQ%cJ3! zH{Z30(@q)1w#_}0Pbua6(xQ{)N5U_GdIjq(?|%qixoIKNh}8opfNad;qwSxGS83ZA zeIVmy_RF+SuCJrqR33AP{kMwD>jq0n(5vlwVj;Af1h)|M$fw2g5dEc$7^SYfGO}Sy zfZ!?u_E1G{-n(aV-ZN~&KW(_JD>g$1x*U!jhEJ}()}OC)__3?(lAJC&u31~=Ru3%3 znx+l#mw4#%7)D=}R*=mAjmD_li{w-8a^ z4gm7A@*xKEV$}cuAOJ~3K~zz>xTc9jHJCAYYCh`P(j&|Yg=@{iP|n4zF=3Q2W#;lr z$%SJWpoZbGMr~QEAvVG1uj{~Exh7W7-uiN|jmS0ZK z5ia@CEEfAs8|Q4P@5zzy%QGIoDFi)MeJw}JwEU7Neb?w{_~oDi{^%bcPJ*6h8(i>9 z;(k&Bb;M&$&6KHM2EH!(r4l3jk%AA0YtNATD1JU_y(8)1Eh{Y zdGEu~W??&~e+EeOm%-1qKZ$2{!y`A?frdqE*}~$d+fb^%Zf)5Hu609}lP86Cq3xRAwo20_<)ULNsIhLGcBEX;mJ5z@ zI_XGW-qf~eHmQ5#1rrt3pM88+=S;blB zloYhZel>kF+DKMVI<#l4+LCAUoXlh%F3sau=p$d5#d|(Gjrm1en-ciUU0dLl^W|TO zpXO7dEzOQ=`6XF7-tuUjTR?hYiSXgC%wl@30)OV2f=vMS7zP!dn^&68Q=K@-2|)^^ z-%+f}*Nz(HjC)+*&oZ5NBA$=-Wje4B|2d~XpjVEB59a*x+S?ZJ#qTsfubvA^blUJs z+b{bA!n-~-g-?HL4(uK3(GULT_$7RQufuA91ISV0hq-=|z<`+qux5GDzZl@xe#ZV2 zgZ8LktxpZ)8JG(Vg7ZhaFer~Jj&-?SJ$JG3L8r7q2tg!2vx#n^8;#HAhAjbr2sc-R zH!SpVP&6xtw*Wg($l*I{LOnOBt$B7046J}77bqY@FRvvg%<;17OWpMK31!Q!0Yc7r z%UR(m$z4f)DU$3$pW|<>)>!pqfRnpT4 z)Jazd;?_mJ_sUm%E%wV0L_+u_d_UwnBi&yT19ahYa%&~HE}~z`U{y{CIdT!iX9C)~ zj(8-wzid1|F}TrRJgoU{*pi4IAmDX?yWRg@52v;X<;Lz8*qD&7OLQ94Ta(N>Nj#=O zcxmMZu(6;Fc68m+B7l@@>118YI#S1(+A)fL^I5Z+sic12=YXGR67#A#Y~qjb6&@k7V(^-y_#~? zn=KJ%>m0%$O%UJ+K>CZ^bvz@LGdv7 zGRLoN;#|U%r;K zejX}xY81*y9K&p{kmeHp49&SL0yw!Rn0RU{93xEx<&@|e^bg#{lD=%d7<^bh{Ja`} z4j7&nTZnD2o@^O7yRZu!Y4Y1Jc-xg|D*(**f%jcLgMYYc1`A6nXhRC#N&r#=O$&JH zL0KM4pj0LsEJR+V)q@5I5c#aL*1c3;gV|4ga~AvVTtfWha}0VJHn8nwK8b53G2ScX zCk;BV0Mzo?SD3%p{zgI{PEP#s%(14CeB_oGsiV_vG5m5+0U!P9EbcorFl}kscEc~5 zez`ONKJt|r{LSa5(I4cW@z`HPzpUjUp?9I571J;5PaqK#Q!GQ%FGULiZICbgGXA(` zir}S*V!uwxFJ<2veUIe?AD6#-CO87{9}FN-ChX*djlx7%s?UjPOK*+8B;dn0y?e5R z4>iUrVcHz6Jmz)<$vi74XsajlbFy;sa&$SYYSFa?NV;rY+cH-u(=aO|ZBblTo|fXd z$W)$N4q=t&bjSrHIem1nQgSXUTFyC&=9^n_vz#s0?%wV1o2V8R=^7$>GZFktf-wMS zybn+#Awi=D)Ci?Xzu*!|L_Lyu&GW`U4?PfD^`dUpmM{SRlf03>*@osY5LbSjD$%wQ z`bfaDj%*o%zA&Arnnrdw#6y|`FuzFno6n~!KY_~S_2zPGMXEGgu6dPaxh=rhx>}gg zqw8uxn=TTl^7*}oDt!Fwa~Sxi+K0j5iHr2^#+Q;Ad~kk!WEl#UrC2NB$azT-`F|+V zkR+lMD9P0&ofq^Wp`*}^0^|4$mi+Rb2M4(L${AFKE%}<|=KQXqw<=%Hez~|r_|TVU zaKUG$Fuw@2J>&5@hTB1xM&IND6@ve|#4m$SA>QBSN?oS^POhU<@(KwFzvLcI{0eV$ zDU$m7evT;dOZjXd$tR?`QPMt2Y?0bhgbOF8EeW5lD*WNz-O0xcIOQg>B}lh0QKjf| z8gta>y=vwbikBl!6{zrvlKs<-*B|;QpR~3qk1f%xayuBjhVm_&kS-#H^1w zkTdYeXy;RN@KuAiA=w&=wOq(qtDt5xFlb9QNXf}xKens~TMzK~HywnYJUlW_UPVGU zuhZNj;r*A-;NmNq!H?Fv%gj0JmTR*Her

*ll^)dmtYGurc#?QdgC#xRdi16 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 WFRR^F*Zw_@0ctAR%1w&4G5-h2UO5~9 literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.mssql.png b/pandora_console/images/discovery/pandorafms.mssql.png new file mode 100644 index 0000000000000000000000000000000000000000..3556b485728698b79327db8971462c12589f1246 GIT binary patch literal 19898 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 Qe;l4skX4qck}~=JZ`F>))&Kwi literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.ovh.png b/pandora_console/images/discovery/pandorafms.ovh.png new file mode 100644 index 0000000000000000000000000000000000000000..69eddb9a31610ff374fb5e76e8e3ac5d9c8267d6 GIT binary patch literal 4361 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 CT5|XR literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.postgresql.png b/pandora_console/images/discovery/pandorafms.postgresql.png new file mode 100644 index 0000000000000000000000000000000000000000..e07c3b8871accb2da6fa1f0e64798d6af9a692b7 GIT binary patch literal 16440 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 literal 0 HcmV?d00001 diff --git a/pandora_console/images/discovery/pandorafms.xenserver.png b/pandora_console/images/discovery/pandorafms.xenserver.png new file mode 100644 index 0000000000000000000000000000000000000000..0f9fd893fa5301db28e1a448012bed09a9172fcb GIT binary patch literal 8732 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 literal 0 HcmV?d00001 From 28d230433abf35554ed21f3f6dce78e797054781 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 5 Dec 2023 12:40:21 +0100 Subject: [PATCH 119/157] upload image --- pandora_console/images/ent_icon.png | Bin 0 -> 34891 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pandora_console/images/ent_icon.png diff --git a/pandora_console/images/ent_icon.png b/pandora_console/images/ent_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..62dc5d22d780d888592a6125a17495648bdaaad3 GIT binary patch literal 34891 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 Aw*UYD literal 0 HcmV?d00001 From 21ea0f5196cab6e2de910f8e829ebca94c7c642c Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Tue, 5 Dec 2023 12:53:32 +0100 Subject: [PATCH 120/157] #11494 Fix MTRS --- pandora_console/include/functions_modules.php | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 13813d479c..ea776d6fe3 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4859,13 +4859,33 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule if ($events_time !== false && count($events_time) > 0) { $failed_event = []; $normal_event = []; - foreach ($events_time as $event) { - if ($event['event_type'] === 'going_up_critical') { + $events_time = array_reverse($events_time); + $mtrs_events = []; + foreach ($events_time as $key => $event) { + if ($event['event_type'] === 'going_up_critical' || $event['event_type'] === 'going_down_critical') { $failed_event[] = $event['utimestamp']; + $mtrs_events[]['failed_event'] = $event['utimestamp']; } - if ($event['event_type'] === 'going_down_normal') { + if ($event['event_type'] === 'going_up_normal' + || $event['event_type'] === 'going_down_normal' + || $event['event_type'] === 'going_up_warning' + || $event['event_type'] === 'going_down_warning' + ) { $normal_event[] = $event['utimestamp']; + $mtrs_events[]['normal_event'] = $event['utimestamp']; + } + } + + $process_mtrs_events = []; + + if (empty($mtrs_events) === false) { + $last_event_key = ''; + foreach ($mtrs_events as $key => $val) { + if (key($val) !== $last_event_key) { + $last_event_key = key($val); + $process_mtrs_events[] = $val; + } } } @@ -4874,28 +4894,21 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $mtrs_array[] = ($current_time - $failed_event[0]); } else if (empty($failed_event) === true) { $mtrs_array[] = 0; - } else if (count($normal_event) >= count($failed_event)) { - foreach ($normal_event as $key => $value) { - if (isset($failed_event[$key]) === false) { - $failed_event[$key] = end($failed_event); - } - - if (($failed_event[$key] - $normal_event[$key]) < 0) { - $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); - } else { - $mtrs_array[] = ($failed_event[$key] - $normal_event[$key]); - } - } } else { - foreach ($normal_event as $key => $value) { - if (($failed_event[$key] - $normal_event[$key]) < 0) { - $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); - } else { - $mtrs_array[] = ($failed_event[$key] - $normal_event[$key]); + $last_value = ''; + foreach ($process_mtrs_events as $key => $val) { + $current_value = $val[key($val)]; + if ($last_value !== '') { + $mtrs_array[] = ($current_value - $last_value); } + + $last_value = $current_value; } - $mtrs_array[] = ($current_time - end($failed_event)); + $last_mtrs_event = key(end($process_mtrs_events)); + if ($last_mtrs_event === 'failed_event') { + $mtrs_array[] = ($current_time - $last_value); + } } $mtbf_array = []; @@ -4903,7 +4916,7 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule if (!empty($failed_event) === true) { if (count($failed_event) > 1) { for ($i = 1; $i <= array_key_last($failed_event); $i++) { - $mtbf_array[] = ($failed_event[($i - 1)] - $failed_event[$i]); + $mtbf_array[] = ($failed_event[$i] - ($failed_event[($i - 1)])); } } else { $mtbf_array[] = 0; From 75720df6fa05b95b8b8e08812d5e64bfa9ec8afb Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 5 Dec 2023 13:23:37 +0100 Subject: [PATCH 121/157] #12176 fixed empty news board --- pandora_console/include/lib/TacticalView/elements/NewsBoard.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_console/include/lib/TacticalView/elements/NewsBoard.php b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php index 3be2dd685f..a2a2b7faba 100644 --- a/pandora_console/include/lib/TacticalView/elements/NewsBoard.php +++ b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php @@ -117,6 +117,8 @@ class NewsBoard extends Element $output .= '

X|J&okXt#($InR?v9h4=FP9s2qOTHyFS`iGLIA}plVKIoSLHa$so-3!R`RNIvT6Z< zXO@{wm=SgeSHVsNzoZKI{B`sA;r)Zw0HZB1J<cr3TiDt_>5TctaqVpE|)nUO=uL$T#?w(Ors;gHiG@W(K@mr0$r8ed0<++6| zyXtVl*)nIaT(W{8Yn39WT&_IVAT6t{Zd-7s1FBqm^bKr_W-XoCf*{LT^lFo(W7~Zy zIS>F~@9v3yRngl4T+S~#0|2O=z0sX%IwK^GjeLZT)>>U?U=MZO1Sd`K*Bru|IZb`_ z%$o#*wrq1-i3$zU**ewvuOnMJ=fL|W9Pv!0kR!%T$9075c@QV6gP*_sLjAtL+(MPe zX=r1%KbGYJ1S_wU+U|YZmME)EslKk;roVFzciy{%&;IjVm|d;S?t}v~m~x5z!|Gx9 zpn;s7<*C@Tj+_w=b%^i1fGukEhG{vET>~Vxz^NH)C-~GymMNb#0gXtsv4dY8oT~6Q zpPvrAx&|4XPDH<)U##%KtETbZ%ce26K%JlQ`p*M%aUTf&{t(suVqH)(^!bUu`})zp zqMrp{@!9ns^Y*np@0zqGA_|~dtb*{hZ5sp`G5F`E#nnj;_uyr6K9cszRS$@xY)>NK zgteu6fXKb3g1h^B7e3Bf1*nX_F8OUVy4=d|a(=ApLR>FL?g?c}36e`-el=2#zrJy~ zlnaJ(0a30_iN6j+y6C`qSOHwAuD&@sV9LqM1!bkwu+hFflLsrJHvn{f=)jVxB0!CF zK1+10ex@jPwB$S9<}4DxK!uY0WT19Dgz#WOi9W==v%D6%2H@oM0FVb9&UfY!0Hi#l z9Ev~U=y_=XL{8AJD_h34h#%;#2Vn+Ve&#>qNktH6{D^@0rTT*h7k+LUGxL=Rz%=mJ z+cK=+Ay<~8;lHN8q;+IDWo_0jPqs&4Cwhdp5<(l;r}>-%sR+)PU(&`lzXb55 zz4N&7&ZX=N0=2JsUSX|4u73DuiJgi4GHhLTq79(%yJ~@hw}bOa$5j+x zrdBV5%~)|n-wssn#Iz;g<_Ywcdk@n$ZrD8m@yeD?-BtVL5wB8moP!pib(U zi~6N}&JV%T-rbY86L3BV`?*t2I%fe|DfWcPOkVE+ zxr8hC&Sz~|gNqp4dUpu-A*D+g)Ux1xMS>Wv?>u+LOaYGt=K%X-^ao!jfG83bS&R#` z(eFt;69V8tP6F`r)6FmE76})8W-7cJRkFVfD5MVZDCyUeUrx_gc+cmi@po6uV0Ll% zXFLQ$;l9NFl0x_D0>DnW@mZ=Xx!|=3eVJog4)B9hNe=M?G>CddDhhtd{U^%^ZE%v- z%ks|)ss56j95YC?i2a&vq+064Hm?)emV`b5dj=IQ`O(Fb)(n0QPKTDk~>?LWnKDu4GASS1aZj;u1!y)$ zMl3$ov8S%vbdmSVvbW`wxqz$!fcZsSO~Bg-Zd!JU8lFkeqjJ+Tr$|IF5x3TezEJ`C zh6FKn9UxIcCb#M#>2x($`3kPapL&ln2MTGf+Ls;L7sYFC>&ccpM2p&uw$x!=+&UHG zC-Pt^Kq)NsfscN54)6T%!#FfknX~1&tvaPy^xTSy1z>Y^N~w)D2ZBp=bKrPT5&rh_ zX-v&g(U#=5vN?*gv)T*O>-s2X?&B;maVg;Wv1}dW$3yf>@^Mb|4H4`MzX|?CQKHvG z9n~a&^7k%&dF^eB_}a}2$feSKIuZPGYL@U04~Sw(oq4SOaRkq7fY6Kh$s{~9EhKy$8c2~@XXvo^hZ zXzHHBs9hHzq#iJiZ91J$wp>n-Qi`s)ZkHvjwxmIRu1<+p+e%BWj%7^CflB&VH!F9; za=}Y3FfB#;ZMIFE=avg6tBTwu1YAgjJ`>4KHE!Kvr0r*Sc(@B#S@!B_SxAksxt=Xb zAy>+!lw9M2Y(2mocI@<135KqLJ_?YtdG**JOD(0=zAYW=4Ib{Kjmd9;;+c6r0E?M= z010TNKtrgAaQSufc-tk1aR0+G_>thO1Uxm^YgBV!5%8YNrZBtEw0+xFGPwe@-u#k?aBymXcYfqyeEjQk=nq!#j7P4)>uPZ9^GNDV z37zSefj@*)rjsjy-tJ*lig|ONFWNzD6Y0aT-z3DAN1u#+b+W5~%UvQN3R@D`_-dlXTX#MVsT51Li2yk@c+AkYOgmEezNN zKU;Q^JaaTBge^-e4wi9qs|Oa{O3F3Ouq!`Z97FSv0grV0lWU~-OTwMWa7=bCRW zpvpzT);V7%!PUOq6N^Oj4gjC7CwtO?RBjm~07U5wPQCOlXOw~FoD{-!%3sb4HB)yu z8EZIoO+1SwW}8A+O+J88wNiS>zTJNwn+KTwx60o z7WDz(nwu8z#`hk?9S8c2?Ku*7T3eBF?_|ib-1ep1%)Is9L<#U(*InMVDCPAB^(Vj= z`oq~WVl(zNagTgq9W=!I8iOA3uZt^5s1QYFmjdG?9+huCujVp`cTn+tD@9+G zPo;cT%gfl73xK%}dzVF11re3a;QJwCULXGOG3x1Go{6fqVoVNyo{kiRW`%+;$UZpyG@V0xvl$ zoy;flyj0*3<*QW|#JZ9<&vYfTXbfVM9Ed!gu_9Rx0W!Ev3D#5p@ek4QKca2x!g+5U&6G?hpHT!+Q?mhC7#%-(Hca%lk69vJ$}6 z^{nkcvX15}0cj2_YkCU|OPLSPR5)c<50Bi@tGA&HVM_^6T@>JN4*O1BgM$$SUjRD? zoL`Z2&ei+;Sv2A?2J0zomd^pph;N3lpVXznXI#`J04=XKiF(8NWi4gr7KhvR_tEbo zv2$*6qO@AF9{lqA2m1KkcOS&Hw=J&9Gag^$7rhbpZJ{qk=wIZjhFEime(79t&$+)6 z*7SjV^v~2U8Nf$xlPiSb=xI_}ak7m4lJyOf458oVOeZ+QZ{ZZ)n<_ zG)ur+?mbN3LUR^h;~yC1GS9+L$mHpBbf78eP|~fZ&aHN8Sr)ci3GIe072kZ%-mF-P zppJIxvZ6AqzPVKyi;unmlCBg`S%H`?vjR9v59@|%erzYfapY) zo06bOd@JLZ&H<0w*~8OL8^iO?+>D?3iE-@M+C$HkgPN73wcwXkMY!%?7V*}L4&mTb zIy9{08RuLA5`U5RE9nP3cn{mh97j~@SqXBeUMb+OYkE06`2)BZocOx&8Gz&xy<7Lk zkxr!!U|-ro-P7ANieGomy~jCht&2Or>qbwWgD$HJI5gn1b?L&Wz0R;~I|V|WDjq+! zECp&BY)4S;A#nh1Y50av4`KFme5{Ap{Ni@J@_AdaWjuYnE|xy9iLr;g%jr)|RXo;HrB{@56{j63v1_0s*|^3r|FYP|;ha;Z=F?6q_F zvr7+SW}cXM)t>Q`lJi|tM#fgLwl5FSaum?;*(8?)7p@?|x(E;wSxt_X+!(8~Uvlu{ z47=z^0De`>Y1T@X)QAh#k1eS_|EH>=*X-Rhc?jh+OdzmaaL?zuZt1!tH>c-vz`T3P4%bFmM;4r203o5Q00cV;KF(}OaP=4A5=1;1K~_d z1S}2+GjoLR{%{G`+_ZpO?^(hR9~j`!bcKpBt+!=-hezHMG{Kp#)r2n|gS#Ur&77?epZar?Y5nDWbwuE4{P6+3pZb;sytC1V>fc+i%MhxABq;I<|p)!@va z!P>QD0uDW&G!KwKA?`g71D*jE(*a%sy^)^7S*LHpTVB2sPnsO9o7n1mhKK4J@#{-8e%*@wcHVgHzCPM zKa@dMhDdMy046|(3#(O!DUl;x|m7-Z> z&U3VqXGxb5ZI?R3=w0Fu0C?(a@9B+?VWQ{Ur<}vtp(g`kK){`%le0^5=12C7v2%@` zv7C2G2VY$$4IU_VzH-1NG&=eiz)%=#cuI^M`N=Q^SdyRu@m--13mN(fxiO%SlxZNd zwrm-O;3PEC?UZ?`JtILZx8?<#RfvF|1126hg8%Z89eD23()WJ4fX88G<%dbb1UhXr zt0|w$7M2LJ3xw&pIvBd~2TS;uAN6tXLjxR~t}r!MVRnJgALRKp?~)4a#g)8grKVVS zp7Ta~z?N}`om+c2d3z6!-qpj8KXwdfoj!&id(+2 z4v(%hr8=Fd6Bskaty#43_XE}$@ zIfql3DBt}y5pF^&r;ZFhW+$xbu0y&70=y=f>Qc;F{~;`2xT z!F5=@XI#>AG!#~PA-b1DW-T|igJ0^0*(U>H!Ya(r@Cv@@S3Fp+i(^!l+!u&@8vac` z?vdEFmJT@Y?>uV+#IGL8*|J1;e{Tb4GTQA+eH+$`EkV>L;Ex6a{NW83O!l$*n5|2_ z<=JB+NA$ULrW+19%*Cy22Gby0q`w$H8PrT}U1kh?BLqQgYvIi5Kk zIIl~DZ3Rn~P9@!{vtGZy*X!Zs4)|LaK6cPd#_)#@kUjyt$jl@b;~6tQAChGCZ<(cL zKB1MZ!BwM1S5=Nv#{FMx9@!aTp(Sp?uSr z!=_QrL)fOa9&Fhr)2b_Vu+p$}2d65$@A7GU;v2J=Uo;6t2eCTOIJ4zWh}r8`^{pN* z?Y(555Cg0ZGdAKHB2a+Yz5x6IlzFTA$%Ksv9E{1Dq@|4stU}=9ZM+_A>BplFRTaH% z@1DuSC}S(W?z)3#x!1$U)2T$?b%9{Hx^%JKu>4LqTed>IWu##PkFLQKI`CcTN>N+h zN}|u@)LD%cBa03lcmCUeZ97}K0(>i#@KhJf zwOpNsnbhwx8J@FKt}Pq3RJQD?3_bI2tt#j;&BMA0rTV#*99eFyqLh+FXRT^<(Ir=> ztE{edIA7kpw#Zf@4b^1k$VS#PuG1RrPQt-40$QsPR)WiGyv2n&D07r zpH9_@S0*-SqH8nTh2fy7QD~pl%zzM-N>tC1M@fU^J-AoDj`4vF*6~KK={FZ^)Jp}eB}%d&sNzPalO^cqFGK_jrv_@@tt!+tv*?D zmaFfEEt_(VS6j|4R`|?6&*A@h|3lb&$5Qju{@=JAx_5L!28n)+x4_l5iG+b7v89Yu)QY#a zCFy!=*p@^%P!V1|sIY(k#S<`6cDG5P%(|B6`pD?g2T%M(G zNe)z**|xJ@f6u8SJ@+Yqo*BpIbRMZb6|-55X~V8_Y&xkr)>27eEp&-fXo|O`OG!u7 zMj)LLg>Gj&jk9aI9a5gw>G-jwWhIF184@?lThDQLB}Gi7zkY+35MqR_Q|Tb=Szk`z(3NI6Mj5tFS9&Yj>=I;j33$33wGJ?NtS0|q z+G?h!pSS-RJ%^7u;Blt+-6kRy!9ii1?%xNBO?=y0_hC%59&7W`N`bPX^{bu9jEa!R^%;iYv7 z>FnR$|LYF8z&Y%Uxx=9JTrx)3(23`0+W3^{howvDlivZ#(rH%4pl8ZML7y(^NZL|@ zA{oSVv8Ck8$z{xv<3pl2>N7gxaPAr7`0anU1CKu?UHxg>LS$`m8g?e%0_897|E93EZjcFF5vm#!F7*5P^^wv6ZC>k*$}^mZVmPm{jx zWv+F8j-He5F;QC~~a%8gZjU~q^dP`qYb>%hZ zHSW)@v)}mL(GiRT?m5nJn;fzoc}Gl~3@8k0Lr2T`E>m9)>Q2bX3^JZB0Uso2l9A1c zyl7U91wtU?b*ym;@83qsgK>(}!zdFSN45-tWFy3RXfr7q61J<$;uZ}amTS6nOHGs) z?oXI~q}YyN%bHhJIox^Q0AIdg9$Pj!oPO#kMtjJDUYRHJ^|h6BxvsBywSiowW16n~ zb)F6o+UiN!CApg4hAoecEdgLq0oUHPh_`*<5U#j>0ZV;RF+AhqISS8tvmcXSdZo{J zSaql`Jm(0)ozuS$BxHn1r1TkY^vx2Whx*cXOpl;z1naU-gQ|z5EpVD=v`@XLk_J1m z-?#M9f0ivth4J8o<#^yk6e0uGrxIRhC0r3laBt_sOp+RS?2Ag3~6r04MLr;g(dFW!OE zPaUm!b~AdXR9ZzCw*GQ?qyfN!*9cuW!ghC72bdOG%o$xEanzSbqy|k#??xV zz^~#Nw4bKsJmXPj1mp6#4ZjVO^ao1+i1tk#(@!(YI{p~?%g|6XCQO8k^c4b>}R4LNJrmQ*vnyCQng-rbWoq8o#_B@fcRm z4O@z`VMd3Q1|P!)5M6=$um;NMhC+FcW|#n`q)QiPK&EaR@0@PAHnr&#=>5kIKI$BP zx=R4k800%d06JDNV;9A0HGo;@{-ugZKvSnAj7V0G&>Y*EmuPOBFo-PujgD{h%hs@A`N-=Wpx3&0)h`!hY}oS1*|I+%Tz%s_c7J**eU}FcK8I(TKVBdn z(nd$*f%9rT<4B)j?j?C*N%yHudX|;WC|S?8ian%~jeaoMBIqj{U9%5TtTJKCM(blw zL_RnOa%3F})(Ca;woC)3wPH&U4ioUI>)$o;akO9uQ6|%JCzvI#Hqb0(w&A@tz1so+ zEh~q&h6VH+wp^ht^^?~nkXdfv(UwX<0a|1X!?#N?V%^YEp5+9kc68y@79b6yQ?3nN zqjxj^sjt1eH$LXh?m2wK!99^=FY35Uj7fu8o;`{?u3Un;CD;gTU8LbX$HdHa3TS|@ zT|E$JT^ci=X$n75C)!p61|D?C{59+3C}l~Y=KzG+JI3|mYe2_=Et9sOiJ_RD#E9yW zLMO=V)g=De#L=K!pvv+C%& z+HU&1be)rvv^7&F*9NYqL3Ihl=k&?xuwlz1V@m+|;r#<#@YyL`wJ(0LtpQ-A+=M~_ zT%$&#-B{i;o<8Z^zWAuhXB_DxoRm9NG1w@`_WhPf$^D9Pf>zY9hv=8|@6zZw0@1H;}-9a6tqG|Z!-yk=1M5dKY#Gfc>!UY1RvSFRlq6ltz9*b2X2 zAqL!3o^@{{ATfVnPu1T#?(qCG$MO5G+=cP6_IFQKE17}tkg|taJ;?#=E-NX+v}d{X zSCUR7TTabY`0&;B#|!R%n7dttc$=YySuP|BS%`rSR{o4@{>hW7gGnDyq))fKip%{H zIT6S;X1cU|p5&1Mi{@^%CDX?w>l?9G3pNx%BOn9EvYwKs)_<+o(yQ_JgNn}Ew`X!1 z?UUhM@|KGWyUJN<`LGl3UD9gU&C1)brONA}3A{O#zzGSj8@$rgMW0Ii_0Y7B zKIgy6ptb0A03`ErWm=aWY+gCJQdce0s%PmT^-K8e+cSYdMV}_nJBc7(vvtk>R3}OY z9c!nurfFQm`HtVooDNBM?n>E)9HTiZ!^ArVpQaw^pk~q>V_U`_yoTBh8>k+ugbk_Pw#otYQ!S!K%&4y>ekZP>D$mTSwK?^?v)T`?nq9{6XBL9+{a;n|YUwAo?# z=ZeHf7+CfSpK&BKQV$9XCv1BcbWQ2&&z?vPf?<3g;_q$v1!S)?k>Hc|U&$(s>>q?J z13|E*&nIEygs%@-oJ&|l>Fk3>KgRh%A3gR6ZfnApxVj>|)dxL*jW3o1Y}+uEmGs1J zPIhj$Oc!|;4%Fq=1b7Kg=F)~OkAN+^Mo=Y?ol~R)t~C(P1r$<8omV>Mbh7lw>07Bk zsH0Vu%d_h0yj+>ZTbJqc+`}RRsgfQ#Pdi>x_l7-_i$r)gfQtxqpV;WH#lJAh>q`sN z>gYlb6M6vFlA2eMZwi!2@QV0DgDwJiz-Z9O22qkl4H|-_S2~+^eAv?F8-HWGww0d| zY|LTuwmr6&&|caml*K*lK?lcFe80qOW1_3ew4u)FIp77)*o=`8dpng*!vb~-gm<)wr$vQcw0X0v`skelu^|%c`Evt(2YqHp7u3KzoGkr zM8qkVnHo)we) z8!H{GftpEc@Je+Kym-b~wy}XD(t*+?vwcy%2|vgM(&NFFDQ_Q@kpC?SVdLai%HhEt za}D=EXdmzg*NK6pV*`lUQifqc9g5pKNa!K4Li}nR;ZZw#_=TU`Qps9N;{2H8InwJ>!vG)K&5na>$qaXPg8!56?Kc(4O=ePZ}IfLOer4$H2^mb~(|f zggk2nFlWoeuC>ic%Y=*Xg$CtaB0GGV+Uvo##2T?B5e^dETly8Q-+#%3oKOYq-6@<8 zq}aq-RnU{OR$ZNE?NYJw*K3k?P5PEk{8P)051H;3bzCh&%q~EG^3-DTg5D zQ%PL=p^YOL5^@+6LdfxanUkD(J(jj4$%~nbna4O;D))jTY{N+6mmrUABmyErA`i~R zwhA)_@ZdpWtxlYwm9ZrQ66YNL?bA2o(Yr=qr7o)oCEB*t1AVS(EV|Nag$DmQ{o80P zopO5WI=R4Q!LGfwjPY_vAv z8D#i6gx%gK>- ztpG#nool~N8@5~pTjl_~6}9OgM)T2ix`1VCnXAj{gmrVeM1Hx5(lTC2mgFyw`leZS z)%>i0&`R3jEt$F07VKD#BvV@;*8_lCE}X2ED(oYo-y`5~=yn~?bj1<3?pW(>O>q#8 zV1dhJ9{0LokYQeO5a3RqOXPqP1{PyBSAYtHrG8mo%v`&;`VjcKuzgi^tSaEM1bPSgj~%3QW1K{1ueL!+8f)`eTDO@MJADmO(8$xZ zn4&4wiPHMu#Nfesn!8xDP->IPlU8!g3I>&xdn9bhn5PkZ`EfRtD`b;650j3phX5TB zvUz+LSJcw>Hn#>cFDK+XN?Y$7@R*ZE@Drzv`Rg?B)mxo3261HJWo0q2RY)b$?e(ETC{QQvYQ9P}94#R|tU+D?)3YUfF z82)?}pK-W)Yn0!X>QuQy+)nIL$&le&+7oglQ9t9dcN5k$bOF-Ng6$IdN?Y=nA#EA? z5aN=Si~S2FEmwMpd*j$1LVI$eo)g0rbD-nYmJWcsx+3=n;tOt^G|rHz>m+MeI$bA+ z6T3_dTfEx%NE~UUHh^AgyR5%q%OhY*E2>&*pOHf*V+Y(u2-^04)D*QFJZVe0FZ%v`{bOS;TzONnN~mU-UGvE|YL_|gsYs8}cPlT7g$PtZE& z$&N`(w1khkSPHM~87J%6bMPx!ti9x>`>+W3WnU0_(KNyfa$?)Whg4)=nAjy=H%ABv z8LB@KR*4aVY`50epSftu#yudZ7w5?_>G-oH5pJyrzjOa#I)HAwdP>Q{AtfASC5@?a z6S^ggXYsOd+j3J5=(pt!lQwKw&dV|x7T^w(N~e-8E0kEXOfp$K zbUiBw5{dP379So&tZSFDkAs1yvjP?Qc~D(iQ#A2ki~dL1mgHwUdGJo=E_uJ2b7GqZ z2P-br1Nh}yK8Gmt0898u^$L`o945#_a$(x>2fOzUFu63 zYqdhIh;-QkX4RL+Tx#2DW^EB0R+qN=8@6mux8A*kn}4u`=<~7j3C}qBzt{rA6^f7} z%GAo~Dm~+2`>$Lb;s4}g8~P~uj7m*o-MUPCJRs?#B3-(2llFyV58V_&7) zBl{sr_=Zj_$dzk7$r?+rrRd9DD))G^B@qr2;dcfVZr*?KBw*tZYmz&c2P400UJj$> zCUCp1py>K-c(qi&1j@VUw_(dvr&Y711p1|*L|?b9Cg_yolLPTxW#@R7@=EzK&k8Eq zbg;@w0h-P$1uObm^X;NrX{E}dYm4alXs*W1FVUfj=rsV{6@vo}Cd7Q0tAhYJ+ZYDp zWCcU+oA&e+c~ZjP&yq>SoY>#o04*tSp_*LfhgKl$gC~ad6ejZmZwIljo`U{C9T#W% z5-EO*MYAnY`q8kZbMgHp4&+Ga!+g^5SVnp-lv@CfEywsumQ(mz5!;dFBGic+m>*0v6-Q;;+y;sM_e3R{N0)1`e&s29}mZKYU8_Rxtf zU9gg9vs3>bds`Av5%9JOxbnseCaei*3kPbzYUKfWK&#JnUI_@d>4%nbOTMPHcuM)! zWO7cwHeEJsY4cx}ElUlsk`^>f^jEsJqB*U!lx+nAr5kSPQwks~Lu(ym9j$lnMoGPL zc{y9@@|>KU<5>KxI&I043zY|;{@B6Z-IKQvxz_=7IDk{`&i%|&I>Q?W-#W>!(0F7_ zya%0Ov#Yn6F%Aeb$@Rz;b_@iLNN9NgU>S1Lm1CvEVBwteI}==dx5V+D{Cegt&hYs> zo@M1d+hY4fXgCmR1RFVJ3vqq4Y?&C2gAJ)R55~kZgA~A12xv$!A%t=l^cQVnI}*Gu zF5U~oU^9IB2nahx__nhQHjQ(@-S-c0_k#oIBtfSJ%NAhPK-#Jw??H3xlmzx&R{<S1L3^cKssg1-c z2d1yLq|# z`i6Irt@AW+w`i#Xt?Zv1{n0C9nE!u4Zwz1pGO*00}!!pKLs8l5(At8j2N>b@T zsZ@{qI4Ae~$k-7(cJ7GGbL!rDs7}P$zyIL=izTjpKcY~855g2%s#dbSKp)j{I;R-h!BW_CteMN9e=8P2+yqR`SpOC~g+ zfs94+mYW$PyeM4;0+=x(!UfxhUD;D1@0QHgh;2!im9Z-yB|Sq{ABL`Mc=FRaCDYcQ zW0|LmceS@uQlq`|9an=s`##2p?-i?!FJQ6dM$t^)@g%38o6l_RB+8FCea9*2Nh{I% zeroh3ezU32zMyKURwYr;?@5z-`8*1EZ=t{;=(qFPe>lvbBNZrlKe^O#uGiFxj zVw!q2Pp`HjGtGb)(!O4K^0tQQypnS?LKnA@Qx2!xYsZr*IZ1u(l#S8=03ZNKL_t(- zTRqaA)#3HkjtPs4b+T-J17LK=`=8M?j9&rp3D_iajKc%6)eGxI=yEGoNL&zdC{3lZ zBkMIv<`bI06!df}#BCeeknFcQ92J|1rHTh5PW7aYZQJq}X4e=M4W-<9`yJ`(ZU2N= z8D~e!C08i#gUxNZ3t`s|!n3bfgiR&#YKd&=*%j~j(W4Xm-bbIn?O)$OW9oRxdyYky z4I%j6wlJ>`o?dSYS;?MS+6pXfI+IvF@YonP-nNR#q-*AFdU(H@Ku+;y*8OJ&tJyNfC; zV{j$*S+|#mVG;%^7?UB`-s7~KI8fQxqg10^%^{UXXB# zdix0Y5D|ZKno77k!J?L^NGq**#t-|u^tG40dT_ZeptWi2C-Y4|^BJTsK`$K+jv3I4;_k7mx zxbAbj%cZAme2mroE_|1P_B&3dT$^R>mpf~Im+bbLvRc~uypKtHdb)?5R_ry%^Np>X zo)N9t*ovNEESc6B{H{rZzkc8YD;{64+{*G6kIPuOp@HU7u-mhtZxx`%q3magr|Gt9 zx~(oNJI69_yQbUfva(ZQxqvP&VfCql2y%xQnNOQa`5p(V$)l2AlF_y{PI*bE?z63H z?Y6kEljrHxsie~$d+m97a-p>jo9DF&bTRYnDCsK6u+b-fqlFi|8K!ly5 z&YM8mebj)u++`ODVivg>q})iM0Hn^tl6gA<%wXRNL>);1Wge$fsrF3^@@dC9I3?tEYacO4psuTOUx zwJWvyyB5C_>idxscl$qP|Bh$lOWm77aE6GYBNbOmIBio^6_iDk?s**Uw(%C0?x&>N zbFj$>e-5(M}e1LwS>KIy%amP4O!HjJ*{mt_>B)A#Yg_`WM->Q z3nSpN3rBd#l}mW#^S0wv&)bG)U$KbAh3>T|t$qOLI6BkTJ>OCdkA{Imk4|vYSJrXU zUF*2{?sYu)jS0r#T^M#;?zv!u-+0p{_?G8y+j1;FbL%R8`QIPG$#p%a`{O@f32Np1 zX^1pZF#J=e5g~&+439?Pp6kZ#P+`BP08!)O9`)1d0)SZdAICc zZeIG<`+sk7gy%5ui=^($-MN^uJYs}rL~;U?ZF%ab(auYkK6|0U?pxh_xk59lRz5LP zUg+y(o7e4?6(PZCE3lNwGV2G0Hn=4SAkz(b3lXWD@JR(T!%1A-A%TZfd7=;mAqt#8 ziEV`EG6+~25q|Jh7hwC6>E|XVX2zGkzJX8N-2PB%OOPn`7p?i2G{E5_4L)&X6@PPJ z4VUg2;rT0zxcWKU@S-c1@RDb5!=4M$iiKU#k^bp+b-#5V?Qm^6mSI^*)#D&qs6IF1)xxrE(2 zu%%eO;+wYN>Z_LUx!c#%{VTE682fC$3PREKS`5cJZGC@Sp7M8`#TbAny#!j@sqeq7 zV-V!B7_P=&Rx?=HDLoYYDB%$A1;}h`+tpjmINCx%acon%9exKXVoB78iXySX?T<_LqTTNsMfSZyf1)kb$V%z zWs*PbSW=JB>F~yewB6@)%%W4DmmC79^O7BXjz^z^)7NgF<2BUrDYe3m)tCz}Q&aF1Dom5Y-eg4WK_Fa1^F5WdN63o&A>3wpNw?1avb!d#e zfB6Ld{*LvSPk{j?2eXVNz}UV-xaw((c)>H4@S-c*zvo=Bi0w=MRyBR>5$}>S;Pt`V z0@mkHY&MoQ4S80{tK;=$eS>lD!(-g`^$pw}{=V|S7{^uNfCEWiJf>b${94=N7+0%k0 zKgf(X-Mn|@uY!_3;yf*9oVL!i{Bs%tJ!F+)h~qGnaL=*q*6S+0B+V>mqD+ z@*EU>Ub3a+B$Nij5WSmGXQ~2OFbV{>%)+8 z4->$5nrd}V1xqcn8LLRlj1y~&`yZX)u0tER>wz)uxNie@-ap2pPqeq7%^H`xcMx9s zoF#nci+A9=UbY=qT)ddsVf)vInU{a$_yoWF?~mZ~UtZ5>tfjZ<`YN=jCuV~3x*_3gFqx=y|;ByHwSPVRDLExTj7>MpvLZ#9<8SY_ZH zC)e@5JKpcU%wX!B9T-Mvhv@1fvwcC_S=y=fr>`9txjB|+8J469tzw&o5ZhY5mujBd ztU6C6m7EKkw;6T30qoVO4cJoI5ZP0a(RS7bTdi+V=H=HOdMy!d0Qm9_3D8R-&U`U^ z3UP$hxsHOm3Y~dYwlifq)VbGonM_prI&Fbv5*8_O$i3#q1bb@;x8sn=EjdACpF}`wW14oWGr)6A@i15NIm+%We zx(Ba%-nQ!M&a_xEGd_OvD&BR&5v-5XcN|3N=eGzT=J*z`^mX6*ajCax32xF@dUPgt zB_LbLV%;d1+SIlPVb|?u_uJqc#2<4FeT=rM?PS3|QupL`o0xJMGW^@zEHB`g0&DuZ zB6FOg{c=5+R2$k+J^fgQzP+~retG|OE2ZD-0fq%LH!E+JK_kPvyuf)p3Fh{RA|VFj?8s! z>Ta+grMFF9|N1Q~_r%6L5i!%cG>(XQ8gZ-5+M7pR^Inj_1s!B;NlHr#z%T#vi}1RC zx^t=(klNNPBEtHZ@p~VA0)O!F<5-_~QTFc2RDLZt56ck&PrYb_tDd%qX9XwdS(h*3 z>6b3x(%lQ#xt*}Mn6R3~(XsV56U)A>VA?Ta0OK)mVvX^QV-q~^jRyA~9^?K;$GG?5 z3BK~c7>AEcFm5!yr+-{tx_gBG=ZzQRmCxIj_5D<_Ja)3d|8c_+eCptuvM;w-df>1A zZ1uR*2wCkG)1*Z^lUZG}O5%OTwa&cdyd0fYfgHQ8R)q4-y*Iv`K&&-ej&Oq>gRb1Fu~X*Tk6`0Ic6e@tlMZiVjvTcD%r~zLc2j1 z6Mhz7Vx`2e<`lGcwtkq z{KB2<_*cL84IEpQ6&azi(ueM9#AzFsfLf72z%^CUD@fY0B5B9;CEm-#9!|l5Znywd?4m2H>PbrywNQ>fogRx*3Ish`dZnieZoJz5(EQd5ajYm1i$N@5a7r55mP>;2w zug|+2>dDt^Dmj*Y-t$lgcC)^4CFgCBJukcV(4`B6|4f9}rrezM*Cvf}9d8vVO#m?D zpq%<#oBC5I(Cs1PSXm2pf-c$N@2mGL@$H`m%bYrt_L~P;MJ8jPOkUoq{mlEoaWXe_ zA~-vOnqI-%xt;KyH(rd_ym$w^G%Z1w^w<*<{LjDf2o66!K_V)?L#Z*f^y*Au2>`ox z5T1I`2v5Ic0askSfJ-kN;o@B*T)1vovvYj4 zi8!BaSoV#}H-GE~=N)fzv$146#!NqX_$WSc=!WH5fE1WLFg~Qt5DvOoI{P@!sn}WKdN$3mJi}Nn z!e1qrrlWn1gJ+y;OeL>I{!z&D?6C5EwtDr3$dpz-8mC+*EmN|m)~A}D8isw>PuI6{ zT34SlS1JPl+_HE1$ko>#ddmp-IKWq>h*rE&qm!qm?R4i)TMz(KCpa3UCcsc7%H$JO zzQv=oMJ|sBYlp-Tb2XPGXDituL_=?(h@IzrE~KbKlYZmSSRyqGmdehIJaDK@%GtAk zrp7GdiaK;@X8J$ioozh~nlkd8qNO0<`(C~S-}-{>(8)TtrQ_POFMs~I6L|RXM%m5C z9NCOgrK_sP$(hFT*lL4gtBkKcG%+@7+6yd>fD5)!`?sC2`vSrR+ggWcX%Sc$5k@0m zDg6FW(=eLg>`WS9b)9i?y}{Z#b1?P8fz>$3~X+PM5rpFED& zzG4TidfH;up`K=3Zd)Y$)uOQtW!x52^O%8>2VDww+ zG?vmzbixAh&&ElxG1(tJRZt|yI}|zh?*zQDF}qjhTM3hVejm=1b#M+Ps$P-~^Vb$) z38pbK-nr56Cl1}PB2D)NTmhd`l;o!^1M+r;=qlw|9W^`pK0P}Apzl?*HCtvMO9*jXa=DA-i#Wy{DG27~6AEY1h zP`-8?AA4egAAa{?tc{U9UlnT@L-HdbjOP}XNd~dQOx$h-(qxkZ;Zk3$mXwi;RpwMY ziLrdc_w2+kyzW9QjLPF}+HuLu`0!^>;MYHN)VL{U7E8VDD{T)9#9Q?B-OKFOLcKyB zn{So1;}7XLI9|CE*WEH`yOZVs8_q&@%~J&hgPuUtR=jM2(BlcIt>g$Ht=ya@ESd2e z%y`%Sz02#}3tCKlbNjU9dPp0al|RIep}cQ1(j3dpOH*TM$*j#Q9ec_fbzCC)o`a#w ztf$&%TS=~z#5S*<^=|EPpEFWAw&x@BXXR?nNC}@t{dw1{ufMt-DYN$JHsF+(j=ef1 zr)mTM6UI%80DuNo%DCJ~P-%xliVu>gtELc735Gzw8j0wwBUwWq1#+pxZEI<6W zC-Kz>#{rY_xSM8N0>BTv@&a6a)l!DrnZ_~}>V66Hk3)v?`iyL>M86`)bC9>=l4F~# zM?v~xlG=udgs-(bj!UJN%qIw)F_IyY6{>d31QEv*NnJ5jMi{5|WRPtUmSFx^)9|kz zK8msFn&k^6epupN9#nDV&DPmkjVO zOkbXLp7du4@S3MvN}h93yD%la-XPSNl$;IwH>4e1*K<&G9jn)KSiJT;OiK27_FFrL z)Uomn036u2(lFtJ0N%@>YJ{LWDRCeOtTX#-GS^N+4PA#j$M!+(jv_{!jH{{QpGc8y z%Wkfi#lb3Li9{lxcmI<*qNIemQ=gf;eUG|D-q@|!2TL?nRg*|B6ybZ-^S0p!UX?%B z!_4lr$!t@fmT&^VV^1`=;p4~Qc0-xk+Sw(Stn{BNSlSWRs&~dOLs)m~EJnTJ3~2*6 zew+_juC6!u*iEZw%ovOPn{iz3zJT!7AKrs)i)Rm(5i&N2vEy_^<}Y>Rlrk*i(9z?P z^(He;{ZRU4MN-<56%!G(tC-1{+@8$E6<;J;s>*}@?%cx>%lQ4`gk{7oIBTqc*=#IB z^IvY5-ps&>2hwvrl7{dr%R_2BVH&+Ql{ksD!?VlEmjdynbC1_p;&0FASe`>zdMgJt z&&iYTOC_gjnl#jr8d6qDp4SWKxUbC9>$QW*r>$FZR)(}^_4GMseYVK4hruj3xpnqm zx7ccKWZerHm&~v) z1IWgo9P7925l6=&bU0h(N@#IfNwW5!-SXDfmpU3F3SHHD0jQOlv{K5M!-J@8tFh$A znDH~?3GO?vZ)H|4CTZGLhrVF+H2SAWL+sR_wN-;zoQ@%Bj^$~_vbHL*S;^DY=PaD6 z{Itnij%&IuU?d_AMW6 zn63qIOB-->Fa@r$R1?lHqD9 z8Y?()oc%%x<$at2OSToL#fyRXgMUOS!fLUMpYj3%dx1#(&z+ozZ_q5Y6P9hxPrUj9 zyyBb8&p^Q^mtMK-hqsaTqbC}C=ri)Wek~5M|41ZJZ&ylK3cD!*g9*g}Zf z+UFR;N`bsq82bCvd7|b?kL4pr8+`iUYUloNs^fBT0eHjr?#A*ZBb+T*5+^K4DUZ_G z_AH8j8kv-9Uw47zm1rGmrAl9|bPJ>C;MumA5u74qwY&C6o0P6LCmbj&$rD$qoM8t?%os^Z?zc`?RUH5}@{Hk9R>e>GyQh29)Q>*gV@#EtLjUsU2_d zlm>0h5%jKIQz`cxvXYLGsfWXl^F0mYS^$Ss>@7@e;a}Kp!W2rF1OHD`Kqe>Kagesf z5fJOd2TtW*(A!2;yHU9`CsVSGCE6z2VK`2*t%+%mxVDSqmZA2IQR471IQ&KpG6E$1 zj^`B4Nhbf)Z=%%hG+4@nuTwjjhFLgrD2mu-k~zm}nW6535J>Iob(wcdnmH#yQhMc6 z7V(qcxeH5+KAEho=x7=HMlEK>&3A9$?gwQ%e0m@`-x8JT37)Cf;p`m2Qri>z5eb(f z(AJh50JX&}e?VK4wetZ>=JvOrjvVja(obbv5)rPrc!Zz(A1+LNJi}PVdU8)nMyE2J zACAOq(XU6FeRT`#Ggi%W5|B-Lb#(Ph5OfP^y-Np_qMxC*`E~jeu}_ClGv&6&?QWS( zdERDV$xICc?`7bFcf5b4#^JnRrv9{iLjMinhPItPQm;SdxD;G1<&~U+T05xZ>AHO~ zb1ZWmUOFRK)`;lP^ODYzY^i>UXb-LL$qkXM5%nQ$m-2?-R_o(5o^lOy&mk$dy zuZgtdCH?$_C$m0g{MRp>jL&EUX!8DN^*CZFL^IN(a{$ZqU6Hyd=TVk#1KzOx zr}GcX+wR@K7w_u6Kx@`tKlX0-gt;EmPsP% zj9Z4|y;?g45u~im?qRs5Y=$e+xJaVZIzLd?Ox@$jX;a_t6XM-Dq`O5?a65G@L*7T5 zhJS7U-j#LaWY8nHHIiA2y!X|y`Cd@A^l9sqg15H4T0q;gz0}^&epsDzEbBJb`eAi$ zDwZVzTl21J$F($64w!98Yu2_(AnWtm;H!DZH64vpW^MAY_s(mwH5+QzQQK%8p=nm> ztbT`=}5Z*TBa|a=%(yP z=@P-o?C)5Mjtn|c*W8vYN}cJ|n#_3tOTGG)<%|6i&5xBeS>iZXGZKl5PN@)12%%(E zE^PzyP<^5Sfc(hdYhSSg-}Tb%7^z73kVtx~KgoKpz5VKgV|@13HORIbafs!AR`v8M zfxbSnIp$ozl7b!`*-v`Jc4c1B6!T<-l5^t7!S)!5KF_e6G>lIlT*G*>Ipb2NZHt6o zc-B7io_+0ZRbD%?;!2x9nRvg6^E|?y_)X zYGqcgB;(0>dPeAPSJJ2=Q?spPQ>ngf*E$VObE@C~03ZNKL_t(@EbDzd>#!`5P-|Ez z&mPZ`hBztHI5N|=Yst1Q*Mq?x>(m%|s86q+CvP1WTffh-=_~X4;nndRHtP&}cGYaK z4pGgqcCoqny5&`F_}2mc2y>gS<^^byMK&ttxB%MGv8Cencu_!2{Pb1@nOtq^xG+|! zIcN2M*?y>(`=kjslXYIAkVh6dPTo?hhNXIn2(m>Fs*dGkSuJXhb0Tc&D?%CDh?6@j zx%58>xOf-g%|Eak+n1!iPY#(a+2|5V%1B20_qjXPaB{sdG)Axtv^|ieaj`E@_Vo5nR8ZV-RWm`WvLNjB@xUXTnegEE-yFz0gR~y3Lwt|0^ zQi+$;WWD6Aew5^fwx{LhSo(59+tYHV9ZPSuVMtk@+|XqxPnZ6b_N3gA( z(;R!ArDs>kksO*|^7O5IDOqev-gwQc_T+UPd(BJsdX8dIe*eCe#~Q{v0o;`DRo9=& zA&C5pvXWdn9kcU?OpcNuQdBSMaF~Iej;&Hs4}gmvd6+n5=XzyAmPt^&mUd33*p77p zvQ;2XQSL4(T`W2DCABT(-8#m2C29L5I46fP?dPZD!-Z`oRx1H`>yPZgvo2pW{YXtRN6(-Rujb-c^YaF^G>}#_hl`mT$K)%IzM5be^)v<&WI&5 z9b@Kqt*!H?Q76EsN{YRJXemt-9<|r! zKBwAqXsZtE!$;|!hWTw^x-V`vGuvt+IiXNSP-G!v|LT+5NLi+X(_fGaZ$?F;72*Zy z?FT7}N10vitQog8#Jwb{e&mxJ?bq8V#D=UNl&0C(7ukm&p=t9d^e4)aOq~@hp`HWc z*d$~+);vr|6d7kTo`pVlX|im3Qhm!vUZTsAUi0GZ_>phf33(2}iM_ z(e@XaoXE7dH|vlkEI@Mq)(!}(wm54;O(YTLcwH4rsU=cNe#x%B`kt&;w(CkV@%`vRmVDW9x9RQvly8_eaC~5trYv7&hwmdsZ=bi)X z$$MCq?8wrg8PZFEi6Ik`3y5I$17FK=?M)-|k; zTRYnJ6*dveocu?E#D*{upOsi9XPq)VMB0wFLWfR9ri?TmLmxAgS!JH*Sbp*D4cvC` z#?0fg?|Gl+uPoxt-@iNlu<2>X(jo9reF&9OcC4@Sk{%tf%Ie2^E33|^t!vUPDU1Cx ze+r~{t(85oa%>{yQ>ZV`|LAyDs;aQ$R9|Ds83qcA8L$k`oc+b5!LJ|KyDV?hDD51v z{GrAXY^uqY_>EVuH2;^{ukof5zbe(&=QU1cIn5kPU++1C<&X%yHN<*Uwob|WLP6dd zRx7KK?h?WFew$#$(yfTXOZ_J z4kG}#_4<{D86RZu?=WcG(LnjJ3C>zp=4B!gHB}S|8U^1$h@X-L0QJV9s%>&^?2_nn zQ3sSAK}PRg53_%{?Z`0=LoL;jH(3c8q4dyijDTj5+i;+DgdlSeJ*w2XY2mRw_bqn ze8~=sMyj8u1521KxXJj~2WSmMaXe&t6qf1xtX94F$` z%K-qNuzH-N#5qbF#N(uWwtDRh;YU_}j^#OuWvQS<^kHOdS)YuzTA`0i7u2qF*mf*f zR#%Cnm)a`TDamU4bYJ>(^d&nOwGQ2m9k8WqQo_>evTa$<-1gnddv$bPDS}a|+i^(u z?^{`)H25umKa$>vqf(r>^hDGp6|9f6!x3jdrJGC*>rv?m&$bZjS{u4~X;Sn_P`%8w zTdGH_CigzwVXr!+vv$g_wL@9xGyiSK6fqZ~DN$uWcI<0%1DVt@BEsvwZ706(=hHp1Ipw+GLT&%T`=EJG(dZ3uR9 zpUxlL_Z(@#QgBE*W4;hKam-n00^hzQ!Fh>coy6OYhDWEVX3p z8+-KKU}^fJ+so=ucw!>MXpZHV?@zz!GtIcPsaF2Zb z!Be>aka1Da-?;;^#$ErJd$_7e0VBCzG6?B~6J}fjN={>>E)|wNqL9tqI_Y!c1w9)-P(omY$*+@K0Tgor3-0S zk4EO$Yj4QFAKHgfpFIc5o(~;ceRg1CBP!w&FF6Jvuu)0~URbC4?^H_Eyn8R)-ieq1D`!ab~ZMcds`@4?F4>B6w49*>Q0d2Ub1Ye| z1<9w3$DvrFVc=IM%pX2%w zt~JN9TUYBSrLz{x8p*6x_Ue|7OBcWr^-{UD&0FfK>Cwqs8uQxm28B03JZHos^)-BS zeQl#RNQMl`(lxYoO6^#CMy5{5NrS25$&{{n4NDKhnD*~oX~q*i$c#5Lu-=W9CgwsE z--i?Ck34!w$f(jwBK6?&8M$FY;sjmx1)^o$7jsqfx}7hkz_TCmh*T^yZ$u+HWTC;vLM_bzz`GLFkk zG*j9-7}=J#Za}A&Qq}0?b?Vw9)~6XpYE@4=SMHEY-$O+=^V;yd?WjjE^C{hwDZ;2%uB?oWH1;R439!#< zWIc`%*z{aP{_K@Z__^*@RwAyZ4yBqex^f9W{_34r7^P<$hCCErDla)h<4OArM$;ra zSY4NF#Sh4l4y$S1#flt*GmRyXh`H`ZBEPBMk)Q<<$I3P+dApG+?hlH5dyb{X@@rvL zap<`8053t%zVbDGrPZO!_Ka}N5AVUQ9dsJ7l

'; return $output; + } else { + return ''; } } From 457f8e944804ee4c5fcde6d984ae36e370b07aaa Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 5 Dec 2023 16:07:14 +0100 Subject: [PATCH 122/157] some changes in discovery --- .../godmode/wizards/Applications.class.php | 2 +- .../godmode/wizards/Cloud.class.php | 2 +- .../godmode/wizards/Custom.class.php | 2 +- .../wizards/ManageExtensions.class.php | 63 ++++++++++++++ .../class/ExtensionsDiscovery.class.php | 84 ++++++++++++------- pandora_console/include/styles/pandora.css | 6 ++ 6 files changed, 124 insertions(+), 35 deletions(-) diff --git a/pandora_console/godmode/wizards/Applications.class.php b/pandora_console/godmode/wizards/Applications.class.php index f873170101..f92a8cf0d6 100644 --- a/pandora_console/godmode/wizards/Applications.class.php +++ b/pandora_console/godmode/wizards/Applications.class.php @@ -219,7 +219,7 @@ class Applications extends Wizard 'class' => 'agent_details_line', 'content' => ui_toggle( Wizard::printBigButtonsList($not_defined_extensions, true), - ''.__('Not defined applications').'', + ''.__('Not installed').'', 'not_defined_apps', 'not_defined_apps', false, diff --git a/pandora_console/godmode/wizards/Cloud.class.php b/pandora_console/godmode/wizards/Cloud.class.php index 4b2755cd38..c464c49faa 100644 --- a/pandora_console/godmode/wizards/Cloud.class.php +++ b/pandora_console/godmode/wizards/Cloud.class.php @@ -239,7 +239,7 @@ class Cloud extends Wizard 'class' => 'agent_details_line', 'content' => ui_toggle( Wizard::printBigButtonsList($not_defined_extensions, true), - ''.__('Not defined applications').'', + ''.__('Not installed').'', 'not_defined_apps', 'not_defined_apps', false, diff --git a/pandora_console/godmode/wizards/Custom.class.php b/pandora_console/godmode/wizards/Custom.class.php index 69e30dd86c..516b8d1e80 100644 --- a/pandora_console/godmode/wizards/Custom.class.php +++ b/pandora_console/godmode/wizards/Custom.class.php @@ -142,7 +142,7 @@ class Custom extends Wizard 'class' => 'agent_details_line', 'content' => ui_toggle( Wizard::printBigButtonsList($not_defined_extensions, true), - ''.__('Not defined applications').'', + ''.__('Not installed').'', 'not_defined_apps', 'not_defined_apps', false, diff --git a/pandora_console/godmode/wizards/ManageExtensions.class.php b/pandora_console/godmode/wizards/ManageExtensions.class.php index 91ba1926e5..34c9950bc6 100644 --- a/pandora_console/godmode/wizards/ManageExtensions.class.php +++ b/pandora_console/godmode/wizards/ManageExtensions.class.php @@ -697,6 +697,9 @@ class ManageExtensions extends HTML $order, ); + $appsMetadata = self::loadDiscoveryAppsMetadata(); + $flattenMetadata = array_merge(...array_values($appsMetadata)); + $count = db_get_num_rows($sqlCount); foreach ($data as $key => $row) { @@ -705,6 +708,15 @@ class ManageExtensions extends HTML $logo = $this->defaultLogo; } + $metadataImage = $flattenMetadata[$row['short_name']]['image']; + + if (isset($metadataImage) === true + && file_exists($config['homedir'].'/images/discovery/'.$metadataImage) === true + && file_exists($this->path.'/'.$row['short_name'].'/logo.png') === false + ) { + $logo = '/images/discovery/'.$metadataImage; + } + $logo = html_print_image($logo, true, ['style' => 'max-width: 30px; margin-right: 15px;']); $data[$key]['name'] = $logo.io_safe_output($row['name']); $data[$key]['short_name'] = $row['short_name']; @@ -1490,4 +1502,55 @@ class ManageExtensions extends HTML } + /** + * Read metadata CSV from system and store data structure in memory. + * + * @return array Data structure. + */ + private static function loadDiscoveryAppsMetadata() + { + global $config; + + // Open the CSV file for reading. + $fileHandle = fopen($config['homedir'].'/extras/discovery/DiscoveryApps.csv', 'r'); + + // Check if the file was opened successfully. + if ($fileHandle !== false) { + $csvData = []; + + // Loop through each line in the CSV file. + while (($data = fgetcsv($fileHandle)) !== false) { + $csvData[] = explode(';', $data[0]); + } + + // Close the file handle. + fclose($fileHandle); + } + + $groupedArray = []; + + foreach ($csvData as $item) { + $key = $item[2]; + if (isset($groupedArray[$key]) === false) { + $groupedArray[$key] = []; + } + + $itemShortName = $item[0]; + unset($item[0]); + unset($item[2]); + + $itemIns = [ + 'name' => $item[1], + 'enterprise' => $item[3], + 'image' => $item[4], + 'url' => $item[5], + ]; + + $groupedArray[$key][$itemShortName] = $itemIns; + } + + return $groupedArray; + } + + } diff --git a/pandora_console/include/class/ExtensionsDiscovery.class.php b/pandora_console/include/class/ExtensionsDiscovery.class.php index ff5a38a0a8..ee13e9a3a5 100644 --- a/pandora_console/include/class/ExtensionsDiscovery.class.php +++ b/pandora_console/include/class/ExtensionsDiscovery.class.php @@ -224,37 +224,32 @@ class ExtensionsDiscovery extends Wizard // Print JS required for message management. echo ' From d83a64da9cdf521ed5e2d4ccc14b621a90c721bc Mon Sep 17 00:00:00 2001 From: artica Date: Fri, 8 Dec 2023 01:00:28 +0100 Subject: [PATCH 128/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index af43ac70be..cf45bc8c04 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231207 +Version: 7.0NG.774-231208 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index d5c73049a1..3f74da9f87 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231207" +pandora_version="7.0NG.774-231208" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 5b536bb64b..000b692d19 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231207'; +use constant AGENT_BUILD => '231208'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index a3b2d8ec3d..e57959ed4d 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231207 +%define release 231208 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index 3390a1408b..c6ef6704db 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231207 +%define release 231208 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index 41db54797d..ae96f7945b 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231207 +%define release 231208 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index c7a34dfe60..592b29ec01 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231207 +%define release 231208 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 0dcd58b6b2..c709ccabf7 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231207 +%define release 231208 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 284c4a8eff..cc189da870 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231207" +PI_BUILD="231208" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 6c3def2e2b..0492bd3747 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231207} +{231208} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index e59fbc64d7..6aaa99ac54 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231207") +#define PANDORA_VERSION ("7.0NG.774 Build 231208") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 97dd2beb29..36ba552dbc 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231207))" + VALUE "ProductVersion", "(7.0NG.774(Build 231208))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 48095b1006..35def31e62 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231207 +Version: 7.0NG.774-231208 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 44d1fd3ef3..bbbf38f128 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231207" +pandora_version="7.0NG.774-231208" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 63966fbf18..2677ba9e07 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231207'; +$build_version = 'PC231208'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 2bebc528c2..b4ba9a62e1 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 0303c330ad..9a3dced24c 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231207 +%define release 231208 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 36a2ab9091..781187cf0c 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231207 +%define release 231208 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 659bb9965d..5b028839fb 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231207" +PI_BUILD="231208" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index c7f561dfcd..6bbdcb4126 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231207"; +my $version = "7.0NG.774 Build 231208"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 9e379a06df..dc0d11d629 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231207"; +my $version = "7.0NG.774 Build 231208"; # save program name for logging my $progname = basename($0); From ef339a1bbef0e0c465210a98b425e75be446c028 Mon Sep 17 00:00:00 2001 From: artica Date: Sat, 9 Dec 2023 01:00:21 +0100 Subject: [PATCH 129/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index cf45bc8c04..e0263e29f0 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231208 +Version: 7.0NG.774-231209 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 3f74da9f87..6cabe758b0 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231208" +pandora_version="7.0NG.774-231209" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 000b692d19..8b429b87ec 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231208'; +use constant AGENT_BUILD => '231209'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index e57959ed4d..918cef117c 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231208 +%define release 231209 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index c6ef6704db..ef4e08550d 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231208 +%define release 231209 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index ae96f7945b..def8be7161 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231208 +%define release 231209 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 592b29ec01..7d91de26cb 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231208 +%define release 231209 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index c709ccabf7..b747a39de4 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231208 +%define release 231209 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index cc189da870..be64b4e7f4 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231208" +PI_BUILD="231209" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 0492bd3747..ae59b488fb 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231208} +{231209} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 6aaa99ac54..c3380d5dc9 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231208") +#define PANDORA_VERSION ("7.0NG.774 Build 231209") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 36ba552dbc..b3a74ea04c 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231208))" + VALUE "ProductVersion", "(7.0NG.774(Build 231209))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 35def31e62..b34e7c3c10 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231208 +Version: 7.0NG.774-231209 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index bbbf38f128..7605720802 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231208" +pandora_version="7.0NG.774-231209" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 2677ba9e07..30ba658118 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231208'; +$build_version = 'PC231209'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index b4ba9a62e1..479c48ef78 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 9a3dced24c..54a425c8fe 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231208 +%define release 231209 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 781187cf0c..1ee1d4526f 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231208 +%define release 231209 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 5b028839fb..8fbc6e43d9 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231208" +PI_BUILD="231209" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 6bbdcb4126..4317b3e2f0 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231208"; +my $version = "7.0NG.774 Build 231209"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index dc0d11d629..38cb9a2750 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231208"; +my $version = "7.0NG.774 Build 231209"; # save program name for logging my $progname = basename($0); From 16f75809f119232c98e5b5d7c5f8c803206ca18d Mon Sep 17 00:00:00 2001 From: artica Date: Sun, 10 Dec 2023 01:00:20 +0100 Subject: [PATCH 130/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index e0263e29f0..76a4410d93 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231209 +Version: 7.0NG.774-231210 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 6cabe758b0..ae514aaa0b 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231209" +pandora_version="7.0NG.774-231210" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 8b429b87ec..7336194d0b 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231209'; +use constant AGENT_BUILD => '231210'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 918cef117c..004b530bd7 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231209 +%define release 231210 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index ef4e08550d..a28a04822c 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231209 +%define release 231210 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index def8be7161..4fd4c4c668 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231209 +%define release 231210 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 7d91de26cb..f48688ab34 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231209 +%define release 231210 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index b747a39de4..f28d34b142 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231209 +%define release 231210 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index be64b4e7f4..7993a571d4 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231209" +PI_BUILD="231210" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index ae59b488fb..5f413b451d 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231209} +{231210} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index c3380d5dc9..83835da51f 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231209") +#define PANDORA_VERSION ("7.0NG.774 Build 231210") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index b3a74ea04c..34690b79c2 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231209))" + VALUE "ProductVersion", "(7.0NG.774(Build 231210))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index b34e7c3c10..b15c17467f 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231209 +Version: 7.0NG.774-231210 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 7605720802..a9d1293879 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231209" +pandora_version="7.0NG.774-231210" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 30ba658118..b769ce3c7b 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231209'; +$build_version = 'PC231210'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 479c48ef78..f8372cb9ef 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 54a425c8fe..857cc2f38d 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231209 +%define release 231210 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 1ee1d4526f..c6198d03f8 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231209 +%define release 231210 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 8fbc6e43d9..18c05f9996 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231209" +PI_BUILD="231210" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 4317b3e2f0..5ef975902f 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231209"; +my $version = "7.0NG.774 Build 231210"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 38cb9a2750..660221c07c 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231209"; +my $version = "7.0NG.774 Build 231210"; # save program name for logging my $progname = basename($0); From 5351af2f7a762be74c8096e8b451fb348132b857 Mon Sep 17 00:00:00 2001 From: artica Date: Mon, 11 Dec 2023 01:00:22 +0100 Subject: [PATCH 131/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 76a4410d93..4e0ddda275 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231210 +Version: 7.0NG.774-231211 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index ae514aaa0b..b9ad79a017 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231210" +pandora_version="7.0NG.774-231211" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 7336194d0b..dea8a1db61 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231210'; +use constant AGENT_BUILD => '231211'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 004b530bd7..00ca89e515 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231210 +%define release 231211 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index a28a04822c..ca9029cba0 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231210 +%define release 231211 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index 4fd4c4c668..f47b8313f5 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231210 +%define release 231211 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index f48688ab34..547fe315f0 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231210 +%define release 231211 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index f28d34b142..baec9b3b27 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231210 +%define release 231211 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 7993a571d4..9f2d39b086 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231210" +PI_BUILD="231211" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 5f413b451d..26255617af 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231210} +{231211} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 83835da51f..b053ad9bda 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231210") +#define PANDORA_VERSION ("7.0NG.774 Build 231211") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 34690b79c2..0a75f5df7d 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231210))" + VALUE "ProductVersion", "(7.0NG.774(Build 231211))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index b15c17467f..3f268e2383 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231210 +Version: 7.0NG.774-231211 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index a9d1293879..cbb2b91142 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231210" +pandora_version="7.0NG.774-231211" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index b769ce3c7b..ccf7174e57 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231210'; +$build_version = 'PC231211'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index f8372cb9ef..b9ac34794c 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 857cc2f38d..8aea06e829 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231210 +%define release 231211 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index c6198d03f8..24151d4685 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231210 +%define release 231211 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 18c05f9996..e833bb1958 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231210" +PI_BUILD="231211" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 5ef975902f..269e23f3eb 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231210"; +my $version = "7.0NG.774 Build 231211"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 660221c07c..aae2e87f8e 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231210"; +my $version = "7.0NG.774 Build 231211"; # save program name for logging my $progname = basename($0); From d034116dd31cbe9f3ac4ace193a145ecd4b71f90 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Mon, 11 Dec 2023 09:26:57 +0100 Subject: [PATCH 132/157] #11495 Fix report --- .../include/ajax/reporting.ajax.php | 2 +- pandora_console/include/functions_modules.php | 60 +++++++++++++------ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/pandora_console/include/ajax/reporting.ajax.php b/pandora_console/include/ajax/reporting.ajax.php index 59469a16e3..5f83d79b88 100755 --- a/pandora_console/include/ajax/reporting.ajax.php +++ b/pandora_console/include/ajax/reporting.ajax.php @@ -251,7 +251,7 @@ if ($change_custom_fields_macros_report === true) { } if ($get_agents === true) { - $agents_id = str_replace('"', '', $agents_id); + $agents_id = str_replace('"', '"', $agents_id); try { $agents_id = json_decode($agents_id, true); diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index c759187e21..ea776d6fe3 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4794,7 +4794,6 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule $availability = 0; $type = ''; - if ((bool) is_metaconsole() === true) { if (enterprise_include_once('include/functions_metaconsole.php') !== ENTERPRISE_NOT_HOOK) { $server_id = []; @@ -4860,13 +4859,33 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule if ($events_time !== false && count($events_time) > 0) { $failed_event = []; $normal_event = []; - foreach ($events_time as $event) { - if ($event['event_type'] === 'going_up_critical') { + $events_time = array_reverse($events_time); + $mtrs_events = []; + foreach ($events_time as $key => $event) { + if ($event['event_type'] === 'going_up_critical' || $event['event_type'] === 'going_down_critical') { $failed_event[] = $event['utimestamp']; + $mtrs_events[]['failed_event'] = $event['utimestamp']; } - if ($event['event_type'] === 'going_down_normal') { + if ($event['event_type'] === 'going_up_normal' + || $event['event_type'] === 'going_down_normal' + || $event['event_type'] === 'going_up_warning' + || $event['event_type'] === 'going_down_warning' + ) { $normal_event[] = $event['utimestamp']; + $mtrs_events[]['normal_event'] = $event['utimestamp']; + } + } + + $process_mtrs_events = []; + + if (empty($mtrs_events) === false) { + $last_event_key = ''; + foreach ($mtrs_events as $key => $val) { + if (key($val) !== $last_event_key) { + $last_event_key = key($val); + $process_mtrs_events[] = $val; + } } } @@ -4876,16 +4895,19 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule } else if (empty($failed_event) === true) { $mtrs_array[] = 0; } else { - foreach ($normal_event as $key => $value) { - if (isset($failed_event[$key]) === false) { - $failed_event[$key] = end($failed_event); + $last_value = ''; + foreach ($process_mtrs_events as $key => $val) { + $current_value = $val[key($val)]; + if ($last_value !== '') { + $mtrs_array[] = ($current_value - $last_value); } - if (($failed_event[$key] - $normal_event[$key]) < 0) { - $mtrs_array[] = ($normal_event[$key] - $failed_event[$key]); - } else { - $mtrs_array[] = ($failed_event[$key] - $normal_event[$key]); - } + $last_value = $current_value; + } + + $last_mtrs_event = key(end($process_mtrs_events)); + if ($last_mtrs_event === 'failed_event') { + $mtrs_array[] = ($current_time - $last_value); } } @@ -4894,19 +4916,19 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule if (!empty($failed_event) === true) { if (count($failed_event) > 1) { for ($i = 1; $i <= array_key_last($failed_event); $i++) { - $mtbf_array[] = ($failed_event[($i - 1)] - $failed_event[$i]); + $mtbf_array[] = ($failed_event[$i] - ($failed_event[($i - 1)])); } } else { - $mtbf_array[] = ($current_time - $failed_event[0]); + $mtbf_array[] = 0; } } else { $mtbf_array[] = 0; } - $total_time_failed = array_sum($mtbf_array); + $total_time_failed = array_sum($mtrs_array); $total_time_ok = ($interval_time - $total_time_failed); if (count($events_time) === 1) { - if ((string) $first_utimestamp !== '0') { + if ((int) $first_utimestamp !== 0) { $availability = round((($total_time_ok / $interval_time) * 100), 2); } } else { @@ -4914,14 +4936,14 @@ function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule } if ($critical_events > 1) { - $mtbf = round(( $total_time_failed / $critical_events)); + $mtbf = round(array_sum($mtbf_array) / count($mtbf_array)); } else { $mtbf = false; } - if (count($mtrs_array) === 1 && (string) $first_utimestamp !== '0' && $type === 0) { + if (count($mtrs_array) === 1 && (int) $first_utimestamp !== 0) { $mtrs = round($total_time_failed / count($mtrs_array)); - } else if (count($mtrs_array) > 1 && (string) $first_utimestamp !== '0') { + } else if (count($mtrs_array) > 1 && (int) $first_utimestamp !== 0) { $mtrs = round((array_sum($mtrs_array) / count($mtrs_array))); } else { $mtrs = false; From 28dc5cada056b580ce1e43bf3ecc35df38d8e78c Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 11 Dec 2023 12:21:33 +0100 Subject: [PATCH 133/157] #12596 new dialog on baner open version --- pandora_console/general/header.php | 55 ++++++++++++++++++++-- pandora_console/include/functions_menu.php | 47 ++++++++++++++++++ pandora_console/include/styles/pandora.css | 4 ++ 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 28311371bf..7879ab665f 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -455,19 +455,28 @@ echo sprintf(''; + if (enterprise_installed()) { + $subtitle_header = $config['custom_subtitle_header']; + $class_header = ''; + } else { + $subtitle_header = __('the Flexible Monitoring System (OpenSource version)'); + echo ''; + $class_header = 'underline-hover modal_module_list'; + } + if (is_reporting_console_node() === true) { - echo '
'; + echo '
'; echo ''; echo $config['custom_title_header']; echo ''; echo ''; - echo $config['custom_subtitle_header']; + echo $subtitle_header; echo ''; echo '
'; echo '
'; echo '
'.$modal_help, $header_user, $header_logout.'
'; } else { - echo '
'.$config['custom_title_header'].''.$config['custom_subtitle_header'].'
+ echo '
'.$config['custom_title_header'].''.$subtitle_header.'
'.$header_searchbar.'
'.$header_autorefresh, $header_autorefresh_counter, $header_discovery, $header_welcome, $servers_list, $modal_help, $header_setup, $header_user, $header_logout.'
'; } @@ -916,6 +925,46 @@ echo sprintf('
', $menuTypeClass); $(document).ready (function () { + + $('.header_left').on('click', function(){ + // Hidden tips modal. + $(".window").css("display", "none"); + jQuery.post( + "ajax.php", + { + page: "include/functions_menu", + 'why_enterprise': "true" + }, + function(data) { + if (data) { + $("#dialog_why_enterprise").html(data); + // Open dialog + $("#dialog_why_enterprise").dialog({ + resizable: false, + draggable: false, + modal: true, + show: { + effect: "fade", + duration: 200 + }, + hide: { + effect: "fade", + duration: 200 + }, + closeOnEscape: true, + width: 700, + height: 450, + close: function(){ + $('#dialog_why_enterprise').html(''); + } + }); + } + }, + "html" + ); + }); + + // Check new notifications on a periodic way setInterval(check_new_notifications, 60000); diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 66b14a2776..fa87941b8e 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -875,6 +875,7 @@ function menu_pepare_acl_select_data($pages, $sec) if (is_ajax()) { $about = (bool) get_parameter('about'); $about_operation = (bool) get_parameter('about_operation'); + $why_enterprise = (bool) get_parameter('why_enterprise'); if ($about) { global $config; global $pandora_version; @@ -1370,4 +1371,50 @@ if (is_ajax()) { echo $dialog; } + + if ($why_enterprise) { + global $config; + global $pandora_version; + $product_name = io_safe_output(get_product_name()); + + $lts_name = ''; + if (empty($config['lts_name']) === false) { + $lts_name = ' '.$config['lts_name'].''; + } + + $image_about = ui_get_full_url('/images/custom_logo/logo-default-pandorafms-collapsed.svg', false, false, false); + $url_why_enterprise = 'https://pandorafms.com/en/why-enterprise/'; + $lang = users_get_user_by_id($config['id_user'])['language']; + if ($lang === 'es') { + $url_why_enterprise = 'https://pandorafms.com/es/por-que-pandora-fms-enterprise/'; + } + + $dialog = ' +
+
+ + + + + + + +
+ + logo + + +

'.$product_name.'

+

'.__('Version').' '.$pandora_version.$lts_name.' - '.(enterprise_installed() ? 'Enterprise' : 'Community').'

+

'.__('You are using the free, OpenSource version of Pandora FMS.').'

+

'.__('This version has no official support or warranty, you can purchase the Enterprise version, which offers support, warranty and additional features to the Opensource version.').'

+

'.__('Click on this link for more information.').'

+
+ +
+
+ '; + + echo $dialog; + } } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index d8f7dd9416..6b35f1682d 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -8764,6 +8764,10 @@ div.graph div.legend table { text-decoration: underline; } +.underline-hover:hover { + text-decoration: underline; +} + .w105px { width: 105px; } From 94256559f1de1a32ceef0de36473dee843a4bd4e Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Mon, 11 Dec 2023 16:46:19 +0100 Subject: [PATCH 134/157] #11495 Fix agent name in metaconsole module selector --- .../reporting/reporting_builder.item_editor.php | 2 +- pandora_console/include/functions_agents.php | 4 ++-- pandora_console/include/functions_modules.php | 12 +++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index c9fa71860c..06652894ca 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -2335,7 +2335,7 @@ if (is_metaconsole() === true) { $modulegroup, $id_agents, !$selection_a_m, - false + true ); } diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 2d6803ccd4..3f9bd48955 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -3664,7 +3664,7 @@ function select_modules_for_agent_group( $sql = "SELECT * FROM ( - SELECT DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.nombre + SELECT (tagente_modulo.id_agente_modulo), tagente_modulo.nombre, tagente.alias FROM tagente_modulo $sql_tags_inner INNER JOIN tagente @@ -3679,7 +3679,7 @@ function select_modules_for_agent_group( $filter_not_string_modules $sql_conditions_tags ) x - GROUP BY nombre + $selection_filter"; $modules = db_get_all_rows_sql($sql); diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index ea776d6fe3..2955cdd4f7 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -3774,9 +3774,15 @@ function get_modules_agents( $t['id_node'] = $tserver; if ($nodes[$tserver] !== null) { - $t['nombre'] = io_safe_output( - $nodes[$tserver]->server_name().' » '.$t['nombre'] - ); + if (isset($t['alias']) === true) { + $t['nombre'] = io_safe_output( + $nodes[$tserver]->server_name().' » '.$t['alias'].' » '.$t['nombre'] + ); + } else { + $t['nombre'] = io_safe_output( + $nodes[$tserver]->server_name().' » '.$t['nombre'] + ); + } } $carry[] = $t; From 1a9bdf97d17e5ab425e06bcf9747b43c2514e5d7 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 11 Dec 2023 17:01:40 +0100 Subject: [PATCH 135/157] #12566 changes in view events --- pandora_console/include/functions_events.php | 7 +++- pandora_console/include/functions_ui.php | 12 ++++--- pandora_console/include/styles/events.css | 21 ++++++++++++ pandora_console/operation/events/events.php | 34 +++++++++++++------- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 013698b33d..2436558967 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -6420,7 +6420,12 @@ function event_print_graph( $color[] = '#82b92f'; } } else { - $interval_length = (int) ($period / $num_intervals); + if ($num_intervals > 0) { + $interval_length = (int) ($period / $num_intervals); + } else { + $interval_length = 0; + } + $intervals = []; $intervals[0] = $start_utimestamp; for ($i = 0; $i < $num_intervals; $i++) { diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 3f9146e7d9..3ea3e8a740 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -7179,11 +7179,7 @@ function ui_print_comments($comment, $truncate_limit=255) $comment['comment'] = io_safe_output($comment['comment']); $short_comment = substr($comment['comment'], 0, 20); - $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$comment['comment'].''; - - if (strlen($comentario) > '200px' && $truncate_limit >= 255) { - $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$short_comment.'...'; - } + $comentario = $comment['comment']; if (strlen($comentario) >= $truncate_limit) { $comentario = ui_print_truncate_text( @@ -7198,6 +7194,12 @@ function ui_print_comments($comment, $truncate_limit=255) ); } + $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px; display: contents;', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$comment['comment'].''; + + if (strlen($comentario) > '200px' && $truncate_limit >= 255) { + $comentario = ''.ui_print_timestamp($comment['utimestamp'], true, ['style' => 'font-size: 10px; display: contents;', 'prominent' => 'compact']).' ('.$comment['id_user'].'): '.$short_comment.'...'; + } + return $comentario; } diff --git a/pandora_console/include/styles/events.css b/pandora_console/include/styles/events.css index 1a66ba7174..24d64ce05d 100644 --- a/pandora_console/include/styles/events.css +++ b/pandora_console/include/styles/events.css @@ -108,6 +108,27 @@ td > input[id^="checkbox-multi"] { height: 2.5em; } +.info_table.events tr > td span:not(.invisible) { + display: block; + overflow: hidden; + text-overflow: ellipsis; + max-height: 6em; + line-height: 2em; +} + +th.column-estado { + padding: 0px 0px 0px 12px !important; + max-width: fit-content; +} + +.content-status { + margin: 0 auto; + max-width: fit-content; +} +table#table_events > tbody > tr > td.column-estado { + padding: 0px !important; + text-align: center; +} .sorting_desc { background: url(../../images/sort_down_green.png) no-repeat; background-position-x: left; diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index e019d12ab1..eaf3066e4d 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -906,7 +906,7 @@ if (is_ajax() === true) { break; } - $draw_state = '
'; + $draw_state = '
'; $draw_state .= ''; @@ -1232,15 +1232,18 @@ if (is_ajax() === true) { ); } - $data = array_values( - array_filter( - $data, - function ($item) { - return (bool) (array) $item; - } - ) - ); - $count = count($data); + if (isset($data) === true) { + $data = array_values( + array_filter( + $data, + function ($item) { + return (bool) (array) $item; + } + ) + ); + $count = count($data); + } + // RecordsTotal && recordsfiltered resultados totales. echo json_encode( [ @@ -2585,7 +2588,7 @@ try { if ($evento_id !== false) { $fields[$evento_id] = [ 'text' => 'evento', - 'class' => 'mw250px', + 'class' => 'mw180px', ]; } @@ -2594,6 +2597,15 @@ try { $fields[$comment_id] = ['text' => 'user_comment']; } + $estado = array_search('estado', $fields); + if ($estado !== false) { + $fields[$estado] = [ + 'text' => $fields[$estado], + 'class' => 'column-estado', + ]; + } + + // Always add options column. From 616a8d728b760ea0499fe1a0674d4b278b85dcc9 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 11 Dec 2023 17:56:48 +0100 Subject: [PATCH 136/157] #12416 fixed multiples encrypts --- pandora_console/include/functions_io.php | 3 +++ pandora_console/index.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_io.php b/pandora_console/include/functions_io.php index 6283fdbaed..6264a75138 100755 --- a/pandora_console/include/functions_io.php +++ b/pandora_console/include/functions_io.php @@ -581,6 +581,9 @@ function io_output_password($password, $wrappedBy='') $output = ($plaintext === ENTERPRISE_NOT_HOOK) ? $password : $plaintext; + // If password already decrypt return same password. + $output = (empty($plaintext) === true) ? $password : $plaintext; + return sprintf( '%s%s%s', $wrappedBy, diff --git a/pandora_console/index.php b/pandora_console/index.php index 27f84d53fb..4ca8f80a82 100755 --- a/pandora_console/index.php +++ b/pandora_console/index.php @@ -1234,7 +1234,7 @@ if (has_metaconsole() === true [ 'dbhost' => $config['replication_dbhost'], 'dbuser' => $config['replication_dbuser'], - 'dbpass' => $config['replication_dbpass'], + 'dbpass' => io_output_password($config['replication_dbpass']), 'dbname' => $config['replication_dbname'], ] ); From ffdf0d81b9f5740bada3d3647209bc100dbe68b0 Mon Sep 17 00:00:00 2001 From: artica Date: Tue, 12 Dec 2023 01:00:30 +0100 Subject: [PATCH 137/157] Auto-updated build strings. --- pandora_agents/pc/Win32/pandora_agent.conf | 2 +- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/pandora_agents/pc/Win32/pandora_agent.conf b/pandora_agents/pc/Win32/pandora_agent.conf index b064eba730..27f0326da0 100644 --- a/pandora_agents/pc/Win32/pandora_agent.conf +++ b/pandora_agents/pc/Win32/pandora_agent.conf @@ -1,6 +1,6 @@ # Base config file for Pandora FMS Windows Agent # (c) 2006-2023 Pandora FMS -# Version 7.0NG.774 +# Version 7.0NG.774 # This program is Free Software, you can redistribute it and/or modify it # under the terms of the GNU General Public Licence as published by the Free Software # Foundation; either version 2 of the Licence or any later version diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 4e0ddda275..54a176337b 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231211 +Version: 7.0NG.774-231212 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index b9ad79a017..d051c72a6b 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231211" +pandora_version="7.0NG.774-231212" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 28221f797a..7eb214fc62 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231211'; +use constant AGENT_BUILD => '231212'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 00ca89e515..9f3291fdb9 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231211 +%define release 231212 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index ca9029cba0..a848441ad2 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231211 +%define release 231212 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index f47b8313f5..6abf503eaf 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231211 +%define release 231212 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 547fe315f0..d65d8d79ff 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231211 +%define release 231212 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index baec9b3b27..c97d33c59a 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231211 +%define release 231212 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 9f2d39b086..8c8824bfd5 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231211" +PI_BUILD="231212" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 26255617af..3b72f76b39 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231211} +{231212} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index b053ad9bda..efd6655451 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231211") +#define PANDORA_VERSION ("7.0NG.774 Build 231212") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 0a75f5df7d..324a4cac17 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231211))" + VALUE "ProductVersion", "(7.0NG.774(Build 231212))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 3f268e2383..d5a81b977a 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231211 +Version: 7.0NG.774-231212 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index cbb2b91142..9e1c0f5a64 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231211" +pandora_version="7.0NG.774-231212" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index ccf7174e57..1cf4f577a5 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231211'; +$build_version = 'PC231212'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index b9ac34794c..c54a0c974d 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 8aea06e829..2d0ed51620 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231211 +%define release 231212 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 24151d4685..07ac77eee2 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231211 +%define release 231212 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index e833bb1958..8fa24f1001 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231211" +PI_BUILD="231212" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 269e23f3eb..e8eb01d313 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231211"; +my $version = "7.0NG.774 Build 231212"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index aae2e87f8e..8ac11f20bc 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231211"; +my $version = "7.0NG.774 Build 231212"; # save program name for logging my $progname = basename($0); From 77fd03d58a58d216bfa320502fb583c13aabef16 Mon Sep 17 00:00:00 2001 From: miguel angel rasteu Date: Tue, 12 Dec 2023 10:15:37 +0100 Subject: [PATCH 138/157] #11495 Fix agent name in module selection --- pandora_console/include/functions_agents.php | 2 +- pandora_console/include/functions_modules.php | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 3f9bd48955..aa122b292f 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -3643,7 +3643,7 @@ function select_modules_for_agent_group( if (!$selection && $agents != null) { $number_agents = count($id_agents); - $selection_filter = "HAVING COUNT(id_agente_modulo) = $number_agents"; + $selection_filter = "GROUP BY nombre HAVING COUNT(id_agente_modulo) = $number_agents"; } if (tags_has_user_acl_tags(false)) { diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 019f92d4e1..b5cf42d894 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -3801,7 +3801,7 @@ function get_modules_agents( $return = array_reduce( $modules[$tserver], - function ($carry, $item) use ($tserver, $nodes) { + function ($carry, $item) use ($tserver, $nodes, $selection) { $t = []; foreach ($item as $k => $v) { $t[$k] = $v; @@ -3809,7 +3809,7 @@ function get_modules_agents( $t['id_node'] = $tserver; if ($nodes[$tserver] !== null) { - if (isset($t['alias']) === true) { + if (isset($t['alias']) === true && (bool) $selection === true) { $t['nombre'] = io_safe_output( $nodes[$tserver]->server_name().' » '.$t['alias'].' » '.$t['nombre'] ); @@ -3851,9 +3851,23 @@ function get_modules_agents( $selection, false, $useName, - false, + true, $notStringModules ); + + $modules = array_reduce( + $modules, + function ($carry, $item) use ($id_agents, $selection) { + if (count($id_agents) > 1 && (bool) $selection === true) { + $carry[$item['id_agente_modulo']] = $item['alias'].' » '.$item['nombre']; + } else { + $carry[$item['id_agente_modulo']] = $item['nombre']; + } + + return $carry; + }, + [] + ); } return $modules; From a2f60a1d2240c4cb96b3c32635e96d2c1ba5f99e Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Tue, 12 Dec 2023 12:12:24 +0100 Subject: [PATCH 139/157] Updated MR changes --- pandora_console/extras/mr/67.sql | 4 ++-- pandora_console/pandoradb_data.sql | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandora_console/extras/mr/67.sql b/pandora_console/extras/mr/67.sql index c5cc4e114e..2fc576d477 100644 --- a/pandora_console/extras/mr/67.sql +++ b/pandora_console/extras/mr/67.sql @@ -49,7 +49,7 @@ SET @script_test = 'enable\n expect:Password:\s* _ SET @script_get_config = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'; SET @script_set_config = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'; SET @script_get_firmware = 'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'; -SET @script_set_firmware = 'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'; +SET @script_set_firmware = 'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? firmware.bin\n show flash\n reload\n expect:confirm y\n config terminal\n boot system firmware.bin\n'; SET @script_custom = ''; SET @script_os_version = @script_get_firmware; @@ -769,7 +769,7 @@ SET @script_test = 'enable\n expect:Password:\s* _ SET @script_get_config = 'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'; SET @script_set_config = 'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'; SET @script_get_firmware = 'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'; -SET @script_set_firmware = 'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'; +SET @script_set_firmware = 'copy tftp flash _TFTP_SERVER_IP_ firmware.bin.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ firmware.bin primary\n boot system flash primary\n'; SET @script_custom = ''; SET @script_os_version = @script_get_firmware; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 9581276979..db70f4b0e0 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2556,12 +2556,12 @@ INSERT INTO `tncm_script` VALUES (3,2,'enable expect:Password:\s* _enablepass_ term length 0 config terminal _applyconfigbackup_ exit '), (4,3,'enable expect:Password:\s* _enablepass_ term length 0 capture:show version | i IOS Software exit '), (5,5,'enable expect:Password:\s* _enablepass_ term length 0 config term end end exit '), - (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? _DESTINATION_FILE_NAME_ show flash reload expect:confirm y config terminal boot system _DESTINATION_FILE_NAME_'), + (6,4,'copy tftp flash expect:\]\? _TFTP_SERVER_IP_ expect:\]\? _SOURCE_FILE_NAME_ expect:\]\? firmware.bin show flash reload expect:confirm y config terminal boot system firmware.bin'), (7,0,'enable\n expect:Password:\s* _enablepass_\n exit\n'), (8,1,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show running-config\n exit\n'), (9,2,'enable\n expect:Password:\s* _enablepass_\n term length 0\n config terminal\n _applyconfigbackup_\n exit\n'), (10,3,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), - (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? _DESTINATION_FILE_NAME_\n show flash\n reload\n expect:confirm y\n config terminal\n boot system _DESTINATION_FILE_NAME_\n'), + (11,4,'copy tftp flash\n expect:\]\? _TFTP_SERVER_IP_\n expect:\]\? _SOURCE_FILE_NAME_\n expect:\]\? firmware.bin\n show flash\n reload\n expect:confirm y\n config terminal\n boot system firmware.bin\n'), (12,5,''), (13,7,'enable\n expect:Password:\s* _enablepass_\n term length 0\n capture:show version | i IOS Software\n exit\n'), (14,0,'expect:root@% cli\n exit\n'), @@ -2596,7 +2596,7 @@ INSERT INTO `tncm_script` VALUES (43,1,'enable\n expect:Password:\s* _enablepass_\n capture:show running-config\n exit\n'), (44,2,'configure terminal\n load replace /var/tmp/file.conf\n end\n write memory\n exit\n'), (45,3,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), - (46,4,'copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ _DESTINATION_FILE_NAME_ primary\n boot system flash primary\n'), + (46,4,'copy tftp flash _TFTP_SERVER_IP_ firmware.bin.swi secondary\n boot system flash secondary\n copy tftp flash _TFTP_SERVER_IP_ firmware.bin primary\n boot system flash primary\n'), (47,5,''), (48,7,'enable\n expect:Password:\s* _enablepass_\n capture:show version\n exit\n'), (49,0,'sleep:1 exit\n\r'), From 90c91f67fa65a8d2b697cc9bb5762238584abde3 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 12 Dec 2023 12:45:13 +0100 Subject: [PATCH 140/157] #12633 Fixed Acknowledged --- pandora_console/include/functions_events.php | 61 ++++++-------------- 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 747e5154ce..1a37bfbf95 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -5039,7 +5039,11 @@ function events_page_general($event) $data[1] = $user_owner; } - $table_general->cellclass[3][1] = 'general_owner'; + if (is_metaconsole() === true && $event['server_name'] !== '') { + $table_general->cellclass[4][1] = 'general_owner'; + } else { + $table_general->cellclass[3][1] = 'general_owner'; + } $table_general->data[] = $data; @@ -5100,38 +5104,7 @@ function events_page_general($event) $data = []; $data[0] = __('Acknowledged by'); - - if ($event['estado'] == 1 || $event['estado'] == 2) { - if (empty($event['id_usuario']) === true) { - $user_ack = __('Autovalidated'); - } else { - $user_ack = db_get_value( - 'fullname', - 'tusuario', - 'id_user', - $event['id_usuario'] - ); - - if (empty($user_ack) === true) { - $user_ack = $event['id_usuario']; - } - } - - $data[1] = $user_ack.' ( '; - if ($event['ack_utimestamp_raw'] !== false - && $event['ack_utimestamp_raw'] !== 'false' - && empty($event['ack_utimestamp_raw']) === false - ) { - $data[1] .= date( - $config['date_format'], - $event['ack_utimestamp_raw'] - ); - } - - $data[1] .= ' ) '; - } else { - $data[1] = ''.__('N/A').''; - } + $data[1] = events_page_general_acknowledged($event['id_evento']); $table_general->cellclass[7][1] = 'general_status'; @@ -5237,15 +5210,19 @@ function events_page_general_acknowledged($event_id) $Acknowledged = ''; $event = db_get_row('tevento', 'id_evento', $event_id); if ($event !== false && ($event['estado'] == 1 || $event['estado'] == 2)) { - $user_ack = db_get_value( - 'fullname', - 'tusuario', - 'id_user', - $config['id_user'] - ); + if (empty($event['id_usuario']) === true) { + $user_ack = __('Autovalidated'); + } else { + $user_ack = db_get_value( + 'fullname', + 'tusuario', + 'id_user', + $config['id_user'] + ); - if (empty($user_ack) === true) { - $user_ack = $config['id_user']; + if (empty($user_ack) === true) { + $user_ack = $config['id_user']; + } } $Acknowledged = $user_ack.' ( '; @@ -5260,7 +5237,7 @@ function events_page_general_acknowledged($event_id) $Acknowledged .= ' ) '; } else { - $Acknowledged = 'N/A'; + $Acknowledged = ''.__('N/A').''; } return $Acknowledged; From 9dbac217c18661b89b41e2fb6088601259b8b4fe Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 12 Dec 2023 14:07:18 +0100 Subject: [PATCH 141/157] #12633 Fixed Acknowledged 2 --- pandora_console/include/functions_events.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 1a37bfbf95..64beee38c1 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -5103,9 +5103,23 @@ function events_page_general($event) $table_general->cellclass[count($table_general->data)][1] = 'general_acknowleded'; $data = []; + + if (empty($event['server_id']) === false && (int) $event['server_id'] > 0 + && is_metaconsole() === true + ) { + $node_connect = new Node($event['server_id']); + $node_connect->connect(); + } + $data[0] = __('Acknowledged by'); $data[1] = events_page_general_acknowledged($event['id_evento']); + if (empty($event['server_id']) === false && (int) $event['server_id'] > 0 + && is_metaconsole() === true + ) { + $node_connect->disconnect(); + } + $table_general->cellclass[7][1] = 'general_status'; $table_general->data[] = $data; From 6e60d19193a5b43378939d4496abc7bbb00d2825 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 12 Dec 2023 15:46:42 +0100 Subject: [PATCH 142/157] #8365 ftp server ip --- .../godmode/setup/setup_general.php | 29 +++++++++++++++++++ pandora_console/include/functions_config.php | 4 +++ 2 files changed, 33 insertions(+) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 56596af445..90b2264793 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -896,6 +896,35 @@ echo ''.__('Mail configuration').''; echo ''; + echo '
'; + echo ''.__('NCM Configuration').''; + + $table_ncm_config = new stdClass(); + $table_ncm_config->width = '100%'; + $table_ncm_config->class = 'databox filter-table-adv'; + $table_ncm_config->size = []; + $table_ncm_config->size[0] = '50%'; + $table_ncm_config->data = []; + + $table_ncm_config->data[0][] = html_print_label_input_block( + __('FTP server IP').ui_print_help_tip(__('This value will be used by TFTP_SERVER_IP macro in NCM scripts.'), true), + html_print_input_text( + 'tftp_server_ip', + $config['tftp_server_ip'], + '', + false, + 255, + true, + false, + false, + '', + 'w50p' + ) + ); + + html_print_table($table_ncm_config); + + echo '
'; html_print_action_buttons( html_print_submit_button( diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index e47e84adeb..0f55153922 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -431,6 +431,10 @@ function config_update_config() if (config_update_value('inventory_changes_blacklist', implode(',', $inventory_changes_blacklist), true) === false) { $error_update[] = __('Inventory changes blacklist'); } + + if (config_update_value('tftp_server_ip', (string) get_parameter('tftp_server_ip'), true) === false) { + $error_update[] = __('Ftp server ip'); + } break; case 'enterprise': From 14f8deebcaef67ef2b5f7c15b91ef4b28746a1f5 Mon Sep 17 00:00:00 2001 From: artica Date: Wed, 13 Dec 2023 01:00:28 +0100 Subject: [PATCH 143/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 54a176337b..f8b810d817 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231212 +Version: 7.0NG.774-231213 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index d051c72a6b..fe934f5bb2 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231212" +pandora_version="7.0NG.774-231213" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 7eb214fc62..263b12b006 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231212'; +use constant AGENT_BUILD => '231213'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 9f3291fdb9..c8b79b5432 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231212 +%define release 231213 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index a848441ad2..e15c66a2b0 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231212 +%define release 231213 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index 6abf503eaf..c8b9c5bab9 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231212 +%define release 231213 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index d65d8d79ff..54311de34a 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231212 +%define release 231213 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index c97d33c59a..bfeb6b46be 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231212 +%define release 231213 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 8c8824bfd5..ccd8e1bbe9 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231212" +PI_BUILD="231213" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 3b72f76b39..af055f92d2 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231212} +{231213} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index efd6655451..0c717e94de 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231212") +#define PANDORA_VERSION ("7.0NG.774 Build 231213") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 324a4cac17..d0c4b12420 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231212))" + VALUE "ProductVersion", "(7.0NG.774(Build 231213))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index d5a81b977a..3db8b82868 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231212 +Version: 7.0NG.774-231213 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 9e1c0f5a64..ed5bacf153 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231212" +pandora_version="7.0NG.774-231213" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 1cf4f577a5..a06a174ade 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231212'; +$build_version = 'PC231213'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index c54a0c974d..91de00f8a8 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 2d0ed51620..3d44ddc426 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231212 +%define release 231213 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 07ac77eee2..0bad40c2b6 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231212 +%define release 231213 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 8fa24f1001..8dcdf85db0 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231212" +PI_BUILD="231213" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index e8eb01d313..0b74326632 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231212"; +my $version = "7.0NG.774 Build 231213"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 8ac11f20bc..afcf8b9199 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231212"; +my $version = "7.0NG.774 Build 231213"; # save program name for logging my $progname = basename($0); From 7df7fdff7da53afc2235230b72768b4757a46c25 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 13 Dec 2023 10:32:29 +0100 Subject: [PATCH 144/157] fix msg error agent cluster pandora_enterprise#12511 --- .../godmode/agentes/modificar_agente.php | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index 5ea31914c6..a7ee6bf4c0 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -958,12 +958,33 @@ if ($agents !== false) { ); if ($check_aw === true && is_management_allowed() === true) { - if ($agent['id_os'] != CLUSTER_OS_ID) { - $onClickActionDeleteAgent = 'if (!confirm(\' '.__('Are you sure?').'\')) return false;'; - } else { - $onClickActionDeleteAgent = 'if (!confirm(\' '.__('WARNING! - You are going to delete a cluster agent. Are you sure?').'\')) return false;'; + $clusters = agents_get_agent_belongs_cluster($agent['id_agente']); + $cluster_belongs = ''; + if (empty($clusters) === false) { + $clusters = array_reduce( + $clusters, + function ($carry, $item) { + $carry[] = $item['name']; + return $carry; + } + ); + $cluster_belongs = implode(', ', $clusters); } + $msg = ''; + if ($agent['id_os'] == CLUSTER_OS_ID) { + $msg .= __('You are going to delete a cluster agent'); + $msg .= '. '; + } else if (empty($cluster_belongs) === false) { + $msg .= __('This agent belongs to the clusters'); + $msg .= ': '; + $msg .= $cluster_belongs; + $msg .= '. '; + } + + $msg .= __('Are you sure?'); + $onClickActionDeleteAgent = 'if (!confirm(\' '.$msg.'\')) return false;'; + $agentActionButtons[] = html_print_menu_button( [ 'href' => ui_get_full_url( From 167c204b6db0ff38ec4cdafc541c867883084f68 Mon Sep 17 00:00:00 2001 From: rafael Date: Wed, 13 Dec 2023 10:35:27 +0100 Subject: [PATCH 145/157] 12531 adding security plugin for windows --- .../windows/pandora_security_win/.gitignore | 1 + .../windows/pandora_security_win/Makefile | 10 + .../windows/pandora_security_win/build.sh | 5 + .../pandora_security_win/docker/Dockerfile | 34 + .../pandora_security_win/docker/winetricks | 23525 ++++++++++++++++ .../src/pandora_security_win.py | 396 + .../pandora_security_win/src/requirements.txt | 1 + pandora_agents/win32/bin/pandora_agent.conf | 5 + .../win32/bin/util/pandora_security_win.exe | 3 + 9 files changed, 23980 insertions(+) create mode 100644 pandora_agents/plugins/windows/pandora_security_win/.gitignore create mode 100644 pandora_agents/plugins/windows/pandora_security_win/Makefile create mode 100644 pandora_agents/plugins/windows/pandora_security_win/build.sh create mode 100644 pandora_agents/plugins/windows/pandora_security_win/docker/Dockerfile create mode 100644 pandora_agents/plugins/windows/pandora_security_win/docker/winetricks create mode 100644 pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py create mode 100644 pandora_agents/plugins/windows/pandora_security_win/src/requirements.txt create mode 100755 pandora_agents/win32/bin/util/pandora_security_win.exe diff --git a/pandora_agents/plugins/windows/pandora_security_win/.gitignore b/pandora_agents/plugins/windows/pandora_security_win/.gitignore new file mode 100644 index 0000000000..53c37a1660 --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/.gitignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/pandora_agents/plugins/windows/pandora_security_win/Makefile b/pandora_agents/plugins/windows/pandora_security_win/Makefile new file mode 100644 index 0000000000..3de60fb2c0 --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/Makefile @@ -0,0 +1,10 @@ +# Makefile for winexe.py. +.PHONY: all build_image pandora_security_win.py + +all: build_image pandora_security_win.py + +build_image: + docker build -t pandora_security_win docker/ + +pandora_security_win.py: + docker run --rm -t -v`pwd`:/pybuild pandora_security_win diff --git a/pandora_agents/plugins/windows/pandora_security_win/build.sh b/pandora_agents/plugins/windows/pandora_security_win/build.sh new file mode 100644 index 0000000000..b06af04f1f --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Build the winexe binary. +wine pip install -r src/requirements.txt +wine pyinstaller --onefile src/pandora_security_win.py +rm -rf build/ __pycache__/ pandora_security_win.spec diff --git a/pandora_agents/plugins/windows/pandora_security_win/docker/Dockerfile b/pandora_agents/plugins/windows/pandora_security_win/docker/Dockerfile new file mode 100644 index 0000000000..3f7e1d7133 --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/docker/Dockerfile @@ -0,0 +1,34 @@ +FROM i386/debian + +# Update the package list. +RUN apt-get update + +# Install needed packages. +RUN apt-get install --yes \ +gnupg2 \ +unzip \ +software-properties-common \ +wget \ +xvfb + +# Install WineHQ. +RUN wget -q https://dl.winehq.org/wine-builds/winehq.key -O- | apt-key add - +RUN apt-add-repository https://dl.winehq.org/wine-builds/debian/; apt-get update +RUN apt-get install --yes --install-recommends wine + +# Use Windows 10. +COPY winetricks /tmp/winetricks +RUN /bin/bash /tmp/winetricks win10; rm -f /tmp/winetricks + +# Install Python. +RUN wget https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe +RUN xvfb-run wine python-3.8.10.exe /quiet Include_doc=0 Include_dev=0 Include_test=0 InstallAllUsers=1 PrependPath=1 TargetDir=c:\python; echo +ENV WINEPATH="c:\\python;c:\\python\Scripts" + +# Install Python modules.. +RUN wine pip.exe install wheel +RUN wine pip.exe install pyinstaller + +VOLUME ["/pybuild"] +WORKDIR "/pybuild" +ENTRYPOINT ["/bin/bash", "/pybuild/build.sh"] diff --git a/pandora_agents/plugins/windows/pandora_security_win/docker/winetricks b/pandora_agents/plugins/windows/pandora_security_win/docker/winetricks new file mode 100644 index 0000000000..08b3a7054e --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/docker/winetricks @@ -0,0 +1,23525 @@ +#!/bin/sh +# shellcheck disable=SC2030,SC2031 +# SC2030: Modification of WINE is local (to subshell caused by (..) group). +# SC2031: WINE was modified in a subshell. That change might be lost +# This has to be right after the shebang, see: https://github.com/koalaman/shellcheck/issues/779 + +# Name of this version of winetricks (YYYYMMDD) +# (This doesn't change often, use the sha256sum of the file when reporting problems) +WINETRICKS_VERSION=20210206-next + +# This is a UTF-8 file +# You should see an o with two dots over it here [ö] +# You should see a micro (u with a tail) here [µ] +# You should see a trademark symbol here [™] + +#-------------------------------------------------------------------- +# +# Winetricks is a package manager for Win32 dlls and applications on POSIX. +# Features: +# - Consists of a single shell script - no installation required +# - Downloads packages automatically from original trusted sources +# - Points out and works around known wine bugs automatically +# - Both command-line and GUI operation +# - Can install many packages in silent (unattended) mode +# - Multiplatform; written for Linux, but supports OS X and Cygwin too +# +# Uses the following non-POSIX system tools: +# - wine is used to execute Win32 apps except on Cygwin. +# - ar, cabextract, unrar, unzip, and 7z are needed by some verbs. +# - aria2c, wget, curl, or fetch is needed for downloading. +# - fuseiso, archivemount (Linux), or hdiutil (macOS) is used to mount .iso images. +# - perl is used to munge steam config files. +# - pkexec, sudo, or kdesu (gksu/gksudo/kdesudo are deprecated upstream but also still supported) +# are used to mount .iso images if the user cached them with -k option. +# - sha256sum, sha256, or shasum (OSX 10.5 does not support these, 10.6+ is required) +# - torify is used with option "--torify" if sites are blocked in single countries. +# - xdg-open (if present) or open (for OS X) is used to open download pages +# for the user when downloads cannot be fully automated. +# - xz is used by some verbs to decompress tar archives. +# - zenity is needed by the GUI, though it can limp along somewhat with kdialog/xmessage. +# +# On Ubuntu, the following line can be used to install all the prerequisites: +# sudo apt install aria2 binutils cabextract fuseiso p7zip-full policykit-1 tor unrar unzip wine xdg-utils xz-utils zenity +# +# On Fedora, these commands can be used (RPM Fusion is used to install unrar): +# sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm +# sudo dnf install binutils cabextract fuseiso p7zip-plugins polkit tor unrar unzip wget wine xdg-utils xz zenity +# +# See https://github.com/Winetricks/winetricks for documentation and tutorials, +# including how to contribute changes to winetricks. +# +#-------------------------------------------------------------------- +# +# Copyright: +# Copyright (C) 2007-2014 Dan Kegel +# Copyright (C) 2008-2019 Austin English +# Copyright (C) 2010-2011 Phil Blankenship +# Copyright (C) 2010-2015 Shannon VanWagner +# Copyright (C) 2010 Belhorma Bendebiche +# Copyright (C) 2010 Eleazar Galano +# Copyright (C) 2010 Travis Athougies +# Copyright (C) 2010 Andrew Nguyen +# Copyright (C) 2010 Detlef Riekenberg +# Copyright (C) 2010 Maarten Lankhorst +# Copyright (C) 2010 Rico Schüller +# Copyright (C) 2011 Scott Jackson +# Copyright (C) 2011 Trevor Johnson +# Copyright (C) 2011 Franco Junio +# Copyright (C) 2011 Craig Sanders +# Copyright (C) 2011 Matthew Bauer +# Copyright (C) 2011 Giuseppe Dia +# Copyright (C) 2011 Łukasz Wojniłowicz +# Copyright (C) 2011 Matthew Bozarth +# Copyright (C) 2013-2017 Andrey Gusev +# Copyright (C) 2013-2020 Hillwood Yang +# Copyright (C) 2013,2016 André Hentschel +# +# License: +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program. If not, see +# . +# +#-------------------------------------------------------------------- +# Coding standards: +# +# Portability: +# - Portability matters, as this script is run on many operating systems +# - No bash, zsh, or csh extensions; only use features from +# the POSIX standard shell and utilities; see +# https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html +# - Prefer classic sh idioms as described in e.g. +# "Portable Shell Programming" by Bruce Blinn, ISBN: 0-13-451494-7 +# - If there is no universally available program for a needed function, +# support the two most frequently available programs. +# e.g. fall back to wget if curl is not available; likewise, support +# both sha256sum and sha256. +# - When using Unix commands like cp, put options before filenames so it will +# work on systems like OS X. e.g. "rm -f foo.dat", not "rm foo.dat -f" +# +# Formatting: +# - Your terminal and editor must be configured for UTF-8 +# If you do not see an o with two dots over it here [ö], stop! +# - Do not use tabs in this file or any verbs. +# - Indent 4 spaces. +# - Try to keep line length below 80 (makes printing easier) +# - Open curly braces ('{'), +# then should go on the same line as 'if/elif' +# close curlies ('}') and 'fi' should line up with the matching { or if, +# cases indented 4 spaces from 'case' and 'esac'. For instance, +# +# if test "$FOO" = "bar"; then +# echo "FOO is bar" +# fi +# +# case "$FOO" in +# bar) echo "FOO is still bar" ;; +# esac +# +# Commenting: +# - Comments should explain intent in English +# - Keep functions short and well named to reduce need for comments +# +# Naming: +# Public things defined by this script, for use by verbs: +# - Variables have uppercase names starting with W_ +# - Functions have lowercase names starting with w_ +# +# Private things internal to this script, not for use by verbs: +# - Local variables have lowercase names starting with uppercase _W_ +# (and should not use the local declaration, as it is not POSIX) +# - Global variables have uppercase names starting with WINETRICKS_ +# - Functions have lowercase names starting with winetricks_ +# FIXME: A few verbs still use winetricks-private functions or variables. +# +# Internationalization / localization: +# - Important or frequently used message should be internationalized +# so translations can be easily added. For example: +# case $LANG in +# de*) echo "Das ist die deutsche Meldung" ;; +# *) echo "This is the English message" ;; +# esac +# +# Support: +# - Winetricks is maintained by Austin English . +# - If winetricks has helped you out, then please consider donating to the FSF/EFF as a thank you: +# * EFF - https://supporters.eff.org/donate/button +# * FSF - https://my.fsf.org/donate +# - Donations towards electricity bill and developer beer fund can be sent via Bitcoin to 18euSAZztpZ9wcN6xZS3vtNnE1azf8niDk +# - I try to actively respond to bugs and pull requests on GitHub: +# - Bugs: https://github.com/Winetricks/winetricks/issues/new +# - Pull Requests: https://github.com/Winetricks/winetricks/pulls +#-------------------------------------------------------------------- + +# Using TRUE and FALSE instead of 0 and 1, to make the logic flow better and cause less confusion with other languages's definitions. +TRUE=0 +FALSE=1 + +# FIXME: XDG_CACHE_HOME is defined twice, clean this up +XDG_DATA_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}" +XDG_CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}" + +W_COUNTRY="" +W_PREFIXES_ROOT="${WINE_PREFIXES:-${XDG_DATA_HOME}/wineprefixes}" + +# For temp files before $WINEPREFIX is available: +if [ -x "$(command -v mktemp 2>/dev/null)" ] ; then + W_TMP_EARLY="$(mktemp -d "${TMPDIR:-/tmp}/winetricks.XXXXXXXX")" +elif [ -w "${TMPDIR}" ] ; then + W_TMP_EARLY="${TMPDIR}" +else + W_TMP_EARLY="/tmp" +fi + +#---- Public Functions ---- + +# Ask permission to continue +w_askpermission() +{ + echo "------------------------------------------------------" + echo "$@" + echo "------------------------------------------------------" + + if test "${W_OPT_UNATTENDED}"; then + _W_timeout="--timeout 5" + fi + + case ${WINETRICKS_GUI} in + zenity) ${WINETRICKS_GUI} "${_W_timeout}" --question --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;; + kdialog) ${WINETRICKS_GUI} --title winetricks --warningcontinuecancel "$@" ;; + none) + if [ -n "${_W_timeout}" ]; then + # -t / TMOUT don't seem to be portable, so just assume yes in unattended mode + w_info "Unattended mode, not prompting for confirmation" + else + printf %s "Press Y or N, then Enter: " + read -r response + test "${response}" = Y || test "${response}" = y + fi + esac + + if test $? -ne 0; then + case ${LANG} in + uk*) w_die "Операція скасована." ;; + pl*) w_die "Anulowano operację, opuszczanie." ;; + pt*) w_die "Operação cancelada, saindo." ;; + *) w_die "Operation cancelled, quitting." ;; + esac + exec false + fi + + unset _W_timeout +} + +# Display info message. Time out quickly if user doesn't click. +w_info() +{ + # If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op: + if [ -z "${WINETRICKS_SUPER_QUIET}" ] ; then + echo "------------------------------------------------------" + echo "$@" + echo "------------------------------------------------------" + fi + + case ${WINETRICKS_GUI} in + zenity) ${WINETRICKS_GUI} --timeout=3 --info --width=400 --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;; + kdialog) ${WINETRICKS_GUI} --title winetricks --msgbox "$@" ;; + none) ;; + esac +} + +# Display warning message to stderr (since it is called inside redirected code) +w_warn() +{ + # If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op: + if [ -z "${WINETRICKS_SUPER_QUIET}" ] ; then + echo "------------------------------------------------------" + echo "warning: $*" + echo "------------------------------------------------------" + fi + + if test "${W_OPT_UNATTENDED}"; then + _W_timeout="--timeout 5" + fi + + case ${WINETRICKS_GUI} in + zenity) ${WINETRICKS_GUI} "${_W_timeout}" --error --width=400 --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";; + kdialog) ${WINETRICKS_GUI} --title winetricks --error "$@" ;; + none) ;; + esac + + unset _W_timeout +} + +# Display warning message to stderr (since it is called inside redirected code) +# And give gui user option to cancel (for when used in a loop) +# If user cancels, exit status is 1 +w_warn_cancel() +{ + echo "------------------------------------------------------" >&2 + echo "$@" >&2 + echo "------------------------------------------------------" >&2 + + if test "${W_OPT_UNATTENDED}"; then + _W_timeout="--timeout 5" + fi + + # Zenity has no cancel button, but will set status to 1 if you click the go-away X + case ${WINETRICKS_GUI} in + zenity) ${WINETRICKS_GUI} "${_W_timeout}" --error --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";; + kdialog) ${WINETRICKS_GUI} --title winetricks --warningcontinuecancel "$@" ;; + none) ;; + esac + + # can't unset, it clears status +} + +# Display fatal error message and terminate script +w_die() +{ + w_warn "$@" + + exit 1 +} + +# Kill all instances of a process in a safe way (Solaris killall kills _everything_) +w_killall() +{ + # shellcheck disable=SC2046,SC2086 + kill -s KILL $(pgrep $1) +} + +# Helper for w_package_broken() and friends. If --force is used, continue. +# If not, exit 99 or the optional value passed as $1 +_w_force_continue_check() +{ + exitval="${1:-99}" + if [ "${WINETRICKS_FORCE}" = 1 ]; then + w_warn "--force was used, so trying anyway. Caveat emptor." + else + exit "${exitval}" + fi +} + +_w_get_broken_messages() +{ + # bit of a hack, but otherwise if two bugs are reported, the second message won't get set: + unset broken_good_version_known + unset broken_good_and_bad_version_known + unset broken_only_bad_version_known + unset broken_no_version_known + + # Unify the broken messages (to make it easier for future translators): + case ${LANG} in + pt*) + # default broken messages + broken_good_version_known_default="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Atualize para >=${good_version}. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_good_and_bad_version_known_default="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version}. Atualize para >=${good_version}. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_only_bad_version_known_default="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version}. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_no_version_known_default="Este pacote (${W_PACKAGE}) está quebrado. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + + # mingw broken messages + broken_good_version_known_mingw="Este pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped} quando o wine é feito com o mingw. Atualize para >=${good_version} ou refaça o wine sem mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_good_and_bad_version_known_mingw="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version} quando o wine é feito com o mingw. Atualize para >=${good_version} ou refaça o wine sem mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_only_bad_version_known_mingw="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version} quando o wine é feito com o mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_no_version_known_mingw="Este pacote (${W_PACKAGE}) está quebrado quando o wine é feito com o mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + + # no mingw broken messages + broken_good_version_known_no_mingw="Este pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped} quando o wine é feito sem mingw. Atualize para >=${good_version}. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_good_and_bad_version_known_no_mingw="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version} quando o wine é feito sem mingw. Atualize para >=${good_version}. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_only_bad_version_known_no_mingw="O pacote (${W_PACKAGE}) está quebrado no wine-${_wine_version_stripped}. Quebrado desde ${bad_version} quando o wine é feito sem mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_no_version_known_no_mingw="Este pacote (${W_PACKAGE}) está quebrado quando o wine é feito sem mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + + # win64 broken messages + broken_good_version_known_win64="Este pacote (${W_PACKAGE}) está quebrado em 64-bit wine-${_wine_version_stripped}. Use um prefixo feito com WINEARCH=win32 ou atualize o wine para >=${good_version} para trabalhar com isto. Or use --force to try anyway. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_good_and_bad_version_known_win64="Este pacote (${W_PACKAGE}) está quebrado em 64-bit wine-${_wine_version_stripped}. Quebrado desde ${bad_version}. Use um prefixo feito com WINEARCH=win32 ou atualize o wine para >=${good_version} para trabalhar com isto. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_only_bad_version_known_win64="Este pacote (${W_PACKAGE}) está quebrado em 64-bit wine-${_wine_version_stripped}. Quebrado desde ${bad_version}. Use um prefixo feito com WINEARCH=win32 para trabalhar com isto. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + broken_no_version_known_win64="Este pacote (${W_PACKAGE}) está quebrado quando o wine é feito sem mingw. Veja ${bug_link} para mais informações. Use --force para tentar forçar de toda forma." + ;; + *) + # default broken messages + broken_good_version_known_default="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Upgrade to >=${good_version}. See ${bug_link} for more info. Use --force to try anyway." + broken_good_and_bad_version_known_default="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version}. Upgrade to >=${good_version}. See ${bug_link} for more info. Use --force to try anyway." + broken_only_bad_version_known_default="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version}. See ${bug_link} for more info. Use --force to try anyway." + broken_no_version_known_default="This package (${W_PACKAGE}) is broken. See ${bug_link} for more info. Use --force to try anyway." + + # mingw broken messages + broken_good_version_known_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped} when wine is built with mingw. Upgrade to >=${good_version} or rebuild wine without mingw. See ${bug_link} for more info. Use --force to try anyway." + broken_good_and_bad_version_known_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version} when wine is built with mingw. Upgrade to >=${good_version} or rebuild wine without mingw. See ${bug_link} for more info. Use --force to try anyway." + broken_only_bad_version_known_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version} when wine is built with mingw. See ${bug_link} for more info. Use --force to try anyway." + broken_no_version_known_mingw="This package (${W_PACKAGE}) is broken when wine is built with mingw. See ${bug_link} for more info. Use --force to try anyway." + + # no mingw broken messages + broken_good_version_known_no_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped} when wine is built without mingw. Upgrade to >=${good_version}. See ${bug_link} for more info. Use --force to try anyway." + broken_good_and_bad_version_known_no_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version} when wine is built without mingw. Upgrade to >=${good_version}. See ${bug_link} for more info. Use --force to try anyway." + broken_only_bad_version_known_no_mingw="This package (${W_PACKAGE}) is broken in wine-${_wine_version_stripped}. Broken since ${bad_version} when wine is built without mingw. See ${bug_link} for more info. Use --force to try anyway." + broken_no_version_known_no_mingw="This package (${W_PACKAGE}) is broken when wine is built without mingw. See ${bug_link} for more info. Use --force to try anyway." + + # win64 broken messages + broken_good_version_known_win64="This package (${W_PACKAGE}) is broken on 64-bit wine-${_wine_version_stripped}. Use a prefix made with WINEARCH=win32 or upgrade wine to >=${good_version} to work around this. Or use --force to try anyway. See ${bug_link} for more info. Use --force to try anyway." + broken_good_and_bad_version_known_win64="This package (${W_PACKAGE}) is broken on 64-bit wine-${_wine_version_stripped}. Broken since ${bad_version}. Use a prefix made with WINEARCH=win32 or upgrade wine to >=${good_version} to work around this. See ${bug_link} for more info. Use --force to try anyway." + broken_only_bad_version_known_win64="This package (${W_PACKAGE}) is broken on 64-bit wine-${_wine_version_stripped}. Broken since ${bad_version}. Use a prefix made with WINEARCH=win32 to work around this. See ${bug_link} for more info. Use --force to try anyway." + broken_no_version_known_win64="This package (${W_PACKAGE}) is broken when wine is built without mingw. See ${bug_link} for more info. Use --force to try anyway." + ;; + esac +} + +# Warn user if package is broken (on all arches) in the current wine version. Bug report required. +w_package_broken() +{ + # FIXME: test cases for this + + bug_link="$1" + bad_version="$2" # Optional, for upstream regressions + good_version="$3" # Optional, if it's been fixed upstream + + _w_get_broken_messages + + broken_good_version_known="${broken_good_version_known:-${broken_good_version_known_default}}" + broken_good_and_bad_version_known="${broken_good_and_bad_version_known:-${broken_good_and_bad_version_known_default}}" + broken_only_bad_version_known="${broken_only_bad_version_known:-${broken_only_bad_version_known_default}}" + broken_no_version_known="${broken_no_version_known:-${broken_no_version_known_default}}" + + if [ -z "${bug_link}" ] ; then + w_die "Bug report link required!" + fi + + if [ -n "${good_version}" ] && [ -n "${bad_version}" ]; then + if w_wine_version_in "${bad_version},${good_version}"; then + w_warn "${broken_good_and_bad_version_known}" + else + return + fi + elif [ -n "${good_version}" ]; then + if w_wine_version_in ,"${good_version}"; then + w_warn "${broken_good_version_known}" + else + return + fi + elif [ -n "${bad_version}" ]; then + if w_wine_version_in "${bad_version}",; then + w_warn "${broken_only_bad_version_known}" + else + return + fi + else + w_warn "${broken_no_version_known}" + fi + + unset broken_good_version_known + unset broken_good_and_bad_version_known + unset broken_only_bad_version_known + unset broken_no_version_known + + _w_force_continue_check +} + +w_detect_mingw() +{ + # mingw builds have some (not yet all) .dll files in ${WINE}/../lib{,64}/wine + # non-mingw have exclusively .dll.so files + # + # It's more portable though, to check for 'Wine (placeholder|builtin) DLL' + # placeholder=no-mingw + # builtin=mingw (wine-4.11+) + + # See https://github.com/Winetricks/winetricks/issues/1461 + if w_wine_version_in 4.10, ; then + if grep -obUa "Wine placeholder DLL" "$(w_winepath -u "c:\\windows\\system32\\kernelbase.dll" 2>/dev/null)" | grep -q '64:Wine placeholder DLL'; then + _W_no_mingw=1 + elif grep -obUa "Wine builtin DLL" "$(w_winepath -u "c:\\windows\\system32\\kernelbase.dll" 2>/dev/null)" | grep -q '64:Wine builtin DLL'; then + _W_mingw=1 + else + w_warn "Unable to detect wine dlls, please file an issue on Github!" + fi + else + # FIXME: better message here (at least, easier to grep/recognize + echo "w_detect_mingw: mingw detection unimplemented for wine<4.11" + _W_no_mingw=1 + fi +} + +# Warn user if package is broken in the current wine version when compiled with mingw. Bug report required. +w_package_broken_mingw() +{ + # FIXME: test cases for this + + bug_link="$1" + bad_version="$2" # Optional, for upstream regressions + good_version="$3" # Optional, if it's been fixed upstream + + w_detect_mingw + + _w_get_broken_messages + + if [ -z "${_W_mingw}" ]; then + echo "Not using a mingw build, nothing to do" + return + fi + + broken_good_version_known="${broken_good_version_known_mingw}" + broken_good_and_bad_version_known="${broken_good_and_bad_version_known_mingw}" + broken_only_bad_version_known="${broken_only_bad_version_known_mingw}" + broken_no_version_known="${broken_no_version_known_mingw}" + + w_package_broken "${bug_link}" "${bad_version}" "${good_version}" +} + +# Warn user if package is broken in the current wine version when compiled without mingw. Bug report required. +w_package_broken_no_mingw() +{ + # FIXME: test cases for this + + bug_link="$1" + bad_version="$2" # Optional, for upstream regressions + good_version="$3" # Optional, if it's been fixed upstream + + w_detect_mingw + + _w_get_broken_messages + + if [ -z "${_W_no_mingw}" ]; then + echo "Using a mingw build, nothing to do" + return + fi + + broken_good_version_known="${broken_good_version_known_no_mingw}" + broken_good_and_bad_version_known="${broken_good_and_bad_version_known_no_mingw}" + broken_only_bad_version_known="${broken_only_bad_version_known_no_mingw}" + broken_no_version_known="${broken_no_version_known_no_mingw}" + + w_package_broken "${bug_link}" "${bad_version}" "${good_version}" +} + +# Warn user if package is broken on win64. +w_package_broken_win64() +{ + # FIXME: test cases for this + + bug_link="$1" + bad_version="$2" # Optional, for upstream regressions + good_version="$3" # Optional, if it's been fixed upstream + + _w_get_broken_messages + + if [ "${W_ARCH}" != "win64" ]; then + echo "Not using a 64-bit prefix, nothing to do" + return + fi + + broken_good_version_known="${broken_good_version_known_win64}" + broken_good_and_bad_version_known="${broken_good_and_bad_version_known_win64}" + broken_only_bad_version_known="${broken_only_bad_version_known_win64}" + broken_no_version_known="${broken_no_version_known_win64}" + + w_package_broken "${bug_link}" "${bad_version}" "${good_version}" +} + +# Some packages don't support win32, die with an appropriate message +# Returns 64 (for tests/winetricks-test) +w_package_unsupported_win32() +{ + if [ "${W_ARCH}" = "win32" ] ; then + w_warn "This package (${W_PACKAGE}) does not work on a 32-bit installation. You must use a prefix made with WINEARCH=win64." + _w_force_continue_check 64 + fi +} + + +# Some packages don't support win64, die with an appropriate message +# Note: this is for packages that natively don't support win64, not packages that are broken on wine64, for that, use w_package_broken_win64() +# Returns 32 (for tests/winetricks-test) +w_package_unsupported_win64() +{ + if [ "${W_ARCH}" = "win64" ] ; then + case ${LANG} in + pl*) w_warn "Ten pakiet (${W_PACKAGE}) nie działa z 64-bitową instalacją. Musisz użyć prefiksu utworzonego z WINEARCH=win32." ;; + pt*) w_warn "Este pacote (${W_PACKAGE}) não funciona em instalação de 64-bit. Você precisa usar um prefixo feito com WINEARCH=win32." ;; + ru*) w_warn "Данный пакет не работает в 64-битном окружении. Используйте префикс, созданный с помощью WINEARCH=win32." ;; + zh_CN*) w_warn "(${W_PACKAGE}) 无法在64位下工作,只能将容器变量设置为 WINEARCH=win32 安装。" ;; + zh_TW*|zh_HK*) w_warn "(${W_PACKAGE}) 無法在64元下工作,只能將容器變數設定為 WINEARCH=win32 安装。" ;; + *) w_warn "This package (${W_PACKAGE}) does not work on a 64-bit installation. You must use a prefix made with WINEARCH=win32." ;; + esac + _w_force_continue_check 32 + fi +} + +# For packages that are not well tested or have some known issues on win64, but aren't broken +w_package_warn_win64() +{ + if [ "${W_ARCH}" = "win64" ] ; then + case ${LANG} in + pt*) w_warn "Este pacote (${W_PACKAGE}) talvez não funcione completamente em 64-bit. Em prefixo 32-bit talvez funcione melhor." ;; + pl*) w_warn "Ten pakiet (${W_PACKAGE}) może nie działać poprawnie z 64-bitową instalacją. Prefiks 32-bitowy może działać lepiej." ;; + ru*) w_warn "Данный пакет может работать не полностью в 64-битном окружении. 32-битные префиксы могут работать лучше." ;; + zh_CN*) w_warn "(${W_PACKAGE}) 可能在64位环境下工作有问题,安装在32位环境可能会更好。" ;; + zh_TW*|zh_HK*) w_warn "(${W_PACKAGE}) 可能在64元環境下工作有問題,安装在32元環境可能會更好。" ;; + *) w_warn "This package (${W_PACKAGE}) may not fully work on a 64-bit installation. 32-bit prefixes may work better." ;; + esac + fi +} + +### w_try and w_try wrappers ### + +# Execute with error checking +# Put this in front of any command that might fail +w_try() +{ + # "VAR=foo w_try cmd" fails to put VAR in the environment + # with some versions of bash if w_try is a shell function?! + # This is a problem when trying to pass environment variables to e.g. wine. + # Adding an explicit export here works around it, so add any we use. + export WINEDLLOVERRIDES + # If $WINETRICKS_SUPER_QUIET is set, make w_try quiet + if [ -z "${WINETRICKS_SUPER_QUIET}" ]; then + printf '%s\n' "Executing $*" + fi + + # On Vista, we need to jump through a few hoops to run commands in Cygwin. + # First, .exe's need to have the executable bit set. + # Second, only cmd can run setup programs (presumably for security). + # If $1 ends in .exe, we know we're running on real Windows, otherwise + # $1 would be 'wine'. + case "$1" in + *.exe) + chmod +x "$1" || true # don't care if it fails + cmd /c "$@" + ;; + *) + "$@" + ;; + esac + status=$? + + en_ms_5="exit status ${status} - user selected 'Cancel'" + en_ms_105="exit status ${status} - normal, user selected 'restart now'" + en_ms_194="exit status ${status} - normal, user selected 'restart later'" + + en_abort="Note: command $* returned status ${status}. Aborting." + pl_abort="Informacja: poelcenie $* zwróciło status ${status}. Przerywam." + pt_abort="Nota: comando $* retornou o status ${status}. Cancelando." + ru_abort="Важно: команда $* вернула статус ${status}. Прерывание." + + if [ -n "${_w_ms_installer}" ]; then + case ${status} in + # Nonfatal + 0) ;; + 105) echo "${en_ms_105}" ;; + 194) echo "${en_ms_194}" ;; + + # Fatal + 5) w_die "${en_ms_5}" ;; + *) w_die "${en_abort}" ;; + esac + else + case ${status} in + 0) ;; + *) + case ${LANG} in + pl*) w_die "${pl_abort}" ;; + pt*) w_die "${pt_abort}" ;; + ru*) w_die "${ru_abort}" ;; + *) w_die "${en_abort}" ;; + esac + ;; + esac + fi +} + +# For some MS installers that have special exit codes: +w_try_ms_installer() +{ + _w_ms_installer=true + w_try "$@" + unset _w_ms_installer +} + +w_try_7z() +{ + # $1 - directory to extract to + # $2 - file to extract + # $3 .. $n - files to extract from the archive + + destdir="$1" + filename="$2" + shift 2 + + # Not always installed, use Windows 7-Zip as a fallback: + if [ -z "${WINETRICKS_FORCE_WIN_7Z}" ] && [ -x "$(command -v 7z 2>/dev/null)" ] ; then + w_try 7z x "${filename}" -o"${destdir}" "$@" + else + w_warn "Cannot find 7z. Using Windows 7-Zip instead. (You can avoid this by installing 7z, e.g. 'sudo apt-get install p7zip-full' or 'sudo yum install p7zip-plugins')." + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + + # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory: + w_try_cd "${PWD}" + + # errors out if there is a space between -o and path + w_try "${WINE}" "${W_PROGRAMS_X86_WIN}\\7-Zip\\7z.exe" x "$(w_pathconv -w "${filename}")" -o"$(w_pathconv -w "${destdir}")" "$@" + fi +} + +w_try_ar() +{ + # $1 - ar file (.deb) to extract (keeping internal paths, in cwd) + # $2 - file to extract (optional) + + # Not always installed, use Windows 7-zip as a fallback: + if [ -z "${WINETRICKS_FORCE_WIN_7Z}" ] && [ -x "$(command -v ar 2>/dev/null)" ]; then + w_try ar x "$@" + else + w_warn "Cannot find ar. Using Windows 7-zip instead. (You can avoid this by installing binutils, e.g. 'sudo apt-get install binutils' or 'sudo yum install binutils')." + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + + # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory: + w_try_cd "${PWD}" + + # -t* prevents 7-zip from decompressing .tar.xz to .tar, see + # https://sourceforge.net/p/sevenzip/discussion/45798/thread/8cd16946/?limit=25 + w_try "${WINE}" "${W_PROGRAMS_X86_WIN}\\7-Zip\\7z.exe" -t* x "$(w_pathconv -w "$1")" + fi +} + +w_try_cabextract() +{ + # Not always installed, but shouldn't be fatal unless it's being used + if test ! -x "$(command -v cabextract 2>/dev/null)"; then + w_die "Cannot find cabextract. Please install it (e.g. 'sudo apt-get install cabextract' or 'sudo yum install cabextract')." + fi + + w_try cabextract -q "$@" +} + +w_try_cd() +{ + w_try cd "$@" +} + +# Copy $1 into $2. If $2 is found to be a symbolic link, it will be removed first. +# This solve a problem of dlls being symbolic links on some versions or variants of wine. +# We want to replace the symbolic link and not copy into its target. +w_try_cp_dll() +{ + _W_srcfile="$1" + _W_destfile="$2" + [ -d "${_W_destfile}" ] && _W_destfile="${_W_destfile}/$(basename "${_W_srcfile}")" + + [ -h "${_W_destfile}" ] && w_try rm -f "${_W_destfile}" + w_try cp -f "${_W_srcfile}" "${_W_destfile}" +} + +# Copy font files matching a glob pattern from source directory to destination directory. +# Also remove any file in the destination directory that has the same name as +# any of the files that we're trying to copy, but with different case letters. +# Note: it converts font file names to lower case to avoid inconsistencies due to paths +# being case-insensitive under Wine. +w_try_cp_font_files() +{ + # $1 - source directory + # $2 - destination directory + # $3 - optional font file glob pattern (default: "*.ttf") + + _W_src_dir="$1" + _W_dest_dir="$2" + _W_pattern="$3" + shift 2 + + if test ! -d "${_W_src_dir}"; then + w_die "bug: missing source dir" + fi + + if test ! -d "${_W_dest_dir}"; then + w_die "bug: missing destination dir" + fi + + if test -z "${_W_pattern}"; then + _W_pattern="*.ttf" + fi + +# POSIX sh doesn't have a good way to handle this, but putting into a separate script +# and running with sh avoids it. +# +# See https://github.com/Winetricks/winetricks/issues/995 for details + +cat > "${WINETRICKS_WORKDIR}/cp_font_files.sh" <<_EOF_ +#!/bin/sh + _W_src_file="\$@" + + # Extract the file name and lower case it + _W_file_name="\$(basename "\$_W_src_file" | tr "[:upper:]" "[:lower:]")" + + # Remove any existing font files that might have the same name, but with different case characters + # LANG=C to avoid locale issues (https://github.com/Winetricks/winetricks/issues/1892) + LANG=C find "${_W_dest_dir}" -maxdepth 1 -type f -iname "\$_W_file_name" -exec rm '{}' ';' + + # FIXME: w_try() isn't available, need some better error handling: + cp -f "\$_W_src_file" "${_W_dest_dir}/\$_W_file_name" +_EOF_ + + # Use -exec "sh .." to avoid issues with noexec + # Gross quoting is to avoid SC2156 + # LANG=C to avoid locale issues (https://github.com/Winetricks/winetricks/issues/1892) + LANG=C find "${_W_src_dir}" -maxdepth 1 -type f -iname "${_W_pattern}" -exec sh -c 'sh '"${WINETRICKS_WORKDIR}/cp_font_files.sh"' "$1"' _ {} \; + + # Wait for Wine to add the new font to the registry under HKCU\Software\Wine\Fonts\Cache + w_wineserver -w + + unset _W_dest_dir +} + +w_try_msiexec64() +{ + if test "${W_ARCH}" != "win64"; then + w_die "bug: 64-bit msiexec called from a ${W_ARCH} prefix." + fi + + w_try "${WINE}" start /wait "${W_SYSTEM64_DLLS_WIN32}/msiexec.exe" ${W_OPT_UNATTENDED:+/q} "$@" +} + +w_try_regedit() +{ + # If on wow64, run under both wine and wine64 (otherwise they only go in the 32-bit registry afaict) + if [ "${W_ARCH}" = "win32" ]; then + w_try_regedit32 "$@" + elif [ "${W_ARCH}" = "win64" ]; then + w_try_regedit32 "$@" + w_try_regedit64 "$@" + fi +} + +w_try_regedit32() +{ + # on windows, doesn't work without cmd /c + case "${W_PLATFORM}" in + windows_cmd|wine_cmd) cmdc="cmd /c";; + *) unset cmdc ;; + esac + + # shellcheck disable=SC2086 + w_try "${WINE_MULTI}" ${cmdc} regedit ${W_OPT_UNATTENDED:+/S} "$@" +} + +w_try_regedit64() +{ + # on windows, doesn't work without cmd /c + case "${W_PLATFORM}" in + windows_cmd|wine_cmd) cmdc="cmd /c";; + *) unset cmdc ;; + esac + + # shellcheck disable=SC2086 + w_try "${WINE64}" ${cmdc} regedit ${W_OPT_UNATTENDED:+/S} "$@" +} + +w_try_regsvr() +{ + w_try "${WINE}" regsvr32 ${W_OPT_UNATTENDED:+/S} "$@" +} + +w_try_regsvr64() +{ + w_try "${WINE64}" regsvr32 ${W_OPT_UNATTENDED:+/S} "$@" +} + +w_try_unrar() +{ + # $1 - zipfile to extract (keeping internal paths, in cwd) + + # Not always installed, use Windows 7-Zip as a fallback: + if [ -z "${WINETRICKS_FORCE_WIN_7Z}" ] && [ -x "$(command -v unrar 2>/dev/null)" ]; then + w_try unrar x "$@" + else + w_warn "Cannot find unrar. Using Windows 7-Zip instead. (You can avoid this by installing unrar, e.g. 'sudo apt-get install unrar' or 'sudo yum install unrar')." + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + + # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory: + w_try_cd "${PWD}" + + w_try "${WINE}" "${W_PROGRAMS_X86_WIN}\\7-Zip\\7z.exe" x "$(w_pathconv -w "$1")" + fi +} + +w_try_unzip() +{ + # $1 - directory to extract to + # $2 - zipfile to extract + # $3 .. $n - files to extract from the archive + + destdir="$1" + zipfile="$2" + shift 2 + + # Not always installed, use Windows 7-Zip as a fallback: + if [ -z "${WINETRICKS_FORCE_WIN_7Z}" ] && [ -x "$(command -v unzip 2>/dev/null)" ]; then + # FreeBSD ships unzip, but it doesn't support self-compressed executables + # If it fails, fall back to 7-Zip: + unzip -o -q -d"${destdir}" "${zipfile}" "$@" + ret=$? + case ${ret} in + 0) return ;; + 1|*) w_warn "Unzip failed, trying Windows 7-Zip instead." ;; + esac + else + w_warn "Cannot find unzip. Using Windows 7-Zip instead. (You can avoid this by installing unzip, e.g. 'sudo apt-get install unzip' or 'sudo yum install unzip')." + fi + + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + + # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory: + w_try_cd "${PWD}" + + # errors out if there is a space between -o and path + w_try "${WINE}" "${W_PROGRAMS_X86_WIN}\\7-Zip\\7z.exe" x "$(w_pathconv -w "${zipfile}")" -o"$(w_pathconv -w "${destdir}")" "$@" +} + +### End of w_try ### + +w_read_key() +{ + if test ! "${W_OPT_UNATTENDED}"; then + W_KEY=dummy_to_make_autohotkey_happy + return "${TRUE}" + fi + + mkdir -p "${W_CACHE}/${W_PACKAGE}" + + # backwards compatible location + # Auth doesn't belong in cache, since restoring it requires user input + _W_keyfile="${W_CACHE}/${W_PACKAGE}/key.txt" + if ! test -f "${_W_keyfile}"; then + _W_keyfile="${WINETRICKS_AUTH}/${W_PACKAGE}/key.txt" + fi + if ! test -f "${_W_keyfile}"; then + # read key from user + case ${LANG} in + da*) _W_keymsg="Angiv venligst registrerings-nøglen for pakken '${W_PACKAGE}'" + _W_nokeymsg="Ingen nøgle angivet" + ;; + de*) _W_keymsg="Bitte einen Key für Paket '${W_PACKAGE}' eingeben" + _W_nokeymsg="Keinen Key eingegeben?" + ;; + pl*) _W_keymsg="Proszę podać klucz dla programu '${W_PACKAGE}'" + _W_nokeymsg="Nie podano klucza" + ;; + pt*) _W_keymsg="Por favor, insira a chave do aplicativo '${W_PACKAGE}'" + _W_nokeymsg="Nenhuma chave fornecida" + ;; + ru*) _W_keymsg="Пожалуйста, введите ключ для приложения '${W_PACKAGE}'" + _W_nokeymsg="Ключ не введён" + ;; + uk*) _W_keymsg="Будь ласка, введіть ключ для додатка '${W_PACKAGE}'" + _W_nokeymsg="Ключ не надано" + ;; + zh_CN*) _W_keymsg="按任意键为 '${W_PACKAGE}'" + _W_nokeymsg="No key given" + ;; + zh_TW*|zh_HK*) _W_keymsg="按任意鍵為 '${W_PACKAGE}'" + _W_nokeymsg="No key given" + ;; + *) _W_keymsg="Please enter the key for app '${W_PACKAGE}'" + _W_nokeymsg="No key given" + ;; + esac + + case ${WINETRICKS_GUI} in + *zenity) W_KEY=$(zenity --entry --text "${_W_keymsg}") ;; + *kdialog) W_KEY=$(kdialog --inputbox "${_W_keymsg}") ;; + *xmessage) w_die "sorry, can't read key from GUI with xmessage" ;; + none) printf %s "${_W_keymsg}": ; read -r W_KEY ;; + esac + + if test "${W_KEY}" = ""; then + w_die "${_W_nokeymsg}" + fi + echo "${W_KEY}" > "${_W_keyfile}" + fi + W_RAW_KEY=$(cat "${_W_keyfile}") + W_KEY=$(echo "${W_RAW_KEY}" | tr -d '[:blank:][=-=]') + unset _W_keyfile _W_keymsg _W_nokeymsg +} + +w_verify_cabextract_available() +{ + # If verb_a requires verb_b, then verba will fail when the dependency for verb_b is installed + # This should be called by verb_a, to give a proper warning + + w_try_cabextract -q -v >/dev/null 2>&1 +} + +# Convert a Windows path to a Unix path quickly. +# $1 is an absolute Windows path starting with c:\ or C:/ +# with no funny business, so we can use the simplest possible +# algorithm. +winetricks_wintounix() +{ + _W_winp_="$1" + # Remove drive letter and colon + _W_winp="${_W_winp_#??}" + # Prepend the location of drive c + printf %s "${WINEPREFIX}"/dosdevices/c: + # Change backslashes to slashes + echo "${_W_winp}" | sed 's,\\,/,g' +} + +# Convert between Unix path and Windows path +# Usage is lowest common denominator of cygpath/winepath +# so -u to convert to Unix, and -w to convert to Windows +w_pathconv() +{ + case "${W_PLATFORM}" in + windows_cmd) + # for some reason, cygpath turns some spaces into newlines?! + cygpath "$@" | tr '\012' '\040' | sed 's/ $//' + ;; + *) + case "$@" in + -u?c:\\*|-u?C:\\*|-u?c:/*|-u?C:/*) winetricks_wintounix "$2" ;; + *) w_winepath "$@" ;; + esac + ;; + esac +} + +# Expand an environment variable and print it to stdout +w_expand_env() +{ + winetricks_early_wine_arch cmd.exe /c echo "%$1%" +} + +# Get the latest tagged release from github.com API +w_get_github_latest_release() +{ + # FIXME: can we get releases that aren't on master branch? + org="$1" + repo="$2" + + WINETRICKS_SUPER_QUIET=1 w_download_to "${W_TMP_EARLY}" "https://api.github.com/repos/${org}/${repo}/releases/latest" "" "release.json" >/dev/null 2>&1 + + # aria2c condenses the json (https://github.com/aria2/aria2/issues/1389) + # but curl/wget don't, so handle both cases: + json_length="$(wc -l "${W_TMP_EARLY}/release.json")" + case "${json_length}" in + 0*) latest_version="$(sed -e "s/\",\"/|/g" "${W_TMP_EARLY}/release.json" | tr '|' '\n' | grep tag_name | sed 's@.*"@@')";; + *) latest_version="$(grep -w tag_name "${W_TMP_EARLY}/release.json" | cut -d '"' -f 4)";; + esac + + echo "${latest_version}" +} + +# Get the latest tagged prerelease from github.com API +w_get_github_latest_prerelease() +{ + # FIXME: can we get releases that aren't on master branch? + org="$1" + repo="$2" + + WINETRICKS_SUPER_QUIET=1 w_download_to "${W_TMP_EARLY}" "https://api.github.com/repos/${org}/${repo}/releases" "" "release.json" >/dev/null 2>&1 + + # aria2c condenses the json (https://github.com/aria2/aria2/issues/1389) + # but curl/wget don't, so handle both cases: + json_length="$(wc -l "${W_TMP_EARLY}/release.json")" + case "${json_length}" in + 0*) latest_version="$(sed -e "s/\",\"/|/g" "${W_TMP_EARLY}/release.json" | tr '|' '\n' | grep tag_name -m 1 | sed 's@.*"@@')";; + *) latest_version="$(grep -m 1 -w tag_name "${W_TMP_EARLY}/release.json" | cut -d '"' -f 4)";; + esac + + echo "${latest_version}" +} + +# get sha256sum string and set $_W_gotsha256sum to it +w_get_sha256sum() +{ + _W_sha256_file="$1" + + # See https://github.com/Winetricks/winetricks/issues/645 + # User is running winetricks from /dev/stdin + if [ -f "${_W_sha256_file}" ] || [ -h "${_W_sha256_file}" ] ; then + _W_gotsha256sum=$(${WINETRICKS_SHA256SUM} < "${_W_sha256_file}" | sed 's/(stdin)= //;s/ .*//') + else + w_warn "${_W_sha256_file} is not a regular file, not checking sha256sum" + return + fi +} + +w_get_shatype() { + _W_sum="$1" + + # tr -d " " is for FreeBSD/OS X/Solaris return a leading space: + # See https://stackoverflow.com/questions/30927590/wc-on-osx-return-includes-spaces/30927885#30927885 + _W_sum_length="$(echo "${_W_sum}" | tr -d "\\n" | wc -c | tr -d " ")" + case "${_W_sum_length}" in + 0) _W_shatype="none" ;; + 64) _W_shatype="sha256" ;; + # 128) sha512.. + *) w_die "unsupported shasum..bug" ;; + esac +} + +# verify a sha256sum +w_verify_sha256sum() +{ + _W_vs_wantsum=$1 + _W_vs_file=$2 + + w_get_sha256sum "${_W_vs_file}" + if [ "${_W_gotsha256sum}"x != "${_W_vs_wantsum}"x ] ; then + if [ "${WINETRICKS_FORCE}" = 1 ]; then + w_warn "sha256sum mismatch! However --force was used, so trying anyway. Caveat emptor." + else + w_askpermission "SHA256 mismatch!\n\nURL: ${_W_url}\nDownloaded: ${_W_gotsha256sum}\nExpected: ${_W_vs_wantsum}\n\nThis is often the result of an updated package such as vcrun2019.\nIf you are willing to accept the risk, you can bypass this check.\nAlternatively, you may use the --force option to ignore this check entirely.\n\nContinue anyway?" + fi + fi + unset _W_vs_wantsum _W_vs_file _W_gotsha256sum +} + +# verify any kind of shasum (that winetricks supports ;) ): +w_verify_shasum() +{ + _W_vs_wantsum="$1" + _W_vs_file="$2" + + w_get_shatype "${_W_vs_wantsum}" + + case "${_W_shatype}" in + none) w_warn "No checksum provided, not verifying" ;; + sha256) w_verify_sha256sum "${_W_sum}" "${_W_vs_file}" ;; + # 128) sha512.. + *) w_die "unsupported shasum..bug" ;; + esac +} + +# simple wrapper around winepath using winetricks_early_wine (to strip escape characters, etc.) +# For https://bugs.winehq.org/show_bug.cgi?id=48937 and any future regressions +w_winepath() +{ + winetricks_early_wine winepath "$@" +} + +# wget outputs progress messages that look like this: +# 0K .......... .......... .......... .......... .......... 0% 823K 40s +# This function replaces each such line with the pair of lines +# 0% +# # Downloading... 823K (40s) +# It uses minimal buffering, so each line is output immediately +# and the user can watch progress as it happens. + +# wrapper around wineserver, to let users know that it will wait indefinitely/kill stuff +w_wineserver() +{ + case "$@" in + *-k) w_warn "Running ${WINESERVER} -k. This will kill all running wine processes in prefix=${WINEPREFIX}";; + *-w) w_warn "Running ${WINESERVER} -w. This will hang until all wine processes in prefix=${WINEPREFIX} terminate";; + *) w_warn "Invoking wineserver with '$*'";; + esac + # shellcheck disable=SC2068 + "${WINESERVER}" $@ +} + +winetricks_parse_wget_progress() +{ + # Parse a percentage, a size, and a time into $1, $2 and $3 + # then use them to create the output line. + case ${LANG} in + pl*) perl -p -e \ + '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Pobieranie… \2 (\3)/' ;; + ru*) perl -p -e \ + '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Загрузка... \2 (\3)/' ;; + *) perl -p -e \ + '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Downloading... \2 (\3)/' ;; + esac +} + +# Execute wget, and if in GUI mode, also show a graphical progress bar +winetricks_wget_progress() +{ + case ${WINETRICKS_GUI} in + zenity) + # Use a subshell so if the user clicks 'Cancel', + # the --auto-kill kills the subshell, not the current shell + ( + ${torify} wget "$@" 2>&1 | + winetricks_parse_wget_progress | \ + ${WINETRICKS_GUI} --progress --width 400 --title="${_W_file}" --auto-kill --auto-close + ) + err=$? + if test ${err} -gt 128; then + # 129 is 'killed by SIGHUP' + # Sadly, --auto-kill only applies to parent process, + # which was the subshell, not all the elements of the pipeline... + # have to go find and kill the wget. + # If we ran wget in the background, we could kill it more directly, perhaps... + if pid=$(pgrep -f ."${_W_file}"); then + echo User aborted download, killing wget + # shellcheck disable=SC2086 + kill ${pid} + fi + fi + return ${err} + ;; + *) ${torify} wget "$@" ;; + esac +} + +w_dotnet_verify() +{ + case "$1" in + dotnet11) version="1.1" ;; + dotnet11sp1) version="1.1 SP1" ;; + dotnet20) version="2.0" ;; + dotnet20sp1) version="2.0 SP1" ;; + dotnet20sp2) version="2.0 SP2" ;; + dotnet30) version="3.0" ;; + dotnet30sp1) version="3.0 SP1" ;; + dotnet35) version="3.5" ;; + dotnet35sp1) version="3.5 SP1" ;; + dotnet40) version="4 Client" ;; + dotnet45) version="4.5" ;; + dotnet452) version="4.5.2" ;; + dotnet46) version="4.6" ;; + dotnet461) version="4.6.1" ;; + dotnet462) version="4.6.2" ;; + dotnet471) version="4.7.1" ;; + dotnet472) version="4.7.2" ;; + dotnet48) version="4.8" ;; + *) echo error ; exit 1 ;; + esac + + w_call dotnet_verifier + + # FIXME: The logfile may be useful somewhere (or at least print the location) + + # for 'run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe"' line + # shellcheck disable=SC2140 + w_ahk_do " + SetTitleMatchMode, 2 + ; FIXME; this only works the first time? Check if it's already verified somehow.. + + run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe" + winwait, Verification Utility + ControlClick, Button1 + Control, ChooseString, NET Framework ${version}, ComboBox1 + ControlClick, Button1 ; Verify + loop, 60 + { + sleep 1000 + process, exist, setupverifier2.exe + dn_pid=%ErrorLevel% + if dn_pid = 0 + { + break + } + ifWinExist, Verification Utility, Product verification failed + { + process, close, setupverifier2.exe + exit 1 + } + ifWinExist, Verification Utility, Product verification succeeded + { + process, close, setupverifier2.exe + break + } + } + " + dn_status="$?" + w_info ".Net Verifier returned ${dn_status}" +} + +# Checks if the user can run the self-update/rollback commands +winetricks_check_update_availability() +{ + # Prevents the development file overwrite: + if test -d "../.git"; then + w_warn "You're running in a dev environment. Please make a copy of the file before running this command." + exit + fi + + # Checks read/write permissions on update directories + if ! { test -r "$0" && test -w "$0" && test -w "${0%/*}" && test -x "${0%/*}"; }; then + w_warn "You don't have the proper permissions to run this command. Try again with sudo or as root." + exit + fi +} + +winetricks_selfupdate() +{ + winetricks_check_update_availability + + _W_filename="${0##*/}" + _W_rollback_file="${0}.bak" + _W_update_file="${0}.update" + + _W_tmpdir=${TMPDIR:-/tmp} + _W_tmpdir="$(mktemp -d "${_W_tmpdir}/${_W_filename}.XXXXXXXX")" + + w_download_to "${_W_tmpdir}" https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks "" "${_W_filename}" + + # 2016/10/26: now file is uncompressed? Handle both cases: + update_file_type="$(file "${_W_tmpdir}/${_W_filename}")" + case "${update_file_type}" in + *"POSIX shell script"*) + #echo "already decompressed!" + w_try mv "${_W_tmpdir}/${_W_filename}" "${_W_update_file}" + ;; + *"gzip compressed data"*) + w_try mv "${_W_tmpdir}/${_W_filename}" "${_W_update_file}.gz" + w_try gunzip "${_W_update_file}.gz" + ;; + *) + echo "Unknown file type: ${update_file_type}" + exit 1 + ;; + esac + + w_try rmdir "${_W_tmpdir}" + + w_try cp "$0" "${_W_rollback_file}" + w_try chmod -x "${_W_rollback_file}" + + w_try mv "${_W_update_file}" "$0" + w_try chmod +x "$0" + + w_warn "Update finished! The current version is $($0 -V). Use 'winetricks --update-rollback' to return to the previous version." + + exit +} + +winetricks_selfupdate_rollback() +{ + winetricks_check_update_availability + + _W_rollback_file="${0}.bak" + + if test -f "${_W_rollback_file}"; then + w_try mv "${_W_rollback_file}" "$0" + w_try chmod +x "$0" + w_warn "Rollback finished! The current version is $($0 -V)." + else + w_warn "Nothing to rollback." + fi + exit; +} + +# Download a file +# Usage: w_download_to (packagename|path to download file) url [shasum [filename [cookie jar]]] +# Caches downloads in winetrickscache/$packagename +w_download_to() +{ + winetricks_download_setup + + _W_packagename="$1" # or path to download file to + _W_url="$2" + _W_sum="$3" + _W_file="$4" + _W_cookiejar="$5" + + case ${_W_packagename} in + .) w_die "bug: please do not download packages to top of cache" ;; + esac + + if echo "${_W_url}" | grep ' ' ; then + w_die "bug: please use %20 instead of literal spaces in urls, curl rejects spaces, and they make life harder for linkcheck.sh" + fi + if [ "${_W_file}"x = ""x ] ; then + _W_file=$(basename "${_W_url}") + fi + + w_get_shatype "${_W_sum}" + + if echo "${_W_packagename}" | grep -q -e '\/-' -e '^-'; then + w_die "Invalid path ${_W_packagename} given" + else + if ! echo "${_W_packagename}" | grep -q '^/' ; then + _W_cache="${W_CACHE}/${_W_packagename}" + else + _W_cache="${_W_packagename}" + fi + fi + + if test ! -d "${_W_cache}" ; then + w_try mkdir -p "${_W_cache}" + fi + + # Try download twice + checksum_ok="" + tries=0 + # Set olddir before entering the loop, otherwise second try will overwrite + _W_dl_olddir=$(pwd) + while test ${tries} -lt 2 ; do + # Warn on a second try + test "${tries}" -eq 1 && winetricks_dl_warning + tries=$((tries + 1)) + + if test -s "${_W_cache}/${_W_file}" ; then + if test "${_W_sum}" ; then + if test ${tries} = 1 ; then + # The cache was full. If the file is larger than 500 MB, + # don't checksum it, that just annoys the user. + # shellcheck disable=SC2046 + if test $(du -k "${_W_cache}/${_W_file}" | cut -f1) -gt 500000 ; then + checksum_ok=1 + break + fi + fi + # If checksum matches, declare success and exit loop + case "${_W_shatype}" in + none) + w_warn "No checksum provided, not verifying" + ;; + sha256) + w_get_sha256sum "${_W_cache}/${_W_file}" + if [ "${_W_gotsha256sum}"x = "${_W_sum}"x ] ; then + checksum_ok=1 + break + fi + ;; + esac + + if test "${WINETRICKS_FORCE}" != 1; then + case ${LANG} in + pl*) w_warn "Niezgodność sum kontrolnych dla ${_W_cache}/${_W_file}, pobieram ponownie" ;; + pt*) w_warn "Checksum para ${_W_cache}/${_W_file} não confere, tentando novo download" ;; + ru*) w_warn "Контрольная сумма файла ${_W_cache}/${_W_file} не совпадает, попытка повторной загрузки" ;; + *) w_warn "Checksum for ${_W_cache}/${_W_file} did not match, retrying download" ;; + esac + mv -f "${_W_cache}/${_W_file}" "${_W_cache}/${_W_file}".bak + else + w_warn "Checksum for ${_W_cache}/${_W_file} did not match, but --force was used, so ignoring and trying anyway." + checksum_ok=1 + break + fi + else + # file exists, no checksum known, declare success and exit loop + break + fi + elif test -f "${_W_cache}/${_W_file}" ; then + # zero-length file, just delete before retrying + rm "${_W_cache}/${_W_file}" + fi + + w_try_cd "${_W_cache}" + # Mac folks tend to have curl rather than wget + # On Mac, 'which' doesn't return good exit status + echo "Downloading ${_W_url} to ${_W_cache}" + + # For sites that prefer Mozilla in the user-agent header, set W_BROWSERAGENT=1 + case "${W_BROWSERAGENT}" in + 1) _W_agent="Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" ;; + *) _W_agent="" ;; + esac + + if [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then + # Note: aria2c wants = for most options or silently fails + + # (Slightly fancy) aria2c support + # See https://github.com/Winetricks/winetricks/issues/612 + # --daemon=false --enable-rpc=false to ensure aria2c doesnt go into the background after starting + # and prevent any attempts to rebind on the RPC interface specified in someone's config. + # --input-file='' if the user config has a input-file specified then aria2 will read it and + # attempt to download everything in that input file again. + # --save-session='' if the user has specified save-session in their config, their session will be + # ovewritten by the new aria2 process + + # shellcheck disable=SC2086 + ${torify} aria2c \ + ${aria2c_torify_opts:+"${aria2c_torify_opts}"} \ + --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --continue \ + --daemon=false \ + --dir="${_W_cache}" \ + --enable-rpc=false \ + --input-file='' \ + --max-connection-per-server=5 \ + --max-tries="${WINETRICKS_DOWNLOADER_RETRIES}" \ + --out="${_W_file}" \ + --save-session='' \ + --stream-piece-selector=geom \ + "${_W_url}" + elif [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then + # Use -nd to insulate ourselves from people who set -x in WGETRC + # [*] --retry-connrefused works around the broken sf.net mirroring + # system when downloading corefonts + # [*] --read-timeout is useful on the adobe server that doesn't + # close the connection unless you tell it to (control-C or closing + # the socket) + + # shellcheck disable=SC2086 + winetricks_wget_progress \ + -O "${_W_file}" \ + -nd \ + -c\ + --read-timeout 300 \ + --retry-connrefused \ + --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --tries "${WINETRICKS_DOWNLOADER_RETRIES}" \ + ${_W_cookiejar:+--load-cookies "${_W_cookiejar}"} \ + ${_W_agent:+--user-agent="${_W_agent}"} \ + "${_W_url}" + elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then + # Note: curl does not accept '=' when passing options + # curl doesn't get filename from the location given by the server! + # fortunately, we know it + + # shellcheck disable=SC2086 + ${torify} curl \ + --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + -L \ + -o "${_W_file}" \ + -C - \ + --retry "${WINETRICKS_DOWNLOADER_RETRIES}" \ + ${_W_cookiejar:+--cookie "${_W_cookiejar}"} \ + ${_W_agent:+--user-agent "${_W_agent}"} \ + "${_W_url}" + elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then + # Note: fetch does not support configurable retry count + + # shellcheck disable=SC2086 + ${torify} fetch \ + -T "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + -o "${_W_file}" \ + ${_W_agent:+--user-agent="${_W_agent}"} \ + "${_W_url}" + else + w_die "Here be dragons" + fi + + if test $? = 0; then + # Need to decompress .exe's that are compressed, else Cygwin fails + # Also affects ttf files on github + # FIXME: gzip hack below may no longer be needed, but need to investigate before removing + _W_filetype=$(command -v file 2>/dev/null) + case ${_W_filetype}-${_W_file} in + /*-*.exe|/*-*.ttf|/*-*.zip) + case $(file "${_W_file}") in + *:*gzip*) mv "${_W_file}" "${_W_file}.gz"; gunzip < "${_W_file}.gz" > "${_W_file}";; + esac + esac + + # On Cygwin, .exe's must be marked +x + case "${_W_file}" in + *.exe) chmod +x "${_W_file}" ;; + esac + + w_try_cd "${_W_dl_olddir}" + unset _W_dl_olddir + + # downloaded successfully, exit from loop + break + elif test ${tries} = 2; then + test -f "${_W_file}" && rm "${_W_file}" + w_die "Downloading ${_W_url} failed" + fi + # Download from the Wayback Machine on second try + _W_url="https://web.archive.org/web/2000/${_W_url}" + done + + if test "${_W_sum}" && test ! "${checksum_ok}"; then + w_verify_shasum "${_W_sum}" "${_W_cache}/${_W_file}" + fi +} + +# Open a folder for the user in the specified directory +# Usage: w_open_folder directory +w_open_folder() +{ + for _W_cmd in xdg-open open cygstart true ; do + _W_cmdpath=$(command -v ${_W_cmd}) + if test -n "${_W_cmdpath}" ; then + break + fi + done + ${_W_cmd} "$1" & + unset _W_cmd _W_cmdpath +} + +# Open a web browser for the user to the given page +# Usage: w_open_webpage url +w_open_webpage() +{ + # See https://www.dwheeler.com/essays/open-files-urls.html + for _W_cmd in xdg-open sdtwebclient cygstart open firefox true ; do + _W_cmdpath=$(command -v ${_W_cmd}) + if test -n "${_W_cmdpath}" ; then + break + fi + done + ${_W_cmd} "$1" & + unset _W_cmd _W_cmdpath +} + +# Download a file +# Usage: w_download url [shasum [filename [cookie jar]]] +# Caches downloads in winetrickscache/$W_PACKAGE +w_download() +{ + w_download_to "${W_PACKAGE}" "$@" +} + +# Download one or more files via BitTorrent +# Usage: w_download_torrent [foo.torrent] +# Caches downloads in $W_CACHE/$W_PACKAGE, torrent files are assumed to be there +# If no foo.torrent is given, will add ALL .torrent files in $W_CACHE/$W_PACKAGE +w_download_torrent() +{ + # FIXME: figure out how to extract the filename from the .torrent file + # so callers don't need to check if the files are already downloaded. + + w_call utorrent + + UT_WINPATH="${W_CACHE_WIN}\\${W_PACKAGE}" + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + if [ "$2"x != ""x ] ; then # foo.torrent parameter supplied + w_try "${WINE}" utorrent "/DIRECTORY" "${UT_WINPATH}" "${UT_WINPATH}\\$2" & + else # grab all torrents + for torrent in *.torrent ; do + w_try "${WINE}" utorrent "/DIRECTORY" "${UT_WINPATH}" "${UT_WINPATH}\\${torrent}" & + done + fi + + # Start uTorrent, have it wait until all downloads are finished + w_ahk_do " + SetTitleMatchMode, 2 + winwait, Torrent + Loop + { + sleep 6000 + ifwinexist, Torrent, default + { + ;should uTorrent be the default torrent app? + controlclick, Button1, Torrent, default ; yes + continue + } + ifwinexist, Torrent, already + { + ;torrent already registered, fine + controlclick, Button1, Torrent, default ; yes + continue + } + ifwinexist, Torrent, Bandwidth + { + ;Cancels bandwidth test on first run of uTorrent + controlclick, Button5, Torrent, Bandwidth + continue + } + ifwinexist, Torrent, version + { + ;Decline upgrade to newer version + controlclick, Button3, Torrent, version + controlclick, Button2, Torrent, version + continue + } + break + } + ;Sets parameter to close uTorrent once all downloads are complete + winactivate, Torrent 2.0 + send !o + send a{Down}{Enter} + winwaitclose, Torrent 2.0 + " +} + +w_download_manual_to() +{ + _W_packagename="$1" + _W_url="$2" + _W_file="$3" + _W_shasum="$4" + + # shellcheck disable=SC2154 + case "${media}" in + "download") w_info "FAIL: bug: media type is download, but w_download_manual was called. Programmer, please change verb's media type to manual_download." ;; + esac + + if ! test -f "${W_CACHE}/${_W_packagename}/${_W_file}"; then + case ${LANG} in + da*) _W_dlmsg="Hent venligst filen ${_W_file} fra ${_W_url} og placér den i ${W_CACHE}/${_W_packagename}, kør derefter dette skript.";; + de*) _W_dlmsg="Bitte laden Sie ${_W_file} von ${_W_url} runter, stellen Sie's in ${W_CACHE}/${_W_packagename}, dann wiederholen Sie dieses Kommando.";; + pl*) _W_dlmsg="Proszę pobrać plik ${_W_file} z ${_W_url}, następnie umieścić go w ${W_CACHE}/${_W_packagename}, a na końcu uruchomić ponownie ten skrypt.";; + pt*) _W_dlmsg="Baixe o ${_W_file} de ${_W_url}, salve em ${W_CACHE}/${_W_packagename}, então tente executar novamente este script.";; + ru*) _W_dlmsg="Пожалуйста, скачайте файл ${_W_file} по адресу ${_W_url}, и поместите его в ${W_CACHE}/${_W_packagename}, а затем запустите winetricks заново.";; + uk*) _W_dlmsg="Будь ласка, звантажте ${_W_file} з ${_W_url}, розташуйте в ${W_CACHE}/${_W_packagename}, потім запустіть скрипт знову.";; + zh_CN*) _W_dlmsg="请从 ${_W_url} 下载 ${_W_file},并置放于 ${W_CACHE}/${_W_packagename}, 然后重新运行 winetricks.";; + zh_TW*|zh_HK*) _W_dlmsg="請從 ${_W_url} 下載 ${_W_file},并置放於 ${W_CACHE}/${_W_packagename}, 然后重新執行 winetricks.";; + *) _W_dlmsg="Please download ${_W_file} from ${_W_url}, place it in ${W_CACHE}/${_W_packagename}, then re-run this script.";; + esac + + mkdir -p "${W_CACHE}/${_W_packagename}" + w_open_folder "${W_CACHE}/${_W_packagename}" + w_open_webpage "${_W_url}" + sleep 3 # give some time for web browser to open + w_die "${_W_dlmsg}" + # FIXME: wait in loop until file is finished? + fi + + if test "${_W_shasum}"; then + w_verify_shasum "${_W_shasum}" "${W_CACHE}/${_W_packagename}/${_W_file}" + fi + + unset _W_dlmsg _W_file _W_sha256sum _W_url +} + +w_download_manual() +{ + w_download_manual_to "${W_PACKAGE}" "$@" +} + +# Turn off news, overlays, and friend interaction in Steam +# Run from inside C:\Program Files\Steam +w_steam_safemode() +{ + cat > "${W_TMP}/steamconfig.pl" <<"_EOF_" +#!/usr/bin/env perl +# Parse Steam's localconfig.vcf, add settings to it, and write it out again +# The file is a recursive dictionary +# +# FILE :== CONTAINER +# +# VALUE :== "name" "value" NEWLINE +# +# CONTAINER :== "name" NEWLINE "{" NEWLINE ( VALUE | CONTAINER ) * "}" NEWLINE +# +# We load it into a recursive hash. + +use strict; +use warnings; + +sub read_into_container{ + my( $pcontainer ) = @_; + + $_ = || w_die "Can't read first line of container"; + /{/ || w_die "First line of container was not {"; + while () { + chomp; + if (/"([^"]*)"\s*"([^"]*)"$/) { + ${$pcontainer}{$1} = $2; + } elsif (/"([^"]*)"$/) { + my( %newcon, $name ); + $name = $1; + read_into_container(\%newcon); + ${$pcontainer}{$name} = \%newcon; + } elsif (/}/) { + return; + } else { + w_die "huh?"; + } + } +} + +sub dump_container{ + my( $pcontainer, $indent ) = @_; + foreach (sort(keys(%{$pcontainer}))) { + my( $val ) = ${$pcontainer}{$_}; + if (ref $val eq 'HASH') { + print "${indent}\"$_\"\n"; + print "${indent}{\n"; + dump_container($val, "$indent\t"); + print "${indent}}\n"; + } else { + print "${indent}\"${_}\"\t\t\"$val\"\n"; + } + } +} + +# Disable anything unsafe or annoying +sub disable_notifications{ + my( $pcontainer ) = @_; + ${$pcontainer}{"friends"}{"PersonaStateDesired"} = "1"; + ${$pcontainer}{"friends"}{"Notifications_ShowIngame"} = "0"; + ${$pcontainer}{"friends"}{"Sounds_PlayIngame"} = "0"; + ${$pcontainer}{"friends"}{"Notifications_ShowOnline"} = "0"; + ${$pcontainer}{"friends"}{"Sounds_PlayOnline"} = "0"; + ${$pcontainer}{"friends"}{"Notifications_ShowMessage"} = "0"; + ${$pcontainer}{"friends"}{"Sounds_PlayMessage"} = "0"; + ${$pcontainer}{"friends"}{"AutoSignIntoFriends"} = "0"; + ${$pcontainer}{"News"}{"NotifyAvailableGames"} = "0"; + ${$pcontainer}{"system"}{"EnableGameOverlay"} = "0"; +} + +# Read the file +my(%top); +open FILE, $ARGV[0] || w_die "cannot open ".$ARGV[0]; +my($line); +$line = || w_die "Could not read first line from ".$ARGV[0]; +$line =~ /"UserLocalConfigStore"/ || w_die "this is not a localconfig.vdf file"; +read_into_container(\%top); + +# Modify it +disable_notifications(\%top); + +# Write modified file +print "\"UserLocalConfigStore\"\n"; +print "{\n"; +dump_container(\%top, "\t"); +print "}\n"; +_EOF_ + +for file in userdata/*/config/localconfig.vdf ; do + cp "${file}" "${file}.old" + perl "${W_TMP}"/steamconfig.pl "${file}.old" > "${file}" +done +} + +w_question() +{ + case ${WINETRICKS_GUI} in + *zenity) ${WINETRICKS_GUI} --entry --text "$1" ;; + *kdialog) ${WINETRICKS_GUI} --inputbox "$1" ;; + *xmessage) w_die "sorry, can't ask question with xmessage" ;; + none) + # Using printf instead of echo because we don't want a newline + printf "%s" "$1" >&2 ; + read -r W_ANSWER ; + echo "${W_ANSWER}"; + unset W_ANSWER;; + esac +} + +# Reads steam username and password from environment, cache, or user +# If had to ask user, cache answer. +w_steam_getid() +{ + #TODO: Translate + _W_steamidmsg="Please enter your Steam login ID (not email)" + _W_steampasswordmsg="Please enter your Steam password" + + if test ! "${W_STEAM_ID}"; then + if test -f "${W_CACHE}"/steam_userid.txt; then + W_STEAM_ID=$(cat "${W_CACHE}"/steam_userid.txt) + else + W_STEAM_ID=$(w_question "${_W_steamidmsg}") + echo "${W_STEAM_ID}" > "${W_CACHE}"/steam_userid.txt + chmod 600 "${W_CACHE}"/steam_userid.txt + fi + fi + if test ! "${W_STEAM_PASSWORD}"; then + if test -f "${W_CACHE}"/steam_password.txt; then + W_STEAM_PASSWORD=$(cat "${W_CACHE}"/steam_password.txt) + else + W_STEAM_PASSWORD=$(w_question "${_W_steampasswordmsg}") + echo "${W_STEAM_PASSWORD}" > "${W_CACHE}"/steam_password.txt + chmod 600 "${W_CACHE}"/steam_password.txt + fi + fi +} + +# Usage: +# w_steam_install_game steamidnum windowtitle +w_steam_install_game() +{ + _W_steamid=$1 + _W_steamtitle="$2" + + w_steam_getid + + # Install the steam runtime + WINETRICKS_OPT_SHAREDPREFIX=1 w_call steam + + # Steam puts up a bunch of windows. Here's the sequence: + # "Steam - Updating" - wait for it to close. May appear twice in a row. + # "Steam - Login" - wait for it to close (credentials already given on cmdline) + # "Steam" (small window) - connecting, wait for it to close + # "Steam" (large window) - the main window + # "Steam - Updates News" - close it forcefully + # "Install - $title" - send enter, click a couple checkboxes, send enter again + # "Updating $title" - small download progress dialog + # "Steam - Ready" game install done. (Only comes up if main window not up.) + + w_try_cd "${W_PROGRAMS_X86_UNIX}/Steam" + w_ahk_do " + SetTitleMatchMode 2 + SetWinDelay 500 + ; Run steam once until it finishes its initial update. + ; For me, this exits at 26%. + run steam.exe -applaunch ${_W_steamid} -login ${W_STEAM_ID} ${W_STEAM_PASSWORD} + Loop + { + ifWinExist, Steam - Updating + { + winwaitclose, Steam + process close, Steam.exe + sleep 1000 + ; Run a second time; let it finish updating, then kill it. + run steam.exe + winwait Steam - Updating + winwaitclose + process close, Steam.exe + ; Run a third time, have it log in, wait until it has finished connecting + run steam.exe -applaunch ${_W_steamid} -login ${W_STEAM_ID} ${W_STEAM_PASSWORD} + } + ifWinExist, Steam Login + { + break + } + sleep 500 + } + ; wait for login window to close + winwaitclose + + winwait Steam ; wait for small <> window + winwaitclose + " + +if [ "${STEAM_DVD}" = "TRUE" ]; then + w_ahk_do " + ; Run a fourth time, have it install the app. + run steam.exe -install ${W_ISO_MOUNT_LETTER}:\\ + " +else + w_ahk_do " + ; Run a fourth time, have it install the app. + run steam.exe -applaunch ${_W_steamid} + " +fi + + w_ahk_do " + winwait Install - ${_W_steamtitle} + if ( w_opt_unattended > 0 ) { + send {enter} ; next (for 1st of 3 pages of install dialog) + sleep 1000 + click 32, 91 ; uncheck create menu item? + click 32, 119 ; check create desktop icon? + send {enter} ; next (for 2nd of 3 pages of install dialog) + ; dismiss any news dialogs, and click 'next' on third page of install dialog + loop + { + sleep 1000 + ifwinexist Steam - Updates News + { + winclose + continue + } + ifwinexist Install - ${_W_steamtitle} + { + winactivate + send {enter} ; next (for 3rd of 3 pages of install dialog) + } + ifwinnotexist Install - ${_W_steamtitle} + { + sleep 1000 + ifwinnotexist Install - ${_W_steamtitle} + break + } + } + } + " + +if [ "${STEAM_DVD}" = "TRUE" ]; then + # Wait for install to finish + while true; do + grep "SetHasAllLocalContent(true) called for ${_W_steamid}" "${W_PROGRAMS_X86_UNIX}/Steam/logs/download_log.txt" && break + sleep 5 + done +fi + + w_ahk_do " + ; For DVD's: theoretically, it should be installed now, but most games want to download updates. Do that now. + ; For regular downloads: relaunch to coax steam into showing its nice small download progress dialog + process close, Steam.exe + run steam.exe -login ${W_STEAM_ID} ${W_STEAM_PASSWORD} -applaunch ${_W_steamid} + winwait Ready - + process close, Steam.exe + " + + # Not all users need this disabled, but let's play it safe for now + if w_workaround_wine_bug 22053 "Disabling in-game notifications to prevent game crashes on some machines."; then + w_steam_safemode + fi + + unset _W_steamid _W_steamtitle +} + +#---------------------------------------------------------------- + + +# Usage: w_mount "volume name" [filename-to-check [discnum]] +# Some games have two volumes with identical volume names. +# For these, please specify discnum 1 for first disc, discnum 2 for 2nd, etc., +# else caching can't work. +# FIXME: should take mount option 'unhide' for poorly mastered discs +w_mount() +{ + if test "$3"; then + WINETRICKS_IMG="${W_CACHE}/${W_PACKAGE}/$1-$3.iso" + else + WINETRICKS_IMG="${W_CACHE}/${W_PACKAGE}/$1.iso" + fi + mkdir -p "${W_CACHE}/${W_PACKAGE}" + + if test -f "${WINETRICKS_IMG}"; then + winetricks_mount_cached_iso + else + if test "${WINETRICKS_OPT_KEEPISOS}" = 0 || test "$2"; then + while true; do + winetricks_mount_real_volume "$1" + if test "$2" = "" || test -f "${W_ISO_MOUNT_ROOT}/$2"; then + break + else + w_warn "Wrong disc inserted, $2 not found." + fi + done + fi + + case "${WINETRICKS_OPT_KEEPISOS}" in + 1) + winetricks_cache_iso "$1" + winetricks_mount_cached_iso + ;; + esac + fi +} + +w_umount() +{ + if test "${WINE}" = ""; then + # Windows + winetricks_load_vcdmount + w_try_cd "${VCD_DIR}" + w_try vcdmount.exe /u + else + if test "${W_USE_USERMOUNT}"; then + # FUSE-based tools or hdiutil + if test -d "${W_ISO_USER_MOUNT_ROOT}"; then + "${WINE}" eject "${W_ISO_MOUNT_LETTER}:" + cat > "${W_TMP}"/unset_type_cdrom.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives] +"${W_ISO_MOUNT_LETTER}:"=- +_EOF_ + w_try_regedit "${W_TMP}"/unset_type_cdrom.reg + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:" + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}::" + + case "${WINETRICKS_ISO_MOUNT}" in + hdiutil) + "${WINETRICKS_ISO_MOUNT}" detach "${W_ISO_USER_MOUNT_ROOT}" + ;; + *) + # -uz lazy unmount in case executable still running + fusermount -uz "${W_ISO_USER_MOUNT_ROOT}" + ;; + esac + w_try rmdir "${W_ISO_USER_MOUNT_ROOT}" + fi + W_ISO_MOUNT_ROOT=/mnt/winetricks + else + # sudo + umount + echo "Running ${WINETRICKS_SUDO} umount ${W_ISO_MOUNT_ROOT}" + + case "${WINETRICKS_SUDO}" in + gksu*|kdesudo) + # -l lazy unmount in case executable still running + "${WINETRICKS_SUDO}" "umount -l ${W_ISO_MOUNT_ROOT}" + w_try "${WINETRICKS_SUDO}" "rm -rf ${W_ISO_MOUNT_ROOT}" + ;; + kdesu) + "${WINETRICKS_SUDO}" -c "umount -l ${W_ISO_MOUNT_ROOT}" + w_try "${WINETRICKS_SUDO}" -c "rm -rf ${W_ISO_MOUNT_ROOT}" + ;; + *) + "${WINETRICKS_SUDO}" umount -l "${W_ISO_MOUNT_ROOT}" + w_try "${WINETRICKS_SUDO}" rm -rf "${W_ISO_MOUNT_ROOT}" + ;; + esac + + "${WINE}" eject "${W_ISO_MOUNT_LETTER}:" + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:" + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}::" + fi + fi +} + +w_ahk_do() +{ + if ! test -f "${W_CACHE}/ahk/AutoHotkey.exe"; then + w_download_to ahk https://github.com/AutoHotkey/AutoHotkey/releases/download/v1.0.48.05/AutoHotkey104805_Install.exe 4311c3e7c29ed2d67f415138360210bc2f55ff78758b20b003b91d775ee207b9 + w_try_7z "${W_CACHE}/ahk" "${W_CACHE}/ahk/AutoHotkey104805_Install.exe" AutoHotkey.exe AU3_Spy.exe + chmod +x "${W_CACHE}/ahk/AutoHotkey.exe" + fi + + # Previously this used printf + sed, but that was broken with BSD sed (FreeBSD/OS X): + # https://github.com/Winetricks/winetricks/issues/697 + # So now using trying awk instead (next, perl): + cat <<_EOF_ | awk 'sub("$", "\r")' > "${W_TMP}/${W_PACKAGE}.ahk" +w_opt_unattended = ${W_OPT_UNATTENDED:-0} +$@ +_EOF_ + w_try "${WINE}" "${W_CACHE_WIN}\\ahk\\AutoHotkey.exe" "${W_TMP_WIN}\\${W_PACKAGE}.ahk" +} + +# Function to protect Wine-specific sections of code. +# Outputs a message to console explaining what's being skipped. +# Usage: +# if w_skip_windows name-of-operation; then +# return +# fi +# ... do something that doesn't make sense on Windows ... + +w_skip_windows() +{ + case "${W_PLATFORM}" in + windows_cmd) + echo "Skipping operation '$1' on Windows" + return "${TRUE}" + ;; + esac + return "${FALSE}" +} + +# for common code in w_override_dlls and w_override_app_dlls +w_common_override_dll() +{ + _W_mode="$1" + module="$2" + + # Remove wine's builtin manifest, if present. Use: + # wineboot ; find "$WINEPREFIX"/drive_c/windows/winsxs/ -iname \*deadbeef.manifest | sort + case "${W_PACKAGE}" in + comctl32) + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest + ;; + vcrun2005) + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/amd64_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest + + # These are 32-bit only? + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc80.mfcloc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc80.openmp_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest + ;; + vcrun2008) + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/amd64_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + + # These are 32-bit only? + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc90.mfc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc90.mfcloc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + w_try rm -rf "${W_WINDIR_UNIX}"/winsxs/manifests/x86_microsoft.vc90.openmp_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest + ;; + esac + + if [ "${_W_mode}" = default ] ; then + # To delete a registry key, give an unquoted dash as value + echo "\"*${module}\"=-" >> "${W_TMP}"/override-dll.reg + else + # Note: if you want to override even DLLs loaded with an absolute + # path, you need to add an asterisk: + echo "\"*${module}\"=\"${_W_mode}\"" >> "${W_TMP}"/override-dll.reg + fi +} + +w_override_dlls() +{ + w_skip_windows w_override_dlls && return + + _W_mode=$1 + case ${_W_mode} in + *=*) + w_die "w_override_dlls: unknown mode ${_W_mode}. +Usage: 'w_override_dlls mode[,mode] dll ...'." ;; + disabled) + _W_mode="" ;; + esac + + shift + + echo "Using ${_W_mode} override for following DLLs: $*" + cat > "${W_TMP}"/override-dll.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides] +_EOF_ + while test "$1" != ""; do + w_common_override_dll "${_W_mode}" "$1" + shift + done + + w_try_regedit "${W_TMP_WIN}"\\override-dll.reg + + unset _W_mode +} + +w_override_no_dlls() +{ + w_skip_windows override && return + + w_try_regedit /d "HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides" +} + +w_override_all_dlls() +{ + # Disable all known native Microsoft DLLs in favor of Wine's built-in ones + # Generated with: + # find ./dlls -maxdepth 1 -type d ! -iname "*.dll16" ! -iname "*.drv*" ! -iname "*.ds" ! -iname "*.exe*" ! -iname "*.tlb" ! -iname "*.vxd" -print | sed \ + # -e '/^.*\/adsiid$/ d' \ + # -e '/^.*\/advapi32$/ d' \ + # -e '/^.*\/capi2032$/ d' \ + # -e '/^.*\/dbghelp$/ d' \ + # -e '/^.*\/ddraw$/ d' \ + # -e '/^.*\/dlls$/ d' \ + # -e '/^.*\/dmoguids$/ d' \ + # -e '/^.*\/dxerr8$/ d' \ + # -e '/^.*\/dxerr9$/ d' \ + # -e '/^.*\/dxguid$/ d' \ + # -e '/^.*\/gdi32$/ d' \ + # -e '/^.*\/glu32$/ d' \ + # -e '/^.*\/icmp$/ d' \ + # -e '/^.*\/iphlpapi$/ d' \ + # -e '/^.*\/kernel32$/ d' \ + # -e '/^.*\/l3codeca.acm$/ d' \ + # -e '/^.*\/mfuuid$/ d' \ + # -e '/^.*\/mountmgr.sys$/ d' \ + # -e '/^.*\/mswsock$/ d' \ + # -e '/^.*\/ntdll$/ d' \ + # -e '/^.*\/opengl32$/ d' \ + # -e '/^.*\/secur32$/ d' \ + # -e '/^.*\/strmbase$/ d' \ + # -e '/^.*\/strmiids$/ d' \ + # -e '/^.*\/twain_32$/ d' \ + # -e '/^.*\/unicows$/ d' \ + # -e '/^.*\/user32$/ d' \ + # -e '/^.*\/uuid$/ d' \ + # -e '/^.*\/vdmdbg$/ d' \ + # -e '/^.*\/w32skrnl$/ d' \ + # -e '/^.*\/winecrt0$/ d' \ + # -e '/^.*\/wined3d$/ d' \ + # -e '/^.*\/winemp3.acm$/ d' \ + # -e '/^.*\/wineqtdecoder$/ d' \ + # -e '/^.*\/winmm$/ d' \ + # -e '/^.*\/wintab32$/ d' \ + # -e '/^.*\/wmcodecdspuuid$/ d' \ + # -e '/^.*\/wnaspi32$/ d' \ + # -e '/^.*\/wow32$/ d' \ + # -e '/^.*\/ws2_32$/ d' \ + # -e '/^.*\/wsock32$/ d' \ + # -e 's,.*/, ,' | sort | fmt -63 | sed 's/$/ \\/' + # + # 2018-12-10: Last list update (wine-4.0-rc1) + w_override_dlls builtin \ + acledit aclui activeds actxprxy adsldp adsldpc advpack \ + amstream api-ms-win-appmodel-identity-l1-1-0 \ + api-ms-win-appmodel-runtime-l1-1-1 \ + api-ms-win-appmodel-runtime-l1-1-2 \ + api-ms-win-core-apiquery-l1-1-0 \ + api-ms-win-core-appcompat-l1-1-1 \ + api-ms-win-core-appinit-l1-1-0 \ + api-ms-win-core-atoms-l1-1-0 \ + api-ms-win-core-bem-l1-1-0 api-ms-win-core-com-l1-1-0 \ + api-ms-win-core-com-l1-1-1 api-ms-win-core-comm-l1-1-0 \ + api-ms-win-core-com-private-l1-1-0 \ + api-ms-win-core-console-l1-1-0 \ + api-ms-win-core-console-l2-1-0 \ + api-ms-win-core-crt-l1-1-0 api-ms-win-core-crt-l2-1-0 \ + api-ms-win-core-datetime-l1-1-0 \ + api-ms-win-core-datetime-l1-1-1 \ + api-ms-win-core-debug-l1-1-0 \ + api-ms-win-core-debug-l1-1-1 \ + api-ms-win-core-delayload-l1-1-0 \ + api-ms-win-core-delayload-l1-1-1 \ + api-ms-win-core-errorhandling-l1-1-0 \ + api-ms-win-core-errorhandling-l1-1-1 \ + api-ms-win-core-errorhandling-l1-1-2 \ + api-ms-win-core-errorhandling-l1-1-3 \ + api-ms-win-core-fibers-l1-1-0 \ + api-ms-win-core-fibers-l1-1-1 \ + api-ms-win-core-file-l1-1-0 \ + api-ms-win-core-file-l1-2-0 \ + api-ms-win-core-file-l1-2-1 \ + api-ms-win-core-file-l1-2-2 \ + api-ms-win-core-file-l2-1-0 \ + api-ms-win-core-file-l2-1-1 \ + api-ms-win-core-file-l2-1-2 \ + api-ms-win-core-handle-l1-1-0 \ + api-ms-win-core-heap-l1-1-0 \ + api-ms-win-core-heap-l1-2-0 \ + api-ms-win-core-heap-l2-1-0 \ + api-ms-win-core-heap-obsolete-l1-1-0 \ + api-ms-win-core-interlocked-l1-1-0 \ + api-ms-win-core-interlocked-l1-2-0 \ + api-ms-win-core-io-l1-1-0 api-ms-win-core-io-l1-1-1 \ + api-ms-win-core-job-l1-1-0 api-ms-win-core-job-l2-1-0 \ + api-ms-win-core-kernel32-legacy-l1-1-0 \ + api-ms-win-core-kernel32-legacy-l1-1-1 \ + api-ms-win-core-kernel32-private-l1-1-1 \ + api-ms-win-core-largeinteger-l1-1-0 \ + api-ms-win-core-libraryloader-l1-1-0 \ + api-ms-win-core-libraryloader-l1-1-1 \ + api-ms-win-core-libraryloader-l1-2-0 \ + api-ms-win-core-libraryloader-l1-2-1 \ + api-ms-win-core-libraryloader-l1-2-2 \ + api-ms-win-core-localization-l1-1-0 \ + api-ms-win-core-localization-l1-2-0 \ + api-ms-win-core-localization-l1-2-1 \ + api-ms-win-core-localization-l2-1-0 \ + api-ms-win-core-localization-obsolete-l1-1-0 \ + api-ms-win-core-localization-obsolete-l1-2-0 \ + api-ms-win-core-localization-obsolete-l1-3-0 \ + api-ms-win-core-localization-private-l1-1-0 \ + api-ms-win-core-localregistry-l1-1-0 \ + api-ms-win-core-memory-l1-1-0 \ + api-ms-win-core-memory-l1-1-1 \ + api-ms-win-core-memory-l1-1-2 \ + api-ms-win-core-misc-l1-1-0 \ + api-ms-win-core-namedpipe-l1-1-0 \ + api-ms-win-core-namedpipe-l1-2-0 \ + api-ms-win-core-namespace-l1-1-0 \ + api-ms-win-core-normalization-l1-1-0 \ + api-ms-win-core-path-l1-1-0 \ + api-ms-win-core-privateprofile-l1-1-1 \ + api-ms-win-core-processenvironment-l1-1-0 \ + api-ms-win-core-processenvironment-l1-2-0 \ + api-ms-win-core-processthreads-l1-1-0 \ + api-ms-win-core-processthreads-l1-1-1 \ + api-ms-win-core-processthreads-l1-1-2 \ + api-ms-win-core-processthreads-l1-1-3 \ + api-ms-win-core-processtopology-obsolete-l1-1-0 \ + api-ms-win-core-profile-l1-1-0 \ + api-ms-win-core-psapi-ansi-l1-1-0 \ + api-ms-win-core-psapi-l1-1-0 \ + api-ms-win-core-psapi-obsolete-l1-1-0 \ + api-ms-win-core-quirks-l1-1-0 \ + api-ms-win-core-realtime-l1-1-0 \ + api-ms-win-core-registry-l1-1-0 \ + api-ms-win-core-registry-l2-1-0 \ + api-ms-win-core-registryuserspecific-l1-1-0 \ + api-ms-win-core-rtlsupport-l1-1-0 \ + api-ms-win-core-rtlsupport-l1-2-0 \ + api-ms-win-core-shlwapi-legacy-l1-1-0 \ + api-ms-win-core-shlwapi-obsolete-l1-1-0 \ + api-ms-win-core-shlwapi-obsolete-l1-2-0 \ + api-ms-win-core-shutdown-l1-1-0 \ + api-ms-win-core-sidebyside-l1-1-0 \ + api-ms-win-core-stringansi-l1-1-0 \ + api-ms-win-core-string-l1-1-0 \ + api-ms-win-core-string-l2-1-0 \ + api-ms-win-core-stringloader-l1-1-1 \ + api-ms-win-core-string-obsolete-l1-1-0 \ + api-ms-win-core-synch-ansi-l1-1-0 \ + api-ms-win-core-synch-l1-1-0 \ + api-ms-win-core-synch-l1-2-0 \ + api-ms-win-core-synch-l1-2-1 \ + api-ms-win-core-sysinfo-l1-1-0 \ + api-ms-win-core-sysinfo-l1-2-0 \ + api-ms-win-core-sysinfo-l1-2-1 \ + api-ms-win-core-threadpool-l1-1-0 \ + api-ms-win-core-threadpool-l1-2-0 \ + api-ms-win-core-threadpool-legacy-l1-1-0 \ + api-ms-win-core-threadpool-private-l1-1-0 \ + api-ms-win-core-timezone-l1-1-0 \ + api-ms-win-core-toolhelp-l1-1-0 \ + api-ms-win-core-url-l1-1-0 api-ms-win-core-util-l1-1-0 \ + api-ms-win-core-versionansi-l1-1-0 \ + api-ms-win-core-version-l1-1-0 \ + api-ms-win-core-version-l1-1-1 \ + api-ms-win-core-version-private-l1-1-0 \ + api-ms-win-core-windowserrorreporting-l1-1-0 \ + api-ms-win-core-winrt-error-l1-1-0 \ + api-ms-win-core-winrt-error-l1-1-1 \ + api-ms-win-core-winrt-errorprivate-l1-1-1 \ + api-ms-win-core-winrt-l1-1-0 \ + api-ms-win-core-winrt-registration-l1-1-0 \ + api-ms-win-core-winrt-roparameterizediid-l1-1-0 \ + api-ms-win-core-winrt-string-l1-1-0 \ + api-ms-win-core-winrt-string-l1-1-1 \ + api-ms-win-core-wow64-l1-1-0 \ + api-ms-win-core-wow64-l1-1-1 \ + api-ms-win-core-xstate-l1-1-0 \ + api-ms-win-core-xstate-l2-1-0 \ + api-ms-win-crt-conio-l1-1-0 \ + api-ms-win-crt-convert-l1-1-0 \ + api-ms-win-crt-environment-l1-1-0 \ + api-ms-win-crt-filesystem-l1-1-0 \ + api-ms-win-crt-heap-l1-1-0 \ + api-ms-win-crt-locale-l1-1-0 \ + api-ms-win-crt-math-l1-1-0 \ + api-ms-win-crt-multibyte-l1-1-0 \ + api-ms-win-crt-private-l1-1-0 \ + api-ms-win-crt-process-l1-1-0 \ + api-ms-win-crt-runtime-l1-1-0 \ + api-ms-win-crt-stdio-l1-1-0 \ + api-ms-win-crt-string-l1-1-0 \ + api-ms-win-crt-time-l1-1-0 \ + api-ms-win-crt-utility-l1-1-0 \ + api-ms-win-devices-config-l1-1-0 \ + api-ms-win-devices-config-l1-1-1 \ + api-ms-win-devices-query-l1-1-1 \ + api-ms-win-downlevel-advapi32-l1-1-0 \ + api-ms-win-downlevel-advapi32-l2-1-0 \ + api-ms-win-downlevel-normaliz-l1-1-0 \ + api-ms-win-downlevel-ole32-l1-1-0 \ + api-ms-win-downlevel-shell32-l1-1-0 \ + api-ms-win-downlevel-shlwapi-l1-1-0 \ + api-ms-win-downlevel-shlwapi-l2-1-0 \ + api-ms-win-downlevel-user32-l1-1-0 \ + api-ms-win-downlevel-version-l1-1-0 \ + api-ms-win-dx-d3dkmt-l1-1-0 \ + api-ms-win-eventing-classicprovider-l1-1-0 \ + api-ms-win-eventing-consumer-l1-1-0 \ + api-ms-win-eventing-controller-l1-1-0 \ + api-ms-win-eventing-legacy-l1-1-0 \ + api-ms-win-eventing-provider-l1-1-0 \ + api-ms-win-eventlog-legacy-l1-1-0 \ + api-ms-win-gdi-dpiinfo-l1-1-0 \ + api-ms-win-mm-joystick-l1-1-0 \ + api-ms-win-mm-misc-l1-1-1 api-ms-win-mm-mme-l1-1-0 \ + api-ms-win-mm-time-l1-1-0 \ + api-ms-win-ntuser-dc-access-l1-1-0 \ + api-ms-win-ntuser-rectangle-l1-1-0 \ + api-ms-win-ntuser-sysparams-l1-1-0 \ + api-ms-win-perf-legacy-l1-1-0 \ + api-ms-win-power-base-l1-1-0 \ + api-ms-win-power-setting-l1-1-0 \ + api-ms-win-rtcore-ntuser-draw-l1-1-0 \ + api-ms-win-rtcore-ntuser-private-l1-1-0 \ + api-ms-win-rtcore-ntuser-private-l1-1-4 \ + api-ms-win-rtcore-ntuser-window-l1-1-0 \ + api-ms-win-rtcore-ntuser-winevent-l1-1-0 \ + api-ms-win-rtcore-ntuser-wmpointer-l1-1-0 \ + api-ms-win-rtcore-ntuser-wmpointer-l1-1-3 \ + api-ms-win-security-activedirectoryclient-l1-1-0 \ + api-ms-win-security-audit-l1-1-1 \ + api-ms-win-security-base-l1-1-0 \ + api-ms-win-security-base-l1-2-0 \ + api-ms-win-security-base-private-l1-1-1 \ + api-ms-win-security-credentials-l1-1-0 \ + api-ms-win-security-cryptoapi-l1-1-0 \ + api-ms-win-security-grouppolicy-l1-1-0 \ + api-ms-win-security-lsalookup-l1-1-0 \ + api-ms-win-security-lsalookup-l1-1-1 \ + api-ms-win-security-lsalookup-l2-1-0 \ + api-ms-win-security-lsalookup-l2-1-1 \ + api-ms-win-security-lsapolicy-l1-1-0 \ + api-ms-win-security-provider-l1-1-0 \ + api-ms-win-security-sddl-l1-1-0 \ + api-ms-win-security-systemfunctions-l1-1-0 \ + api-ms-win-service-core-l1-1-0 \ + api-ms-win-service-core-l1-1-1 \ + api-ms-win-service-management-l1-1-0 \ + api-ms-win-service-management-l2-1-0 \ + api-ms-win-service-private-l1-1-1 \ + api-ms-win-service-winsvc-l1-1-0 \ + api-ms-win-service-winsvc-l1-2-0 \ + api-ms-win-shcore-obsolete-l1-1-0 \ + api-ms-win-shcore-scaling-l1-1-1 \ + api-ms-win-shcore-stream-l1-1-0 \ + api-ms-win-shcore-thread-l1-1-0 \ + api-ms-win-shell-shellcom-l1-1-0 \ + api-ms-win-shell-shellfolders-l1-1-0 apphelp \ + appwiz.cpl atl atl100 atl110 atl80 atl90 atmlib \ + authz avicap32 avifil32 avrt bcrypt bluetoothapis \ + browseui bthprops.cpl cabinet cards cdosys cfgmgr32 \ + clusapi combase comcat comctl32 comdlg32 compstui \ + comsvcs concrt140 connect credui crtdll crypt32 \ + cryptdlg cryptdll cryptext cryptnet cryptui ctapi32 \ + ctl3d32 d2d1 d3d10 d3d10_1 d3d10core d3d11 d3d12 d3d8 \ + d3d9 d3dcompiler_33 d3dcompiler_34 d3dcompiler_35 \ + d3dcompiler_36 d3dcompiler_37 d3dcompiler_38 \ + d3dcompiler_39 d3dcompiler_40 d3dcompiler_41 \ + d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 \ + d3dcompiler_47 d3dim d3drm d3dx10_33 d3dx10_34 \ + d3dx10_35 d3dx10_36 d3dx10_37 d3dx10_38 d3dx10_39 \ + d3dx10_40 d3dx10_41 d3dx10_42 d3dx10_43 d3dx11_42 \ + d3dx11_43 d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 \ + d3dx9_28 d3dx9_29 d3dx9_30 d3dx9_31 d3dx9_32 d3dx9_33 \ + d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37 d3dx9_38 d3dx9_39 \ + d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43 d3dxof davclnt \ + dbgeng dciman32 ddrawex devenum dhcpcsvc dhtmled.ocx \ + difxapi dinput dinput8 dispex dmband dmcompos dmime \ + dmloader dmscript dmstyle dmsynth dmusic dmusic32 \ + dnsapi dplay dplayx dpnaddr dpnet dpnhpast dpnlobby \ + dpvoice dpwsockx drmclien dsound dsquery dssenh \ + dswave dwmapi dwrite dx8vb dxdiagn dxgi dxva2 esent \ + evr explorerframe ext-ms-win-authz-context-l1-1-0 \ + ext-ms-win-domainjoin-netjoin-l1-1-0 \ + ext-ms-win-dwmapi-ext-l1-1-0 \ + ext-ms-win-gdi-dc-create-l1-1-1 \ + ext-ms-win-gdi-dc-l1-2-0 ext-ms-win-gdi-devcaps-l1-1-0 \ + ext-ms-win-gdi-draw-l1-1-1 \ + ext-ms-win-gdi-render-l1-1-0 \ + ext-ms-win-kernel32-package-current-l1-1-0 \ + ext-ms-win-kernel32-package-l1-1-1 \ + ext-ms-win-ntuser-draw-l1-1-0 \ + ext-ms-win-ntuser-gui-l1-3-0 \ + ext-ms-win-ntuser-keyboard-l1-3-0 \ + ext-ms-win-ntuser-message-l1-1-1 \ + ext-ms-win-ntuser-misc-l1-2-0 \ + ext-ms-win-ntuser-misc-l1-5-1 \ + ext-ms-win-ntuser-mouse-l1-1-0 \ + ext-ms-win-ntuser-private-l1-1-1 \ + ext-ms-win-ntuser-private-l1-3-1 \ + ext-ms-win-ntuser-rectangle-ext-l1-1-0 \ + ext-ms-win-ntuser-uicontext-ext-l1-1-0 \ + ext-ms-win-ntuser-windowclass-l1-1-1 \ + ext-ms-win-ntuser-window-l1-1-1 \ + ext-ms-win-ntuser-window-l1-1-4 \ + ext-ms-win-oleacc-l1-1-0 \ + ext-ms-win-ras-rasapi32-l1-1-0 \ + ext-ms-win-rtcore-gdi-devcaps-l1-1-0 \ + ext-ms-win-rtcore-gdi-object-l1-1-0 \ + ext-ms-win-rtcore-gdi-rgn-l1-1-0 \ + ext-ms-win-rtcore-ntuser-cursor-l1-1-0 \ + ext-ms-win-rtcore-ntuser-dc-access-l1-1-0 \ + ext-ms-win-rtcore-ntuser-dpi-l1-1-0 \ + ext-ms-win-rtcore-ntuser-dpi-l1-2-0 \ + ext-ms-win-rtcore-ntuser-rawinput-l1-1-0 \ + ext-ms-win-rtcore-ntuser-syscolors-l1-1-0 \ + ext-ms-win-rtcore-ntuser-sysparams-l1-1-0 \ + ext-ms-win-security-credui-l1-1-0 \ + ext-ms-win-security-cryptui-l1-1-0 \ + ext-ms-win-uxtheme-themes-l1-1-0 faultrep feclient \ + fltlib fltmgr.sys fntcache fontsub fusion fwpuclnt \ + gameux gdiplus gpkcsp hal hhctrl.ocx hid hidclass.sys \ + hlink hnetcfg httpapi iccvid ieframe ieproxy \ + imaadp32.acm imagehlp imm32 inetcomm inetcpl.cpl \ + inetmib1 infosoft initpki inkobj inseng iprop \ + irprops.cpl itircl itss joy.cpl jscript jsproxy \ + kerberos kernelbase ksuser ktmw32 loadperf localspl \ + localui lz32 mapi32 mapistub mciavi32 mcicda mciqtz32 \ + mciseq mciwave mf mf3216 mfplat mfreadwrite mgmtapi \ + midimap mlang mmcndmgr mmdevapi mp3dmod mpr mprapi \ + msacm32 msadp32.acm msasn1 mscat32 mscms mscoree \ + msctf msctfp msdaps msdelta msdmo msdrm msftedit \ + msg711.acm msgsm32.acm mshtml msi msident msimg32 \ + msimsg msimtf msisip msisys.ocx msls31 msnet32 \ + mspatcha msports msrle32 msscript.ocx mssign32 \ + mssip32 mstask msvcirt msvcm80 msvcm90 msvcp100 \ + msvcp110 msvcp120 msvcp120_app msvcp140 msvcp60 \ + msvcp70 msvcp71 msvcp80 msvcp90 msvcr100 msvcr110 \ + msvcr120 msvcr120_app msvcr70 msvcr71 msvcr80 \ + msvcr90 msvcrt msvcrt20 msvcrt40 msvcrtd msvfw32 \ + msvidc32 msxml msxml2 msxml3 msxml4 msxml6 mtxdm \ + ncrypt nddeapi ndis.sys netapi32 netcfgx netprofm \ + newdev ninput normaliz npmshtml npptools ntdsapi \ + ntprint objsel odbc32 odbccp32 odbccu32 ole32 oleacc \ + oleaut32 olecli32 oledb32 oledlg olepro32 olesvr32 \ + olethk32 opcservices openal32 opencl packager pdh \ + photometadatahandler pidgen powrprof printui prntvpt \ + propsys psapi pstorec qcap qedit qmgr qmgrprxy \ + quartz query qwave rasapi32 rasdlg regapi resutils \ + riched20 riched32 rpcrt4 rsabase rsaenh rstrtmgr \ + rtutils samlib sapi sas scarddlg sccbase schannel \ + schedsvc scrobj scrrun scsiport.sys security sensapi \ + serialui setupapi sfc sfc_os shcore shdoclc shdocvw \ + shell32 shfolder shlwapi slbcsp slc snmpapi softpub \ + spoolss srclient sspicli sti strmdll svrapi sxs \ + t2embed tapi32 taskschd tdh tdi.sys traffic tzres \ + ucrtbase uiautomationcore uiribbon updspapi url \ + urlmon usbd.sys userenv usp10 uxtheme vbscript \ + vcomp vcomp100 vcomp110 vcomp120 vcomp140 vcomp90 \ + vcruntime140 version virtdisk vssapi vulkan-1 wbemdisp \ + wbemprox wdscore webservices wer wevtapi wiaservc \ + wimgapi windowscodecs windowscodecsext winebus.sys \ + winegstreamer winehid.sys winemapi winevulkan wing32 \ + winhttp wininet winnls32 winscard winsta wintrust \ + winusb wlanapi wldap32 wmasf wmi wmiutils wmp wmphoto \ + wmvcore wpc wpcap wsdapi wshom.ocx wsnmp32 wtsapi32 \ + wuapi wuaueng x3daudio1_0 x3daudio1_1 x3daudio1_2 \ + x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 \ + x3daudio1_7 xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 \ + xapofx1_5 xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 \ + xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7 xaudio2_8 \ + xaudio2_9 xinput1_1 xinput1_2 xinput1_3 xinput1_4 \ + xinput9_1_0 xmllite xolehlp xpsprint xpssvcs \ + + # blank line so you don't have to remove the extra trailing \ +} + +w_override_app_dlls() +{ + w_skip_windows w_override_app_dlls && return + + _W_app=$1 + shift + _W_mode=$1 + shift + + # Fixme: handle comma-separated list of modes + case ${_W_mode} in + b|builtin) _W_mode=builtin ;; + n|native) _W_mode=native ;; + default) _W_mode=default ;; + d|disabled) _W_mode="" ;; + *) + w_die "w_override_app_dlls: unknown mode ${_W_mode}. (want native, builtin, default, or disabled) +Usage: 'w_override_app_dlls app mode dll ...'." ;; + esac + + echo "Using ${_W_mode} override for following DLLs when running ${_W_app}: $*" + ( + echo REGEDIT4 + echo "" + echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\${_W_app}\\DllOverrides]" + ) > "${W_TMP}"/override-dll.reg + + while test "$1" != ""; do + w_common_override_dll "${_W_mode}" "$1" + shift + done + + w_try_regedit "${W_TMP_WIN}"\\override-dll.reg + w_try rm "${W_TMP}"/override-dll.reg + unset _W_app _W_mode +} + +# Has to be set in a few places... +w_set_winver() +{ + w_skip_windows w_set_winver && return + + _W_winver="$1" + + if w_wine_version_in 5.7, ; then + # Make sure we pass the right version name: + case "${_W_winver}" in + # These are the mismatched ones: + # winecfg doesn't accept 'default' as an option (as of wine-5.9): + # https://bugs.winehq.org/show_bug.cgi?id=49241 + # For now, assuming win7: + default) _W_winver="win7";; + win2k3) _W_winver="win2003";; + win2k8) _W_winver="win2008";; + win2k8r2) _W_winver="win2008r2";; + + # xp has two entries (winxp/winxp64): + winxp) + if [ "${W_ARCH}" = "win64" ]; then + _W_winver="winxp64" + else + _W_winver="winxp" + fi + ;; + # These are the same: + nt351|nt40|vista|win10|win20|win2k|win30|win31|win7|win8|win81|win95|win98|winme) : ;; + *) w_die "Unsupported Windows version ${_W_winver}";; + esac + + w_try "${WINE}" winecfg -v "${_W_winver}" + else + # FIXME: remove this after wine-7.0 (i.e., after it's been in stable wine for a while): + + # First, delete any lingering version info, otherwise it may conflict: + ( + "${WINE}" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v SubVersionNumber /f || true + "${WINE}" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v VersionNumber /f || true + "${WINE}" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CSDVersion /f || true + "${WINE}" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentBuildNumber /f || true + "${WINE}" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentVersion /f || true + "${WINE}" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true + "${WINE}" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ServiceCurrent" /v OS /f || true + "${WINE}" reg delete "HKLM\\System\\CurrentControlSet\\Control\\Windows" /v CSDVersion /f || true + "${WINE}" reg delete "HKCU\\Software\\Wine" /v Version /f || true + "${WINE}" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true + ) > /dev/null 2>&1 + + case "${_W_winver}" in + win31) + echo "Setting Windows version to ${_W_winver}" + cat > "${W_TMP}"/set-winver.reg <<_EOF_ +REGEDIT4 + +[HKEY_USERS\\S-1-5-4\\Software\\Wine] +"Version"="win31" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + return + ;; + win95) + # This key is only used for Windows 95/98: + + echo "Setting Windows version to ${_W_winver}" + cat > "${W_TMP}"/set-winver.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion] +"ProductName"="Microsoft Windows 95" +"SubVersionNumber"="" +"VersionNumber"="4.0.950" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + return + ;; + win98) + # This key is only used for Windows 95/98: + + echo "Setting Windows version to ${_W_winver}" + cat > "${W_TMP}"/set-winver.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion] +"ProductName"="Microsoft Windows 98" +"SubVersionNumber"=" A " +"VersionNumber"="4.10.2222" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + return + ;; + nt40) + # Similar to modern version, but sets two extra keys: + + echo "Setting Windows version to ${_W_winver}" + cat > "${W_TMP}"/set-winver.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion] +"CSDVersion"="Service Pack 6a" +"CurrentBuildNumber"="1381" +"CurrentVersion"="4.0" + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ProductOptions] +"ProductType"="WinNT" + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ServiceCurrent] +"OS"="Windows_NT" + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows] +"CSDVersion"=dword:00000600 + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + return + ;; + win2k) + csdversion="Service Pack 4" + currentbuildnumber="2195" + currentversion="5.0" + csdversion_hex=dword:00000400 + ;; + winxp) + # Special case, afaik it's the only Windows version that has different version numbers for 32/64-bit + # So ensure we set the arch appropriate version: + if [ "${W_ARCH}" = "win32" ]; then + csdversion="Service Pack 3" + currentbuildnumber="2600" + currentversion="5.1" + csdversion_hex=dword:00000300 + elif [ "${W_ARCH}" = "win64" ]; then + csdversion="Service Pack 2" + currentbuildnumber="3790" + currentversion="5.2" + csdversion_hex=dword:00000200 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + else + w_die "Invalid W_ARCH ${W_ARCH}" + fi + ;; + win2k3) + csdversion="Service Pack 2" + currentbuildnumber="3790" + currentversion="5.2" + csdversion_hex=dword:00000200 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f + ;; + vista) + csdversion="Service Pack 2" + currentbuildnumber="6002" + currentversion="6.0" + csdversion_hex=dword:00000200 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + ;; + win7|default) + csdversion="Service Pack 1" + currentbuildnumber="7601" + currentversion="6.1" + csdversion_hex=dword:00000100 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + ;; + win2k8) + csdversion="Service Pack 2" + currentbuildnumber="6002" + currentversion="6.0" + csdversion_hex=dword:00000200 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f + ;; + win2k8r2) + csdversion="Service Pack 1" + currentbuildnumber="7601" + currentversion="6.1" + csdversion_hex=dword:00000100 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f + ;; + win8) + csdversion="" + currentbuildnumber="9200" + currentversion="6.2" + csdversion_hex=dword:00000000 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + ;; + win81) + csdversion="" + currentbuildnumber="9600" + currentversion="6.3" + csdversion_hex=dword:00000000 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + ;; + win10) + csdversion="" + currentbuildnumber="10240" + currentversion="10.0" + csdversion_hex=dword:00000000 + "${WINE}" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f + ;; + *) + w_die "Invalid Windows version given." + ;; + esac + + echo "Setting Windows version to ${_W_winver}" + cat > "${W_TMP}"/set-winver.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion] +"CSDVersion"="${csdversion}" +"CurrentBuildNumber"="${currentbuildnumber}" +"CurrentVersion"="${currentversion}" + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows] +"CSDVersion"=${csdversion_hex} + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + fi # if w_wine_version_in 5.7, + + # Prevent a race when calling from another verb + w_wineserver -w +} + +w_unset_winver() +{ + w_warn "w_unset_winver() is deprecated, use \'w_set_winver default\' instead" + w_set_winver default +} + +# Present app $1 with the Windows personality $2 +w_set_app_winver() +{ + w_skip_windows w_set_app_winver && return + + _W_app="$1" + _W_version="$2" + echo "Setting ${_W_app} to ${_W_version} mode" + ( + echo REGEDIT4 + echo "" + echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\${_W_app}]" + echo "\"Version\"=\"${_W_version}\"" + ) > "${W_TMP}"/set-winver.reg + + w_try_regedit "${W_TMP_WIN}"\\set-winver.reg + rm "${W_TMP}"/set-winver.reg + unset _W_app +} + +# Usage: w_compare_wine_version OP VALUE +# Note: currently only -ge and -le are supported, +# as well as the special case -bn (between) +# Example: +# if w_compare_wine_version -ge 2.5 ; then +# ... +# fi +# +# Returns true if comparison is valid +w_compare_wine_version() +{ + comparison="$1" + known_wine_val1="$2" + known_wine_val2="$3" + + case "${comparison}" in + # expected value if the comparison is true + -bn) + # If the current wine version matches the lower version, it's a match (the bug is present). + # If it matches the higher version, it's not a match (the bug is fixed in that version). + if [ "${_wine_version_stripped}" = "${known_wine_val1}" ]; then + return "${TRUE}" + elif [ "${_wine_version_stripped}" = "${known_wine_val2}" ]; then + return "${FALSE}" + else + _expected_pos_current_wine="2" + fi + ;; + -ge) _expected_pos_current_wine="2";; + -le) _expected_pos_current_wine="1";; + *) w_die "Unsupported comparison. Only -bn, -ge, and -le are supported" ;; + esac + + # First, check if current wine is equal to either upper or lower wine version: + case "${_wine_version_stripped}" in + "${known_wine_val1}"|"${known_wine_val2}") return "${TRUE}";; + esac + + _pos_current_wine="$(printf "%s\\n%s\\n%s" "${known_wine_val1}" "${_wine_version_stripped}" "${known_wine_val2}" | sort -t. -k 1,1n -k 2,2n -k 3,3n | grep -n "^${_wine_version_stripped}\$" | cut -d : -f1)" + if [ "${_pos_current_wine}" = "${_expected_pos_current_wine}" ] ; then + #echo "true: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine" + #echo "Wine version comparison is true" + return "${TRUE}" + else + #echo "false: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine" + #echo "Wine version comparison is false" + return "${FALSE}" + fi +} + +# Usage: w_wine_version_in range ... +# True if wine version in any of the given ranges +# 'range' can be +# val1, (for >= val1) +# ,val2 (for <= val2) +# val1,val2 (for >= val1 && <= val2) +w_wine_version_in() +{ + for _W_range; do + _W_val1=$(echo "${_W_range}" | sed 's/,.*//') + _W_val2=$(echo "${_W_range}" | sed 's/.*,//') + # If in this range, return true + case ${_W_range} in + ,*) w_compare_wine_version -le "${_W_val2}" && unset _W_range _W_val1 _W_val2 && return "${TRUE}";; + *,) w_compare_wine_version -ge "${_W_val1}" && unset _W_range _W_val1 _W_val2 && return "${TRUE}";; + *) w_compare_wine_version -bn "${_W_val1}" "${_W_val2}" && unset _W_range _W_val1 _W_val2 && return "${TRUE}";; + esac + done + unset _W_range _W_val1 _W_val2 + return "${FALSE}" +} + +# Usage: workaround_wine_bug bugnumber [message] [good-wine-version-range ...] +# Returns true and outputs given msg if the workaround needs to be applied. +# For debugging: if you want to skip a bug's workaround, put the bug number in +# the environment variable WINETRICKS_BLACKLIST to disable it. +w_workaround_wine_bug() +{ + if test "${WINE}" = ""; then + echo "No need to work around wine bug $1 on Windows" + return "${FALSE}" + fi + case "$2" in + [0-9]*) w_die "bug: want message in w_workaround_wine_bug arg 2, got $2" ;; + "") _W_msg="";; + *) _W_msg="-- $2";; + esac + + # shellcheck disable=SC2086 + if test "$3" && w_wine_version_in $3 $4 $5 $6; then + echo "Current Wine does not have Wine bug $1, so not applying workaround" + return "${FALSE}" + fi + + case "$1" in + "${WINETRICKS_BLACKLIST}") + echo "Wine bug $1 workaround blacklisted, skipping" + return "${FALSE}" + ;; + esac + + case ${LANG} in + da*) w_warn "Arbejder uden om wine-fejl ${1} ${_W_msg}" ;; + de*) w_warn "Wine-Fehler ${1} wird umgegangen ${_W_msg}" ;; + pl*) w_warn "Obchodzenie błędu w wine ${1} ${_W_msg}" ;; + pt*) w_warn "Trabalhando em torno do bug do wine ${1} ${_W_msg}" ;; + ru*) w_warn "Обход ошибки ${1} ${_W_msg}" ;; + uk*) w_warn "Обхід помилки ${1} ${_W_msg}" ;; + zh_CN*) w_warn "绕过 wine bug ${1} ${_W_msg}" ;; + zh_TW*|zh_HK*) w_warn "繞過 wine bug ${1} ${_W_msg}" ;; + *) w_warn "Working around wine bug ${1} ${_W_msg}" ;; + esac + + winetricks_stats_log_command "w_workaround_wine_bug-$1" + return "${TRUE}" +} + +# Function for verbs to register themselves so they show up in the menu. +# Example: +# w_metadata wog games \ +# title="World of Goo Demo" \ +# pub="2D Boy" \ +# year="2008" \ +# media="download" \ +# file1="WorldOfGooDemo.1.0.exe" + +w_metadata() +{ + case ${WINETRICKS_OPT_VERBOSE} in + 2) set -x ;; + *) set +x ;; + esac + + # shellcheck disable=SC2154 + if test "${installed_exe1}" || test "${installed_file1}" || test "${publisher}" || test "${year}"; then + w_die "bug: stray metadata tags set: somebody forgot a backslash in a w_metadata somewhere. Run with sh -x to see where." + fi + if winetricks_metadata_exists "$1"; then + w_die "bug: a verb named $1 already exists." + fi + + _W_md_cmd="$1" + _W_category="$2" + file="${WINETRICKS_METADATA}/${_W_category}/$1.vars" + shift + shift + # Echo arguments to file, with double quotes around the values. + # Used to use Perl here, but that was too slow on Cygwin. + for arg; do + # If _W_wine_not_needed is set, we're a list command that isn't list-installed, and can ignore the installed_* errors: + case "${arg}" in + installed_exe1=/*) + if [ -n "${_W_wine_not_needed}" ]; then + # "_W_wine_not_needed set, no installed_exe1" + : + else + w_die "bug: w_metadata ${_W_md_cmd} has a unix path for installed_exe1, should be a windows path" + fi + ;; + installed_file1=/*) + if [ -n "${_W_wine_not_needed}" ]; then + # "_W_wine_not_needed set, no installed_file1" + : + else + w_die "bug: w_metadata ${_W_md_cmd} has a unix path for installed_file1, should be a windows path" + fi + ;; + media=download_manual) + w_die "bug: verb ${_W_md_cmd} has media=download_manual, should be manual_download";; + esac + # Use longest match when stripping value, + # and shortest match when stripping name, + # so descriptions can have embedded equals signs + # FIXME: backslashes get interpreted here. This screws up + # installed_file1 fairly often. Fortunately, we can use forward + # slashes in that variable instead of backslashes. + echo "${arg%%=*}"=\""${arg#*=}"\" + done > "${file}" + echo category='"'"${_W_category}"'"' >> "${file}" + # If the problem described above happens, you'd see errors like this: + # /tmp/w.dank.4650/metadata/dlls/comctl32.vars: 6: Syntax error: Unterminated quoted string + # so check for lines that aren't properly quoted. + + # Do sanity check unless running on Cygwin, where it's way too slow. + case "${W_PLATFORM}" in + windows_cmd) + ;; + *) + if grep '[^"]$' "${file}"; then + w_die "bug: w_metadata ${_W_md_cmd} corrupt, might need forward slashes?" + fi + ;; + esac + unset _W_md_cmd + + # Restore verbosity: + case ${WINETRICKS_OPT_VERBOSE} in + 1|2) set -x ;; + *) set +x ;; + esac +} + +# Function for verbs to register their main executable [or, if name is given, other executables] +# Deprecated. No-op for backwards compatibility +w_declare_exe() +{ + w_warn "w_declare_exe is deprecated, now a noop" +} + +# Checks that a conflicting verb is not already installed in the prefix +# Usage: w_conflicts verb_to_install conflicting_verbs +w_conflicts() +{ + verb="$1" + conflicting_verbs="$2" + + for x in ${conflicting_verbs}; do + if grep -qw "${x}" "${WINEPREFIX}/winetricks.log" 2>/dev/null; then + w_die "error: ${verb} conflicts with ${x}, which is already installed. You can run \`$0 --force ${verb}\` to ignore this check and attempt installation." + fi + done +} + +# Call a verb, don't let it affect environment +# Hope that subshell passes through exit status +# Usage: w_do_call foo [bar] (calls load_foo bar) +# Or: w_do_call foo=bar (also calls load_foo bar) +# Or: w_do_call foo (calls load_foo) +w_do_call() +{ + ( + # Hack.. + if test "${cmd}" = vd; then + load_vd "${arg}" + _W_status=$? + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP}" + mkdir -p "${W_TMP}" + return ${_W_status} + fi + + case "$1" in + *=*) arg=$(echo "$1" | sed 's/.*=//'); cmd=$(echo "$1" | sed 's/=.*//');; + *) cmd=$1; arg=$2 ;; + esac + + # Kludge: use Temp instead of temp to avoid \t expansion in w_try + # but use temp in Unix path because that's what Wine creates, and having both temp and Temp + # causes confusion (e.g. makes vc2005trial fail) + # FIXME: W_TMP is also set in winetricks_set_wineprefix, can we avoid the duplication? + W_TMP="${W_DRIVE_C}/windows/temp/_$1" + W_TMP_WIN="C:\\windows\\Temp\\_$1" + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP}" + mkdir -p "${W_TMP}" + + # Unset all known used metadata values, in case this is a nested call + unset conflicts installed_file1 installed_exe1 + + if winetricks_metadata_exists "$1"; then + # shellcheck disable=SC1090 + . "${WINETRICKS_METADATA}"/*/"${1}.vars" + elif winetricks_metadata_exists "${cmd}"; then + # shellcheck disable=SC1090 + . "${WINETRICKS_METADATA}"/*/"${cmd}.vars" + elif test "${cmd}" = native || test "${cmd}" = disabled || test "${cmd}" = builtin || test "${cmd}" = default; then + # ugly special case - can't have metadata for these verbs until we allow arbitrary parameters + w_override_dlls "${cmd}" "${arg}" + _W_status=$? + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP}" + mkdir -p "${W_TMP}" + return ${_W_status} + else + w_die "No such verb $1" + fi + + # If needed, set the app's wineprefix + case "${W_PLATFORM}" in + windows_cmd|wine_cmd) ;; + *) + case "${_W_category}-${WINETRICKS_OPT_SHAREDPREFIX}" in + apps-0|benchmarks-0|games-0) winetricks_set_wineprefix "${cmd}";; + *) winetricks_set_wineprefix "${_W_prefix_name}";; + esac + # If it's a new wineprefix, give it metadata + if test ! -f "${WINEPREFIX}"/wrapper.cfg; then + echo ww_name=\""${title}"\" > "${WINEPREFIX}"/wrapper.cfg + fi + ;; + esac + + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP}" + mkdir -p "${W_TMP}" + + # Don't install if a conflicting verb is already installed: + # shellcheck disable=SC2154 + if test "${WINETRICKS_FORCE}" != 1 && test "${conflicts}" && test -f "${WINEPREFIX}/winetricks.log"; then + for x in ${conflicts}; do + w_conflicts "$1" "${x}" + done + fi + + # Allow verifying a verb separately from installing it + if test "${WINETRICKS_VERIFY}" = 1 && winetricks_is_installed "$1" && test -z "${WINETRICKS_FORCE}"; then + echo "$1 is already installed. --force wasn't given, --verify was, so re-verifying." + winetricks_verify + return "${TRUE}" + fi + + # Don't install if already installed + if test "${WINETRICKS_FORCE}" != 1 && winetricks_is_installed "$1"; then + echo "$1 already installed, skipping" + return "${TRUE}" + fi + + # We'd like to get rid of W_PACKAGE, but for now, just set it as late as possible. + W_PACKAGE=$1 + w_try "load_${cmd}" "${arg}" + winetricks_stats_log_command "$@" + + # User-specific postinstall hook. + # Source it so the script can call w_download() if needed. + postfile="${WINETRICKS_POST}/$1/$1-postinstall.sh" + if test -f "${postfile}"; then + chmod +x "${postfile}" + # shellcheck disable=SC1090 + . "${postfile}" + fi + + # Verify install + if test "${installed_exe1}" || test "${installed_file1}"; then + if ! winetricks_is_installed "$1"; then + w_die "$1 install completed, but installed file ${_W_file_unix} not found" + fi + fi + + # If the user specified --verify, also run GUI tests: + if test "${WINETRICKS_VERIFY}" = 1; then + winetricks_verify + fi + + # Clean up after this verb + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP}" + mkdir -p "${W_TMP}" + + # Reset whether use of user mount tool + unset W_USE_USERMOUNT + + # Calling subshell must explicitly propagate error code with exit $? + ) || exit $? +} + +# If you want to check exit status yourself, use w_do_call +w_call() +{ + w_try w_do_call "$@" +} + +w_backup_reg_file() +{ + W_reg_file=$1 + + w_get_sha256sum "${W_reg_file}" + + w_try cp "${W_reg_file}" "${W_TMP_EARLY}/_reg_$(echo "${_W_gotsha256sum}" | cut -c1-8)"_$$.reg + + unset W_reg_file _W_gotsha256sum +} + +w_register_font() +{ + W_file=$1 + shift + W_font=$1 + + case $(echo "${W_file}" | tr "[:upper:]" "[:lower:]") in + *.ttf|*.ttc) W_font="${W_font} (TrueType)";; + esac + + # Kludge: use _r to avoid \r expansion in w_try + cat > "${W_TMP}"/_register-font.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts] +"${W_font}"="${W_file}" +_EOF_ + # too verbose + w_try_regedit "${W_TMP_WIN}"\\_register-font.reg + w_backup_reg_file "${W_TMP}"/_register-font.reg + + # Wine also updates the win9x fonts key, so let's do that, too + cat > "${W_TMP}"/_register-font.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts] +"${W_font}"="${W_file}" +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\_register-font.reg + w_backup_reg_file "${W_TMP}"/_register-font.reg + + unset W_file W_font +} + +# Note: we use UTF-16 (little endian) in .reg file for native (non-English) font names. +w_register_font_replacement() +{ + _W_alias=$1 + shift + _W_font=$1 + # UTF-16 BOM (U+FEFF, "0xEF 0xBB 0xBF" in UTF-8) + printf "\357\273\277" | iconv -f UTF-8 -t UTF-16LE > "${W_TMP}"/_register-font-replacements.reg + # Kludge: use _r to avoid \r expansion in w_try + iconv -f UTF-8 -t UTF-16LE >> "${W_TMP}"/_register-font-replacements.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\Replacements] +"${_W_alias}"="${_W_font}" +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\_register-font-replacements.reg + + w_backup_reg_file "${W_TMP}"/_register-font-replacements.reg + + unset _W_alias _W_font +} + +w_append_path() +{ + # Prepend $1 to the Windows path in the registry. + # Use printf %s to avoid interpreting backslashes. + # 2/4 backslashes, not 4/8, see https://github.com/Winetricks/winetricks/issues/932 + _W_NEW_PATH="$(printf %s "$1" | sed 's,\\,\\\\,g')" + _W_WIN_PATH="$(w_expand_env PATH | sed 's,\\,\\\\,g')" + + # FIXME: OS X? https://github.com/Winetricks/winetricks/issues/697 + sed 's/$/\r/' > "${W_TMP}"/path.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment] +"PATH"="${_W_NEW_PATH};${_W_WIN_PATH}" +_EOF_ + + w_try_regedit "${W_TMP_WIN}"\\path.reg + rm -f "${W_TMP}"/path.reg + unset _W_NEW_PATH _W_WIN_PATH +} + +#---- Private Functions ---- + +# Determines downloader to use, etc. +# I.e., things common to w_download_to(), winetricks_download_to_stdout(), and winetricks_stats_report()) +winetricks_download_setup() +{ + # shellcheck disable=SC2104 + case "${WINETRICKS_DOWNLOADER}" in + aria2c|curl|wget|fetch) : ;; + "") if [ -x "$(command -v aria2c 2>/dev/null)" ] ; then + WINETRICKS_DOWNLOADER="aria2c" + elif [ -x "$(command -v wget 2>/dev/null)" ] ; then + WINETRICKS_DOWNLOADER="wget" + elif [ -x "$(command -v curl 2>/dev/null)" ] ; then + WINETRICKS_DOWNLOADER="curl" + elif [ -x "$(command -v fetch 2>/dev/null)" ] ; then + WINETRICKS_DOWNLOADER="fetch" + else + w_die "Please install wget or aria2c (or, if those aren't available, curl)" + fi + ;; + *) w_die "Invalid value ${WINETRICKS_DOWNLOADER} given for WINETRICKS_DOWNLOADER. Possible values: aria2c, curl, wget, fetch" + esac + + # Common values for aria2c/curl/fetch/wget + # Number of retry attempts (not supported by fetch): + WINETRICKS_DOWNLOADER_RETRIES=${WINETRICKS_DOWNLOADER_RETRIES:-3} + # Connection timeout time (in seconds): + WINETRICKS_DOWNLOADER_TIMEOUT=${WINETRICKS_DOWNLOADER_TIMEOUT:-15} + + case "${WINETRICKS_OPT_TORIFY}" in + 1) torify=torify + # torify needs --async-dns=false, see https://github.com/tatsuhiro-t/aria2/issues/613 + aria2c_torify_opts="--async-dns=false" + if [ ! -x "$(command -v torify 2>/dev/null)" ]; then + w_die "--torify was used, but torify is not installed, please install it." ; exit 1 + fi ;; + *) torify= + aria2c_torify_opts="" ;; + esac +} + + +winetricks_dl_url_to_stdout() +{ + winetricks_download_setup + + # Not using w_try here as it adds extra output, breaking things. + # FIXME: add a w_try_quiet() wrapper around w_try() that doesn't print the + # Executing ... stuff, but still does error checking + if [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then + ${torify} wget -q -O - --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --tries "${WINETRICKS_DOWNLOADER_RETRIES}" "$1" + elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then + ${torify} curl -s --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --retry "${WINETRICKS_DOWNLOADER_RETRIES}" "$1" + elif [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then + # aria2c doesn't have support downloading to stdout: + # https://github.com/aria2/aria2/issues/190 + # So instead, download to a temporary directory and cat the file: + stdout_tmpfile="${W_TMP_EARLY}/stdout.tmp" + + if [ -e "${stdout_tmpfile}" ] ; then + rm "${stdout_tmpfile}" + fi + ${torify} aria2c \ + ${aria2c_torify_opts:+"${aria2c_torify_opts}"} \ + --continue \ + --daemon=false \ + --dir="${W_TMP_EARLY}" \ + --enable-rpc=false \ + --input-file='' \ + --max-connection-per-server=5 \ + --out="stdout.tmp" \ + --save-session='' \ + --stream-piece-selector=geom \ + --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --max-tries="${WINETRICKS_DOWNLOADER_RETRIES}" \ + "$1" > /dev/null + cat "${stdout_tmpfile}" + rm "${stdout_tmpfile}" + elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then + # fetch does not support retry count + ${torify} fetch -o - -T "${WINETRICKS_DOWNLOADER_TIMEOUT}" "$1" 2>/dev/null + else + w_die "Please install aria2c, curl, or wget" + fi +} + +winetricks_dl_warning() { + case ${LANG} in + ru*) _W_countrymsg="Скрипт определил, что ваш IP-адрес принадлежит России. Если во время загрузки файлов вы увидите ошибки несоответствия сертификата, перезапустите скрипт с опцией '--torify' или скачайте файлы вручную, например, используя VPN." ;; + pl*) _W_countrymsg="Wykryto, że twój adres IP należy do Rosji. W wypadku problemów z pobieraniem, uruchom z parametrem '--torify' lub pobierz plik manualnie, np. z użyciem VPN." ;; + *) _W_countrymsg="Your IP address has been determined to belong to Russia. If you encounter a certificate error while downloading, please relaunch with the '--torify' option, or download files manually, for instance using VPN." ;; + esac + + # Lookup own country via IP address only once (i.e. don't run this function for every download invocation) + if [ -z "${W_COUNTRY}" ] ; then + W_COUNTRY="$(winetricks_dl_url_to_stdout "https://ipinfo.io/$(winetricks_dl_url_to_stdout "https://ipinfo.io/ip")" | awk -F '"' '/country/{print $4}')" + export W_COUNTRY + + if [ -z "${W_COUNTRY}" ] ; then + export W_COUNTRY="unknown" + fi + fi + + # TODO: Resolve a full country name via https://github.com/umpirsky/country-list/tree/master/data + case "${W_COUNTRY}" in + "RU") w_warn "${_W_countrymsg}" ;; + *) : ;; + esac +} + +winetricks_get_sha256sum_prog() { + # Linux/Solaris: + if [ -x "$(command -v sha256sum 2>/dev/null)" ] ; then + WINETRICKS_SHA256SUM="sha256sum" + # FreeBSD/NetBSD: + elif [ -x "$(command -v sha256 2>/dev/null)" ] ; then + WINETRICKS_SHA256SUM="sha256" + # OSX (10.6+), 10.5 doesn't support at all: https://stackoverflow.com/questions/7500691/rvm-sha256sum-nor-shasum-found + elif [ -x "$(command -v shasum 2>/dev/null)" ] ; then + WINETRICKS_SHA256SUM="shasum -a 256" + else + w_die "No sha256um utility available." + fi +} + +winetricks_get_platform() +{ + if [ "${OS}" = "Windows_NT" ]; then + if [ -n "${WINELOADERNOEXEC}" ]; then + # Windows/Cygwin + export W_PLATFORM="windows_cmd" + else + # wineconsole/cmd under wine + export W_PLATFORM="wine_cmd" + fi + else + # Normal Unix shell + export W_PLATFORM="wine" + fi +} + +winetricks_latest_version_check() +{ + if [ "${WINETRICKS_LATEST_VERSION_CHECK}" = 'disabled' ] || [ -f "${WINETRICKS_CONFIG}/disable-latest-version-check" ] ; then + w_info "winetricks latest version check update disabled" + return + # Used by ./src/release.sh, not for end users. Silently disables update check, without using $WINETRICKS_SUPER_QUIET + elif [ "${WINETRICKS_LATEST_VERSION_CHECK}" = 'development' ] ; then + return + fi + + latest_version="$(winetricks_dl_url_to_stdout https://raw.githubusercontent.com/Winetricks/winetricks/master/files/LATEST)" + + # Check that $latest_version is an actual number in case github is down + if ! echo "${latest_version}" | grep -q -E "[0-9]{8}" || [ -z "${latest_version}" ] ; then + case ${LANG} in + pl*) w_warn "GitHub nie działa? Wersja '${latest_version}' nie wydaje się być prawdiłową wersją" ;; + pt*) w_warn "Github offline? versão '${latest_version}' não parece uma versão válida" ;; + ru*) w_warn "Отсутствует подключение к Github? версия '${latest_version}' может быть неактуальной" ;; + zh_CN*) w_warn "GitHub 无法访问?${latest_version} 似乎不是个有效的版本号。" ;; + zh_TW*|zh_HK*) w_warn "GitHub 宕機了?${latest_version} 似乎不是個有效的版本號。" ;; + *) w_warn "Github down? version '${latest_version}' doesn't appear to be a valid version" ;; + esac + + # If we can't get the latest version, no reason to go further: + return + fi + + if [ ! "${WINETRICKS_VERSION}" = "${latest_version}" ] && [ ! "${WINETRICKS_VERSION}" = "${latest_version}-next" ]; then + if [ -f "${WINETRICKS_CONFIG}/enable-auto-update" ] ; then + w_info "You are running winetricks-${WINETRICKS_VERSION}." + w_info "New upstream release winetricks-${latest_version} is available." + w_info "auto-update enabled: running winetricks_selfupdate" + winetricks_selfupdate + else + case ${LANG} in + pl*) + w_warn "Korzystasz z winetricks-${WINETRICKS_VERSION}, a najnowszą wersją winetricks-${latest_version}!" + w_warn "Zalecana jest aktualizacja z użyciem menedżera pakietów Twojej dystrybucji, --self-update lub ręczna aktualizacja." + ;; + pt*) + w_warn "Você está utilizando o winetricks-${WINETRICKS_VERSION}, a versão mais recente é winetricks-${latest_version}!" + w_warn "Você pode atualizar com o sistema de atualizações da sua distribuição, --self-update, ou manualmente." + ;; + ru*) + w_warn "Запущен winetricks-${WINETRICKS_VERSION}, последняя версия winetricks-${latest_version}!" + w_warn "Вы можете ее обновить с помощью менеджера пакетов, --self-update или вручную." + ;; + zh_CN*) + w_warn "你正在使用 winetricks-${WINETRICKS_VERSION},最新版本是 winetricks-${latest_version}!" + w_warn "你应该使用你的发行版软件管理器、--self-update 或者手动更新。" + ;; + zh_TW*|zh_HK*) + w_warn "你正在使用 winetricks-${WINETRICKS_VERSION},最新版本是 winetricks-${latest_version}!" + w_warn "你應該使用你的發行版軟體管理者、--self-update 或者手動更新。" + ;; + *) + w_warn "You are running winetricks-${WINETRICKS_VERSION}, latest upstream is winetricks-${latest_version}!" + w_warn "You should update using your distribution's package manager, --self-update, or manually." + ;; + esac + fi + fi +} + +winetricks_print_version() +{ + # Normally done by winetricks_init, but we don't want to set up the WINEPREFIX + # just to get the winetricks version: + + winetricks_get_sha256sum_prog + + w_get_sha256sum "$0" + echo "${WINETRICKS_VERSION} - sha256sum: ${_W_gotsha256sum}" +} + +# Run a small wine command for internal use +# Handy place to put small workarounds +winetricks_early_wine() +{ + # The sed works around https://bugs.winehq.org/show_bug.cgi?id=25838 + # which unfortunately got released in wine-1.3.12 + # We would like to use DISPLAY= to prevent virtual desktops from + # popping up, but that causes AutoHotKey's tray icon to not show up. + # We used to use WINEDLLOVERRIDES=mshtml= here to suppress the Gecko + # autoinstall, but that yielded wineprefixes that *never* autoinstalled + # Gecko (winezeug bug 223). + # The tr removes carriage returns so expanded variables don't have crud on the end + # The grep works around using new wineprefixes with old wine + WINEDEBUG=-all "${WINE}" "$@" 2> "${W_TMP_EARLY}"/early_wine.err.txt | ( sed 's/.*1h.=//' | tr -d '\r' | grep -v -e "Module not found" -e "Could not load wine-gecko" || true) +} + +# Wrapper around winetricks_early_wine() +# Same idea, but use $WINE_ARCH, i.e., always use wine64 for 64-bit prefixes +# Currently only used by w_expand_env() +winetricks_early_wine_arch() +{ + WINE="${WINE_ARCH}" winetricks_early_wine "$@" +} + +winetricks_detect_gui() +{ + if [ -n "$1" ]; then + if [ "$1" = "kdialog" ] && test -x "$(command -v kdialog 2>/dev/null)"; then + WINETRICKS_GUI=kdialog + WINETRICKS_GUI_VERSION="$(kdialog --version)" + elif [ "$1" = "zenity" ] || [ "$1" = "--gui" ] && test -x "$(command -v zenity 2>/dev/null)"; then + WINETRICKS_GUI=zenity + WINETRICKS_GUI_VERSION="$(zenity --version)" + WINETRICKS_MENU_HEIGHT=500 + WINETRICKS_MENU_WIDTH=1010 + else + echo "Invalid argument for --gui" + echo "Valid options are 'zenity' and 'kdialog'" + exit 1 + fi + elif [ "${XDG_CURRENT_DESKTOP}" = "KDE" ] && test -x "$(command -v kdialog 2>/dev/null)"; then + WINETRICKS_GUI=kdialog + WINETRICKS_GUI_VERSION="$(kdialog --version)" + elif test -x "$(command -v zenity 2>/dev/null)"; then + WINETRICKS_GUI=zenity + WINETRICKS_GUI_VERSION="$(zenity --version)" + WINETRICKS_MENU_HEIGHT=500 + WINETRICKS_MENU_WIDTH=1010 + elif test -x "$(command -v kdialog 2>/dev/null)"; then + WINETRICKS_GUI=kdialog + WINETRICKS_GUI_VERSION="$(kdialog --version)" + else + echo "No arguments given, so tried to start GUI, but neither zenity" + echo "nor kdialog were found. Please install one of them if you want" + echo "a graphical interface, or run with --help for more options." + exit 1 + fi + + # Print zenity/dialog version info for debugging: + if [ -z "${WINETRICKS_SUPER_QUIET}" ] ; then + echo "winetricks GUI enabled, using ${WINETRICKS_GUI} ${WINETRICKS_GUI_VERSION##kdialog }" + fi +} + +# Detect which sudo to use +winetricks_detect_sudo() +{ + WINETRICKS_SUDO=sudo + if test "${WINETRICKS_GUI}" = "none"; then + return + fi + + if test x"${DISPLAY}" != x""; then + # This should be the default option because some of GUI sudo programs are unmaintained + # See https://github.com/Winetricks/winetricks/issues/912 + if test -x "$(command -v pkexec 2>/dev/null)"; then + # Maintained and recommended, part of Polkit, desktop-independent + # Usage: pkexec command ... + WINETRICKS_SUDO=pkexec + # Austin said "gksu*/kdesu* should stay (at least for a while)" in Feb 2018 + # See https://github.com/Winetricks/winetricks/pull/915#issuecomment-362984379 + elif test -x "$(command -v gksudo 2>/dev/null)"; then + # Unmaintained [2009], part of gksu + # Usage: gksudo "command ..." + WINETRICKS_SUDO=gksudo + elif test -x "$(command -v kdesudo 2>/dev/null)"; then + # Unmaintained [2015] (latest is for KDE4, no KF5 version available) + # https://cgit.kde.org/kdesudo.git/ + # Usage: kdesudo "command ..." + WINETRICKS_SUDO=kdesudo + # fall back to the su versions if sudo isn't available (Fedora, etc.): + elif test -x "$(command -v gksu 2>/dev/null)"; then + # Unmaintained [2009] + # Usage: gksu "command ..." + WINETRICKS_SUDO=gksu + elif test -x "$(command -v kdesu 2>/dev/null)"; then + # Maintained, KF5 version available + # https://cgit.kde.org/kdesu.git/ + # Usage: kdesu -c "command ..." + WINETRICKS_SUDO=kdesu + fi + fi +} + +# Detect which iso mount tool to use +winetricks_detect_iso_mount() +{ + if test -x "$(command -v fuseiso 2>/dev/null)"; then + # File/dir names are converted to lowercase + WINETRICKS_ISO_MOUNT=fuseiso + elif test -x "$(command -v archivemount 2>/dev/null)"; then + # File/dir names may be uppercase and we may need + # case-insensitive operations + # e.g. w_try "$WINE" cmd /c "copy $W_ISO_MOUNT_LETTER:\\DOC.PDF C:\\doc.pdf" + # This tool had path issue in 0.8.8 or older versions + # e.g. office2013pro works in 0.8.9 or later but doesn't work in 0.8.8 + WINETRICKS_ISO_MOUNT=archivemount + elif test -x "$(command -v hdiutil 2>/dev/null)"; then + # File/dir names may be uppercase (same as archivemount) + WINETRICKS_ISO_MOUNT=hdiutil + else + WINETRICKS_ISO_MOUNT=none + fi + # Notes about other tools: + # fuseiso9660: may append ";1" to filenames + # unar: the drive icon is not "optical drive + disc" in Wine Explorer + # and "wine eject" command fails +} + +winetricks_get_prefix_var() +{ + ( + # shellcheck disable=SC1090 + . "${W_PREFIXES_ROOT}/${p}/wrapper.cfg" + + # The cryptic sed is there to turn ' into '\'' + # shellcheck disable=SC1117 + eval echo \$ww_"$1" | sed "s/'/'\\\''/" + ) +} + +# Display prefix menu, get which wineprefix the user wants to work with +winetricks_prefixmenu() +{ + case ${LANG} in + ru*) _W_msg_title="Winetricks - выберите путь wine (wineprefix)" + _W_msg_body='Что вы хотите сделать?' + _W_msg_apps='Установить программу' + _W_msg_games='Установить игру' + _W_msg_benchmarks='Установить приложение для оценки производительности' + _W_msg_default="Выберите путь для wine по умолчанию" + _W_msg_mkprefix="Создать новый путь wine" + _W_msg_unattended0="Отключить автоматическую установку" + _W_msg_unattended1="Включить автоматическую установку" + _W_msg_help="Просмотр справки (в веб-браузере)" + ;; + uk*) _W_msg_title="Winetricks - виберіть wineprefix" + _W_msg_body='Що Ви хочете зробити?' + _W_msg_apps='Встановити додаток' + _W_msg_games='Встановити гру' + _W_msg_benchmarks='Встановити benchmark' + _W_msg_default="Вибрати wineprefix за замовчуванням" + _W_msg_mkprefix="створити новий wineprefix" + _W_msg_unattended0="Вимкнути автоматичне встановлення" + _W_msg_unattended1="Увімкнути автоматичне встановлення" + _W_msg_help="Переглянути довідку" + ;; + zh_CN*) _W_msg_title="Winetricks - 择一 Wine 容器" + _W_msg_body='君欲何为?' + _W_msg_apps='安装一个 Windows 应用' + _W_msg_games='安装一个游戏' + _W_msg_benchmarks='安装一个基准测试软件' + _W_msg_default="选择默认的 Wine 容器" + _W_msg_mkprefix="创建新的 Wine 容器" + _W_msg_unattended0="禁用静默安装" + _W_msg_unattended1="启用静默安装" + _W_msg_help="查看帮助" + ;; + zh_TW*|zh_HK*) _W_msg_title="Winetricks - 取一 Wine 容器" + _W_msg_body='君欲何為?' + _W_msg_apps='安裝一個 Windows 應用' + _W_msg_games='安裝一個遊戲' + _W_msg_benchmarks='安裝一個基准測試軟體' + _W_msg_default="選取預設的 Wine 容器" + _W_msg_mkprefix="建立新的 Wine 容器" + _W_msg_unattended0="禁用靜默安裝" + _W_msg_unattended1="啟用靜默安裝" + _W_msg_help="檢視輔助說明" + ;; + de*) _W_msg_title="Winetricks - wineprefix auswählen" + _W_msg_body='Was möchten Sie tun?' + _W_msg_apps='Ein Programm installieren' + _W_msg_games='Ein Spiel installieren' + _W_msg_benchmarks='Einen Benchmark-Test installieren' + _W_msg_default="Standard wineprefix auswählen" + _W_msg_mkprefix="Neuen wineprefix erstellen" + _W_msg_unattended0="Automatische Installation deaktivieren" + _W_msg_unattended1="Automatische Installation aktivieren" + _W_msg_help="Hilfe anzeigen" + ;; + pl*) _W_msg_title="Winetricks - wybierz prefiks Wine" + _W_msg_body='Co chcesz zrobić?' + _W_msg_apps='Zainstalować aplikację' + _W_msg_games='Zainstalować grę' + _W_msg_benchmarks='Zainstalować program sprawdzający wydajność komputera' + _W_msg_default="Wybrać domyślny prefiks Wine" + _W_msg_mkprefix="Stwórz nowy prefiks Wine" + _W_msg_unattended0="Wyłącz cichą instalację" + _W_msg_unattended1="Włącz cichą instalację" + _W_msg_help="Wyświetl pomoc" + ;; + pt*) _W_msg_title="Winetricks - Escolha um wineprefix" + _W_msg_body='O que você quer fazer?' + _W_msg_apps='Instalar um programa' + _W_msg_games='Instalar um jogo' + _W_msg_benchmarks='Instalar um teste de desempenho/benchmark' + _W_msg_default="Selecionar o prefixo padrão wineprefix" + _W_msg_mkprefix="Criar novo prefixo wineprefix" + _W_msg_unattended0="Desativar instalação silenciosa" + _W_msg_unattended1="Ativar instalação silenciosa" + _W_msg_help="Ver ajuda" + ;; + *) _W_msg_title="Winetricks - choose a wineprefix" + _W_msg_body='What do you want to do?' + _W_msg_apps='Install an application' + _W_msg_games='Install a game' + _W_msg_benchmarks='Install a benchmark' + _W_msg_default="Select the default wineprefix" + _W_msg_mkprefix="Create new wineprefix" + _W_msg_unattended0="Disable silent install" + _W_msg_unattended1="Enable silent install" + _W_msg_help="View help" + ;; + esac + case "${W_OPT_UNATTENDED}" in + 1) _W_cmd_unattended=attended; _W_msg_unattended="${_W_msg_unattended0}" ;; + *) _W_cmd_unattended=unattended; _W_msg_unattended="${_W_msg_unattended1}" ;; + esac + + case ${WINETRICKS_GUI} in + zenity) + printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --radiolist \ + --column '' \ + --column '' \ + --column '' \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + --hide-column 2 \ + FALSE help '${_W_msg_help}' \ + FALSE apps '${_W_msg_apps}' \ + FALSE benchmarks '${_W_msg_benchmarks}' \ + FALSE games '${_W_msg_games}' \ + TRUE main '${_W_msg_default}' \ + FALSE mkprefix '${_W_msg_mkprefix}' \ + " \ + > "${WINETRICKS_WORKDIR}"/zenity.sh + + if ls -d "${W_PREFIXES_ROOT}"/*/dosdevices > /dev/null 2>&1; then + for prefix in "${W_PREFIXES_ROOT}"/*/dosdevices; do + q="${prefix%%/dosdevices}" + p="${q##*/}" + if test -f "${W_PREFIXES_ROOT}/${p}/wrapper.cfg"; then + _W_msg_name="${p} ($(winetricks_get_prefix_var name))" + else + _W_msg_name="${p}" + fi + case ${LANG} in + zh_CN*) printf %s " FALSE prefix='${p}' '选择管理 ${_W_msg_name}' " ;; + zh_TW*|zh_HK*) printf %s " FALSE prefix='${p}' '選擇管理 ${_W_msg_name}' " ;; + de*) printf %s " FALSE prefix='${p}' '${_W_msg_name} auswählen' " ;; + pl*) printf %s " FALSE prefix='${p}' 'Wybierz ${_W_msg_name}' " ;; + pt*) printf %s " FALSE prefix='${p}' 'Selecione ${_W_msg_name}' " ;; + *) printf %s " FALSE prefix='${p}' 'Select ${_W_msg_name}' " ;; + esac + done >> "${WINETRICKS_WORKDIR}"/zenity.sh + fi + printf %s " FALSE ${_W_cmd_unattended} '${_W_msg_unattended}'" >> "${WINETRICKS_WORKDIR}"/zenity.sh + + sh "${WINETRICKS_WORKDIR}"/zenity.sh | tr '|' ' ' + ;; + + kdialog) + ( + printf %s "kdialog \ + --geometry 600x400+100+100 \ + --title '${_W_msg_title}' \ + --separate-output \ + --radiolist '${_W_msg_body}' \ + help '${_W_msg_help}' off \ + games '${_W_msg_games}' off \ + benchmarks '${_W_msg_benchmarks}' off \ + apps '${_W_msg_apps}' off \ + main '${_W_msg_default}' on \ + mkprefix '${_W_msg_mkprefix}' off \ + " + if ls -d "${W_PREFIXES_ROOT}"/*/dosdevices > /dev/null 2>&1; then + for prefix in "${W_PREFIXES_ROOT}"/*/dosdevices; do + q="${prefix%%/dosdevices}" + p="${q##*/}" + if test -f "${W_PREFIXES_ROOT}/${p}/wrapper.cfg"; then + _W_msg_name="${p} ($(winetricks_get_prefix_var name))" + else + _W_msg_name="${p}" + fi + printf %s "prefix='${p}' 'Select ${_W_msg_name}' off " + done + fi + printf %s " ${_W_cmd_unattended} '${_W_msg_unattended}' off" + ) > "${WINETRICKS_WORKDIR}"/kdialog.sh + sh "${WINETRICKS_WORKDIR}"/kdialog.sh + ;; + esac + unset _W_msg_help _W_msg_body _W_msg_title _W_msg_new _W_msg_default _W_msg_name +} + +# Graphically create new custom wineprefix. +# This returns two verbs: arch and prefix, e.g. "arch=32 prefix=test". +winetricks_mkprefixmenu() +{ + case ${LANG} in + # TODO: translate to other languages + de) _W_msg_title="Winetricks - Neues Wineprefix erstellen" + _W_msg_name="Name" + _W_msg_arch="Architektur" + ;; + pt*) _W_msg_title="Winetricks - criar novo wineprefix" + _W_msg_name="Nome" + _W_msg_arch="Arquitetura" + ;; + *) _W_msg_title="Winetricks - create new wineprefix" + _W_msg_name="Name" + _W_msg_arch="Architecture" + ;; + esac + + case ${WINETRICKS_GUI} in + zenity) + ${WINETRICKS_GUI} --forms --text="" --title "${_W_msg_title}" \ + --add-combo="${_W_msg_arch}" --combo-values=32\|64 \ + --add-entry="${_W_msg_name}" \ + | sed -e 's/^\s*|/64|/' -e 's/^/arch=/' -e 's/|/ prefix=/' + ;; + kdialog) + ${WINETRICKS_GUI} --title="${_W_msg_title}" \ + --radiolist="${_W_msg_arch}" 32 32bit off 64 64bit on \ + | sed -e 's/^$/64/' -e 's/^/arch=/' + ${WINETRICKS_GUI} --title="${_W_msg_title}" --inputbox="${_W_msg_name}" \ + | sed -e 's/^/prefix=/' + ;; + esac + + unset _W_msg_title _W_msg_name _W_msg_arch +} + +# Display main menu, get which submenu the user wants +winetricks_mainmenu() +{ + case ${LANG} in + da*) _W_msg_title="Vælg en pakke-kategori - Nuværende præfiks er \"${WINEPREFIX}\"" + _W_msg_body='Hvad ønsker du at gøre?' + _W_msg_dlls="Install a Windows DLL" + _W_msg_fonts='Install a font' + _W_msg_settings='Change Wine settings' + _W_msg_winecfg='Run winecfg' + _W_msg_regedit='Run regedit' + _W_msg_taskmgr='Run taskmgr' + _W_msg_explorer='Run explorer' + _W_msg_uninstaller='Run uninstaller' + _W_msg_shell='Run a commandline shell (for debugging)' + _W_msg_folder='Browse files' + _W_msg_annihilate="Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX" + ;; + de*) _W_msg_title="Pakettyp auswählen - Aktueller Präfix ist \"${WINEPREFIX}\"" + _W_msg_body='Was möchten Sie tun?' + _W_msg_dlls="Windows-DLL installieren" + _W_msg_fonts='Schriftart installieren' + _W_msg_settings='Wine Einstellungen ändern' + _W_msg_winecfg='winecfg starten' + _W_msg_regedit='regedit starten' + _W_msg_taskmgr='taskmgr starten' + _W_msg_explorer='explorer starten' + _W_msg_uninstaller='uninstaller starten' + _W_msg_shell='Eine Kommandozeile zum debuggen starten' + _W_msg_folder='Ordner durchsuchen' + _W_msg_annihilate="ALLE DATEIEN UND PROGRAMME IN DIESEM WINEPREFIX Löschen" + ;; + pl*) _W_msg_title="Winetricks - obecny prefiks to \"${WINEPREFIX}\"" + _W_msg_body='Co chcesz zrobić w tym prefiksie?' + _W_msg_dlls="Zainstalować windowsową bibliotekę DLL lub komponent" + _W_msg_fonts='Zainstalować czcionkę' + _W_msg_settings='Zmienić ustawienia' + _W_msg_winecfg='Uruchomić winecfg' + _W_msg_regedit='Uruchomić edytor rejestru' + _W_msg_taskmgr='Uruchomić menedżer zadań' + _W_msg_explorer='Uruchomić explorer' + _W_msg_uninstaller='Uruchomić program odinstalowujący' + _W_msg_shell='Uruchomić powłokę wiersza poleceń (dla debugowania)' + _W_msg_folder='Przeglądać pliki' + _W_msg_annihilate="Usuńąć WSZYSTKIE DANE I APLIKACJE WEWNĄTRZ TEGO PREFIKSU WINE" + ;; + pt*) _W_msg_title="Winetricks - o prefixo atual é \"${WINEPREFIX}\"" + _W_msg_body='O que você gostaria de fazer com este prefixo wineprefix?' + _W_msg_dlls="Instalar DLL ou componente do Windows" + _W_msg_fonts='Instalar fontes' + _W_msg_settings='Alterar configurações' + _W_msg_winecfg='Executar winecfg' + _W_msg_regedit='Executar regedit' + _W_msg_taskmgr='Executar taskmgr' + _W_msg_explorer='Executar explorer' + _W_msg_uninstaller='Executar desinstalador' + _W_msg_shell='Executar linha de comandos shell (para depuração)' + _W_msg_folder='Gerenciar arquivos' + _W_msg_annihilate="Apagar TODOS OS DADOS E APLICATIVOS DENTRO DESTE WINEPREFIX" + ;; + ru*) _W_msg_title="Winetricks - текущий путь для wine (wineprefix) \"${WINEPREFIX}\"" + _W_msg_body='Что вы хотите сделать с этим wineprefix?' + _W_msg_dlls="Установить библиотеку DLL или компонент Windows" + _W_msg_fonts='Установить шрифт' + _W_msg_settings='Поменять настройки' + _W_msg_winecfg='Запустить winecfg (редактор настроек wine)' + _W_msg_regedit='Запустить regedit (редактор реестра)' + _W_msg_taskmgr='Запустить taskmgr (менеджер задач)' + _W_msg_explorer='Запустить explorer' + _W_msg_uninstaller='Запустить uninstaller (деинсталлятор)' + _W_msg_shell='Запустить графический терминал (для отладки)' + _W_msg_folder='Проводник файлов' + _W_msg_annihilate="Удалить ВСЕ ДАННЫЕ И ПРИЛОЖЕНИЯ В ЭТОМ WINEPREFIX" + ;; + uk*) _W_msg_title="Winetricks - поточний prefix \"${WINEPREFIX}\"" + _W_msg_body='Що Ви хочете зробити для цього wineprefix?' + _W_msg_dlls="Встановити Windows DLL чи компонент(и)" + _W_msg_fonts='Встановити шрифт' + _W_msg_settings='Змінити налаштування' + _W_msg_winecfg='Запустити winecfg' + _W_msg_regedit='Запустити regedit' + _W_msg_taskmgr='Запустити taskmgr' + _W_msg_explorer='Запустити explorer' + _W_msg_uninstaller='Встановлення/видалення програм' + _W_msg_shell='Запуск командної оболонки (для налагодження)' + _W_msg_folder='Перегляд файлів' + _W_msg_annihilate="Видалити УСІ ДАНІ ТА ПРОГРАМИ З ЦЬОГО WINEPREFIX" + ;; + zh_CN*) _W_msg_title="Winetricks - 当前容器路径是 \"${WINEPREFIX}\"" + _W_msg_body='管理当前容器' + _W_msg_dlls="安装 Windows DLL 或组件" + _W_msg_fonts='安装字体' + _W_msg_settings='修改设置' + _W_msg_winecfg='运行 Wine 配置程序' + _W_msg_regedit='运行注册表' + _W_msg_taskmgr='运行任务管理器' + _W_msg_explorer='运行资源管理器' + _W_msg_uninstaller='运行卸载程序' + _W_msg_shell='运行命令提示窗口 (作为调试)' + _W_msg_folder='浏览容器中的文件' + _W_msg_annihilate="删除容器中所有数据和应用程序" + ;; + zh_TW*|zh_HK*) _W_msg_title="Winetricks - 目前容器路徑是 \"${WINEPREFIX}\"" + _W_msg_body='管理目前容器' + _W_msg_dlls="安裝 Windows DLL 或套件" + _W_msg_fonts='安裝字型' + _W_msg_settings='修改設定' + _W_msg_winecfg='執行 Wine 設定程式' + _W_msg_regedit='執行登錄編輯程式' + _W_msg_taskmgr='執行工作管理員' + _W_msg_explorer='執行檔案總管' + _W_msg_uninstaller='執行解除安裝程式' + _W_msg_shell='執行命令提示視窗 (作為偵錯)' + _W_msg_folder='瀏覽容器中的檔案' + _W_msg_annihilate="刪除容器中所有資料和應用程式" + ;; + *) _W_msg_title="Winetricks - current prefix is \"${WINEPREFIX}\"" + _W_msg_body='What would you like to do to this wineprefix?' + _W_msg_dlls="Install a Windows DLL or component" + _W_msg_fonts='Install a font' + _W_msg_settings='Change settings' + _W_msg_winecfg='Run winecfg' + _W_msg_regedit='Run regedit' + _W_msg_taskmgr='Run taskmgr' + _W_msg_explorer='Run explorer' + _W_msg_uninstaller='Run uninstaller' + _W_msg_shell='Run a commandline shell (for debugging)' + _W_msg_folder='Browse files' + _W_msg_annihilate="Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX" + ;; + esac + + case ${WINETRICKS_GUI} in + zenity) + ( + printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --radiolist \ + --column '' \ + --column '' \ + --column '' \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + --hide-column 2 \ + FALSE dlls '${_W_msg_dlls}' \ + FALSE fonts '${_W_msg_fonts}' \ + FALSE settings '${_W_msg_settings}' \ + FALSE winecfg '${_W_msg_winecfg}' \ + FALSE regedit '${_W_msg_regedit}' \ + FALSE taskmgr '${_W_msg_taskmgr}' \ + FALSE explorer '${_W_msg_explorer}' \ + FALSE uninstaller '${_W_msg_uninstaller}' \ + FALSE shell '${_W_msg_shell}' \ + FALSE folder '${_W_msg_folder}' \ + FALSE annihilate '${_W_msg_annihilate}' \ + " + ) > "${WINETRICKS_WORKDIR}"/zenity.sh + + sh "${WINETRICKS_WORKDIR}"/zenity.sh | tr '|' ' ' + ;; + + kdialog) + ${WINETRICKS_GUI} --geometry 600x400+100+100 \ + --title "${_W_msg_title}" \ + --separate-output \ + --radiolist \ + "${_W_msg_body}"\ + dlls "${_W_msg_dlls}" off \ + fonts "${_W_msg_fonts}" off \ + settings "${_W_msg_settings}" off \ + winecfg "${_W_msg_winecfg}" off \ + regedit "${_W_msg_regedit}" off \ + taskmgr "${_W_msg_taskmgr}" off \ + explorer "${_W_msg_explorer}" off \ + uninstaller "${_W_msg_uninstaller}" off \ + shell "${_W_msg_shell}" off \ + folder "${_W_msg_folder}" off \ + annihilate "${_W_msg_annihilate}" off \ + ${_W_cmd_unattended} "${_W_msg_unattended}" off \ + + ;; + esac + unset _W_msg_body _W_msg_title _W_msg_apps _W_msg_benchmarks _W_msg_dlls _W_msg_games _W_msg_settings +} + +winetricks_settings_menu() +{ + # FIXME: these translations should really be centralized/reused: + case ${LANG} in + da*) _W_msg_title="Vælg en pakke - Nuværende præfiks er \"${WINEPREFIX}\"" + _W_msg_body='Which settings would you like to change?' + ;; + de*) _W_msg_title="Winetricks - Aktueller Präfix ist \"${WINEPREFIX}\"" + _W_msg_body='Welche Einstellungen möchten Sie ändern?' + ;; + pl*) _W_msg_title="Winetricks - obecny prefiks to \"${WINEPREFIX}\"" + _W_msg_body='Jakie ustawienia chcesz zmienić?' + ;; + pt*) _W_msg_title="Winetricks - o prefixo atual é \"${WINEPREFIX}\"" + _W_msg_body='Quais configurações você gostaria de alterar?' + ;; + ru*) _W_msg_title="Winetricks - текущий путь wine (wineprefix) \"${WINEPREFIX}\"" + _W_msg_body='Какие настройки вы хотите изменить?' + ;; + uk*) _W_msg_title="Winetricks - поточний prefix \"${WINEPREFIX}\"" + _W_msg_body='Які налаштування Ви хочете змінити?' + ;; + zh_CN*) _W_msg_title="Winetricks - 当前容器路径是 \"${WINEPREFIX}\"" + _W_msg_body='您想要更改哪项设置?' + ;; + zh_TW*|zh_HK*) _W_msg_title="Winetricks - 目前容器路徑是 \"${WINEPREFIX}\"" + _W_msg_body='您想要變更哪項設定?' + ;; + *) _W_msg_title="Winetricks - current prefix is \"${WINEPREFIX}\"" + _W_msg_body='Which settings would you like to change?' + ;; + esac + + case ${WINETRICKS_GUI} in + zenity) + case ${LANG} in + da*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Pakke \ + --column Navn \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + de*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Einstellung \ + --column Name \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + pl*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Ustawienie \ + --column Nazwa \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + pt*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Configuração \ + --column Título \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + ru*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Установка \ + --column Имя \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + uk*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Установка \ + --column Назва \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + zh_CN*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column 设置 \ + --column 标题 \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + zh_TW*|zh_HK*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column 設定 \ + --column 標題 \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + *) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Setting \ + --column Title \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + esac > "${WINETRICKS_WORKDIR}"/zenity.sh + + for metadatafile in "${WINETRICKS_METADATA}/${WINETRICKS_CURMENU}"/*.vars; do + code=$(winetricks_metadata_basename "${metadatafile}") + ( + title='?' + # shellcheck disable=SC1090 + . "${metadatafile}" + + # Begin 'title' strings localization code + # shellcheck disable=SC2154 + case ${LANG} in + uk*) + case "${title_uk}" in + "") ;; + *) title="${title_uk}";; + esac + esac + + # End of code + printf "%s %s %s %s" " " FALSE \ + "${code}" \ + "\"${title}\"" + ) + done >> "${WINETRICKS_WORKDIR}"/zenity.sh + + sh "${WINETRICKS_WORKDIR}"/zenity.sh | tr '|' ' ' + ;; + + kdialog) + ( + printf %s "kdialog --geometry 600x400+100+100 --title '${_W_msg_title}' --separate-output --checklist '${_W_msg_body}' " + winetricks_list_all | sed 's/\([^ ]*\) *\(.*\)/\1 "\1 - \2" off /' | tr '\012' ' ' + ) > "${WINETRICKS_WORKDIR}"/kdialog.sh + + sh "${WINETRICKS_WORKDIR}"/kdialog.sh + ;; + esac + + unset _W_msg_body _W_msg_title +} + +# Display the current menu, output list of verbs to execute to stdout +winetricks_showmenu() +{ + case ${LANG} in + da*) _W_msg_title='Vælg en pakke' + _W_msg_body='Vilken pakke vil du installere?' + _W_cached="cached" + ;; + de*) _W_msg_title="Winetricks - Aktueller Prefix ist \"${WINEPREFIX}\"" + _W_msg_body='Welche Paket(e) möchten Sie installieren?' + _W_cached="gecached" + ;; + pl*) _W_msg_title="Winetricks - obecny prefiks to \"${WINEPREFIX}\"" + _W_msg_body='Które paczki chesz zainstalować?' + _W_cached="zarchiwizowane" + ;; + pt*) _W_msg_title="Winetricks - o prefixo atual é \"${WINEPREFIX}\"" + _W_msg_body='Quais pacotes você gostaria de instalar?' + _W_cached="em cache" + ;; + ru*) _W_msg_title="Winetricks - текущий путь wine (wineprefix) \"${WINEPREFIX}\"" + _W_msg_body='Какое приложение(я) вы хотите установить?' + _W_cached="в кэше" + ;; + uk*) _W_msg_title="Winetricks - поточний prefix \"${WINEPREFIX}\"" + _W_msg_body='Які пакунки Ви хочете встановити?' + _W_cached="кешовано" + ;; + zh_CN*) _W_msg_title="Winetricks - 当前容器路径是 \"${WINEPREFIX}\"" + _W_msg_body='您想要安装什么应用程序?' + _W_cached="已缓存" + ;; + zh_TW*|zh_HK*) _W_msg_title="Winetricks - 目前容器路徑是 \"${WINEPREFIX}\"" + _W_msg_body='您想要安裝什麼應用程式?' + _W_cached="已緩存" + ;; + *) _W_msg_title="Winetricks - current prefix is \"${WINEPREFIX}\"" + _W_msg_body='Which package(s) would you like to install?' + _W_cached="cached" + ;; + esac + + + case ${WINETRICKS_GUI} in + zenity) + case ${LANG} in + da*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Pakke \ + --column Navn \ + --column Udgiver \ + --column År \ + --column Medie \ + --column Status \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + de*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Paket \ + --column Name \ + --column Herausgeber \ + --column Jahr \ + --column Media \ + --column Status \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + pl*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Pakiet \ + --column Nazwa \ + --column Wydawca \ + --column Rok \ + --column Media \ + --column Status \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + pt*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Pacote \ + --column Título \ + --column Publisher \ + --column Ano \ + --column Mídia \ + --column Status \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + ru*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Пакет \ + --column Название \ + --column Издатель \ + --column Год \ + --column Источник \ + --column Статус \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + uk*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Пакунок \ + --column Назва \ + --column Видавець \ + --column Рік \ + --column Медіа \ + --column Статус \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + zh_CN*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column 包名 \ + --column 软件名 \ + --column 发行商 \ + --column 发行年 \ + --column 媒介 \ + --column 状态 \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + zh_TW*|zh_HK*) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column 包名 \ + --column 軟體名 \ + --column 發行商 \ + --column 發行年 \ + --column 媒介 \ + --column 狀態 \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + *) printf %s "zenity \ + --title '${_W_msg_title}' \ + --text '${_W_msg_body}' \ + --list \ + --checklist \ + --column '' \ + --column Package \ + --column Title \ + --column Publisher \ + --column Year \ + --column Media \ + --column Status \ + --height ${WINETRICKS_MENU_HEIGHT} \ + --width ${WINETRICKS_MENU_WIDTH} \ + " + ;; + esac > "${WINETRICKS_WORKDIR}"/zenity.sh + + true > "${WINETRICKS_WORKDIR}"/installed.txt + + for metadatafile in "${WINETRICKS_METADATA}/${WINETRICKS_CURMENU}"/*.vars; do + code=$(winetricks_metadata_basename "${metadatafile}") + ( + title='?' + # shellcheck disable=SC1090 + . "${metadatafile}" + # Compute cached and downloadable flags + flags="" + winetricks_is_cached "${code}" && flags="${_W_cached}" + installed=FALSE + if winetricks_is_installed "${code}"; then + installed=TRUE + echo "${code}" >> "${WINETRICKS_WORKDIR}"/installed.txt + fi + printf %s " ${installed} \ + ${code} \ + \"${title}\" \ + \"${publisher}\" \ + \"${year}\" \ + \"${media}\" \ + \"${flags}\" \ + " + ) + done >> "${WINETRICKS_WORKDIR}"/zenity.sh + + # Filter out any verb that's already installed + sh "${WINETRICKS_WORKDIR}"/zenity.sh | + tr '|' '\012' | + grep -F -v -x -f "${WINETRICKS_WORKDIR}"/installed.txt | + tr '\012' ' ' + ;; + + kdialog) + ( + printf %s "kdialog --geometry 600x400+100+100 --title '${_W_msg_title}' --separate-output --checklist '${_W_msg_body}' " + winetricks_list_all | sed 's/\([^ ]*\) *\(.*\)/\1 "\1 - \2" off /' | tr '\012' ' ' + ) > "${WINETRICKS_WORKDIR}"/kdialog.sh + + sh "${WINETRICKS_WORKDIR}"/kdialog.sh + ;; + esac + + unset _W_msg_body _W_msg_title +} + +# Converts a metadata absolute path to its app code +winetricks_metadata_basename() +{ + # Classic, but too slow on cygwin + #basename $1 .vars + + # first, remove suffix .vars + _W_mb_tmp="${1%.vars}" + # second, remove any directory prefix + echo "${_W_mb_tmp##*/}" + unset _W_mb_tmp +} + +# Returns true if given verb has been registered +winetricks_metadata_exists() +{ + test -f "${WINETRICKS_METADATA}"/*/"${1}.vars" +} + +# Returns true if given verb has been cached +# You must have already loaded its metadata before calling +winetricks_is_cached() +{ + # FIXME: also check file2... if given + # https://github.com/Winetricks/winetricks/issues/989 + # shellcheck disable=SC2154 + _W_path="${W_CACHE}/$1/${file1}" + case "${_W_path}" in + *..*) + # Remove /foo/.. so verbs that don't have their own cache directories + # can refer to siblings + _W_path="$(echo "${_W_path}" | sed 's,/[^/]*/\.\.,,')" + ;; + esac + + if test -f "${_W_path}"; then + unset _W_path + return "${TRUE}" + fi + + unset _W_path + return "${FALSE}" +} + +# Returns true if given verb has been installed +# You must have already loaded its metadata before calling +winetricks_is_installed() +{ + unset _W_file _W_file_unix + if test "${installed_exe1}"; then + _W_file="${installed_exe1}" + elif test "${installed_file1}"; then + _W_file="${installed_file1}" + else + return "${FALSE}" # not installed + fi + + # Test if the verb has been executed before + if ! grep -qw "$1" "${WINEPREFIX}/winetricks.log" 2>/dev/null; then + unset _W_file + return "${FALSE}" # not installed + fi + + case "${W_PLATFORM}" in + windows_cmd|wine_cmd) + # On Windows, there's no wineprefix, just check if file's there + _W_file_unix="$(w_pathconv -u "${_W_file}")" + if test -f "${_W_file_unix}"; then + unset _W_file _W_file_unix _W_prefix + return "${TRUE}" # installed + fi + ;; + *) + # Compute wineprefix for this app + case "${_W_category}-${WINETRICKS_OPT_SHAREDPREFIX}" in + apps-0|benchmarks-0|games-0) + _W_prefix="${W_PREFIXES_ROOT}/$1" + ;; + *) + _W_prefix="${WINEPREFIX}" + ;; + esac + if test -d "${_W_prefix}/dosdevices"; then + # 'win7 vcrun2005' creates different file than 'winxp vcrun2005' + # so let it specify multiple, separated by | + _W_IFS="${IFS}" + IFS='|' + for _W_file_ in ${_W_file}; do + _W_file_unix="$(WINEPREFIX="${_W_prefix}" w_pathconv -u "${_W_file_}")" + if test -f "${_W_file_unix}" && ! grep -q "Wine placeholder DLL" "${_W_file_unix}"; then + IFS="${_W_IFS}" + unset _W_file _W_file_ _W_file_unix _W_prefix _W_IFS + return "${TRUE}" # installed + fi + done + IFS="${_W_IFS}" + fi + ;; + esac + unset _W_file _W_prefix _W_IFS # leak _W_file_unix for caller. Is this wise? + return "${FALSE}" # not installed +} + +# List verbs which are already fully cached locally +winetricks_list_cached() +{ + for _W_metadatafile in "${WINETRICKS_METADATA}"/*/*.vars; do + # Use a subshell to avoid putting metadata in global space + # If this is too slow, we can unset known metadata by hand + ( + code=$(winetricks_metadata_basename "${_W_metadatafile}") + # shellcheck disable=SC1090 + . "${_W_metadatafile}" + if winetricks_is_cached "${code}"; then + echo "${code}" + fi + ) + done | sort + unset _W_metadatafile +} + +# List verbs which are automatically downloadable, regardless of whether they're cached yet +winetricks_list_download() +{ + # Piping output of w_try_cd to /dev/null since winetricks-test parses it: + w_try_cd "${WINETRICKS_METADATA}" >/dev/null + grep -l 'media=.download' ./*/*.vars | sed 's,.*/,,;s/\.vars//' | sort -u +} + +# List verbs which are downloadable with user intervention, regardless of whether they're cached yet +winetricks_list_manual_download() +{ + # Piping output of w_try_cd to /dev/null since winetricks-test parses it: + w_try_cd "${WINETRICKS_METADATA}" >/dev/null + grep -l 'media=.manual_download' ./*/*.vars | sed 's,.*/,,;s/\.vars//' | sort -u +} + +winetricks_list_installed() +{ + # Rather than check individual metadata/files (which is slow/brittle, and also breaks settings and metaverbs) + # just show winetricks.log (if it exists), which lists verbs in the order they were installed + if [ -f "${WINEPREFIX}/winetricks.log" ]; then + cat "${WINEPREFIX}/winetricks.log" + else + echo "warning: ${WINEPREFIX}/winetricks.log not found; winetricks has not installed anything in this prefix." + fi +} + +# Helper for adding a string to a list of flags +winetricks_append_to_flags() +{ + if test "${flags}"; then + flags="${flags}," + fi + flags="${flags}$1" +} + +# List all verbs in category WINETRICKS_CURMENU verbosely +# Format is "verb title (publisher, year) [flags]" +winetricks_list_all() +{ + # Note: doh123 relies on 'winetricks list' to list main menu categories + case ${WINETRICKS_CURMENU} in + prefix|main|mkprefix) echo "${WINETRICKS_CATEGORIES}" | sed 's/ mkprefix//' | tr ' ' '\012' ; return;; + esac + + case ${LANG} in + da*) _W_cached="cached" ; _W_download="kan hentes" ;; + de*) _W_cached="gecached" ; _W_download="herunterladbar";; + pl*) _W_cached="zarchiwizowane" ; _W_download="do pobrania" ;; + pt*) _W_cached="em cache" ; _W_download="para download" ;; + ru*) _W_cached="в кэше" ; _W_download="доступно для скачивания" ;; + uk*) _W_cached="кешовано" ; _W_download="завантажуване" ;; + zh_CN*) _W_cached="已缓存" ; _W_download="可下载" ;; + zh_TW*|zh_HK*) _W_cached="已緩存" ; _W_download="可下載" ;; + *) _W_cached="cached" ; _W_download="downloadable" ;; + esac + + for _W_metadatafile in "${WINETRICKS_METADATA}/${WINETRICKS_CURMENU}"/*.vars; do + # Use a subshell to avoid putting metadata in global space + # If this is too slow, we can unset known metadata by hand + ( + code=$(winetricks_metadata_basename "${_W_metadatafile}") + # shellcheck disable=SC1090 + . "${_W_metadatafile}" + + # Compute cached and downloadable flags + flags="" + test "${media}" = "download" && winetricks_append_to_flags "${_W_download}" + winetricks_is_cached "${code}" && winetricks_append_to_flags "${_W_cached}" + test "${flags}" && flags="[${flags}]" + + if ! test "${year}" && ! test "${publisher}"; then + printf "%-24s %s %s\\n" "${code}" "${title}" "${flags}" + else + printf "%-24s %s (%s, %s) %s\\n" "${code}" "${title}" "${publisher}" "${year}" "${flags}" + fi + ) + done + unset _W_cached _W_metadatafile +} + +# Abort if user doesn't own the given directory (or its parent, if it doesn't exist yet) +winetricks_die_if_user_not_dirowner() +{ + if test -d "$1"; then + _W_checkdir="$1" + else + # fixme: quoting problem? + _W_checkdir=$(dirname "$1") + fi + _W_nuser=$(id -u) + _W_nowner=$(stat -c '%u' "${_W_checkdir}") + if test x"${_W_nuser}" != x"${_W_nowner}"; then + w_die "You ($(id -un)) don't own ${_W_checkdir}. Don't run this tool as another user!" + fi +} + +# See +# https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf (iso9660) +# https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-167.pdf +# http://www.osta.org/specs/pdf/udf102.pdf +# https://www.ecma-international.org/publications/techreports/E-TR-071.htm + +# Usage: read_bytes offset count device +winetricks_read_bytes() +{ + dd status=noxfer if="$3" bs=1 skip="$1" count="$2" 2>/dev/null +} + +# Usage: read_hex offset count device +winetricks_read_hex() +{ + od -j "$1" -N "$2" -t x1 "$3" | # offset $1, count $2, single byte hex format, file $3 + sed 's/^[^ ]* //' | # remove address + sed '$d' # remove final line which is just final offset +} + +# Usage: read_decimal offset device +# Reads single four byte word, outputs in decimal. +# Uses default endianness. +# udf uses little endian words, so this only works on little endian machines. +winetricks_read_decimal() +{ + od -j "$1" -N 4 -t u4 "$2" | # offset $1, byte count 4, four byte decimal format, file $2 + sed 's/^[^ ]* //' | # remove address + sed '$d' # remove final line which is just final offset +} + +winetricks_read_udf_volume_name() +{ + # "Anchor volume descriptor pointer" starts at sector 256 + + # AVDP Layout (ECMA-167 3/10.2): + # size offset contents + # 16 0 descriptor tag (id = 2) + # 16 8 main (primary?) volume descriptor sequence extent + # ... + + # descriptor tag layout (ECMA-167 3/7.2): + # size offset contents + # 2 0 TagIdentifier + # ... + + # extent layout (ECMA-167 3/7.1): + # size offset contents + # 4 0 length (in bytes) + # 8 4 location (in 2k sectors) + + # primary volume descriptor layout (ECMA-167 3/10.1): + # size offset contents + # 16 0 descriptor tag (id = 1) + # ... + # 32 24 volume identifier (dstring) + + # 1. check the 16 bit TagIdentifier of the descriptor tag, make sure it's 2 + tagid=$(winetricks_read_hex 524288 2 "$1") + : echo "tagid is ${tagid}" + case "${tagid}" in + "02 00") : echo "Found AVDP" ;; + *) echo "Did not find AVDP (tagid was ${tagid})"; exit 1;; + esac + + # 2. read the location of the main volume descriptor: + offset=$(winetricks_read_decimal 524308 "$1") + : echo "MVD is at sector ${offset}" + offset=$((offset * 2048)) + : echo "MVD is at byte ${offset}" + + # 3. check the TagIdentifier of the MVD's descriptor tag, make sure it's 1 + tagid=$(winetricks_read_hex ${offset} 2 "$1") + : echo "tagid is ${tagid}" + case "${tagid}" in + "01 00") : echo Found MVD ;; + *) echo Did not find MVD; exit 1;; + esac + + # 4. Read whether the name is in 8 or 16 bit chars + offset=$((offset + 24)) + width=$(winetricks_read_hex ${offset} 1 "$1") + + offset=$((offset + 1)) + + # 5. Profit! + case ${width} in + 08) winetricks_read_bytes ${offset} 30 "$1" | sed 's/ *$//' ;; + 10) winetricks_read_bytes ${offset} 30 "$1" | tr -d '\000' | sed 's/ *$//' ;; + *) echo "Unhandled dvd volname character width '${width}'"; exit 1;; + esac + + echo "" +} + +winetricks_read_iso9660_volume_name() +{ + winetricks_read_bytes 32808 30 "$1" | sed 's/ *$//' +} + +winetricks_read_volume_name() +{ + # ECMA-119 says that CD-ROMs have sector size 2k, and at sector 16 have: + # size offset contents + # 1 0 Volume descriptor type (1 for primary volume descriptor) + # 5 1 Standard identifier ("CD001" for iso9660) + # ECMA-167, section 9.1.2, has a table of standard identifiers: + # "BEA01": ecma-167 9.2, Beginning Extended Area Descriptor + # "CD001": ecma-119 + # "CDW02": ecma-168 + + std_id=$(winetricks_read_bytes 32769 5 "$1") + : echo "std_id is ${std_id}" + + case ${std_id} in + CD001) winetricks_read_iso9660_volume_name "$1" ;; + BEA01) winetricks_read_udf_volume_name "$1" ;; + *) echo "Unrecognized disk type ${std_id}"; exit 1 ;; + esac +} + +winetricks_volname() +{ + x=$(volname "$1" 2> /dev/null| sed 's/ *$//') + if test -z "${x}"; then + # UDF? See https://bugs.launchpad.net/bugs/678419 + x=$(winetricks_read_volume_name "$1") + fi + echo "${x}" +} + +# Really, should take a volume name as argument, and use 'mount' to get +# mount point if system automounted it. +winetricks_detect_optical_drive() +{ + case "${WINETRICKS_DEV}" in + "") ;; + *) return ;; + esac + + for WINETRICKS_DEV in /dev/cdrom /dev/dvd /dev/sr0; do + test -b ${WINETRICKS_DEV} && break + done + + case "${WINETRICKS_DEV}" in + "x") w_die "can't find cd/dvd drive" ;; + esac +} + +winetricks_cache_iso() +{ + # WINETRICKS_IMG has already been set by w_mount + _W_expected_volname="$1" + + winetricks_die_if_user_not_dirowner "${W_CACHE}" + winetricks_detect_optical_drive + + # Horrible hack for Gentoo - make sure we can read from the drive + if ! test -r ${WINETRICKS_DEV}; then + case "${WINETRICKS_SUDO}" in + gksu*|kdesudo) ${WINETRICKS_SUDO} "chmod 666 ${WINETRICKS_DEV}" ;; + kdesu) ${WINETRICKS_SUDO} -c "chmod 666 ${WINETRICKS_DEV}" ;; + *) ${WINETRICKS_SUDO} chmod 666 ${WINETRICKS_DEV} ;; + esac + fi + + while true; do + # Wait for user to insert disc. + # Sleep long to make it less likely to close the drive during insertion. + while ! dd if=${WINETRICKS_DEV} of=/dev/null count=1; do + sleep 5 + done + + # Some distributions automount discs in /media, take advantage of that + if test -d "/media/_W_expected_volname"; then + break + fi + # Otherwise try and read it straight from unmounted volume + _W_volname=$(winetricks_volname ${WINETRICKS_DEV}) + if test "${_W_expected_volname}" != "${_W_volname}"; then + case ${LANG} in + da*) w_warn "Forkert disk [${_W_volname}] indsat. Indsæt venligst disken [${_W_expected_volname}]" ;; + de*) w_warn "Falsche Disk [${_W_volname}] eingelegt. Bitte legen Sie Disk [${_W_expected_volname}] ein!" ;; + pl*) w_warn "Umieszczono zły dysk [${_W_volname}]. Proszę włożyć dysk [${_W_expected_volname}]" ;; + pt*) w_warn "Disco errado [${_W_volname}] inserido. Por favor insira o disco [${_W_expected_volname}]" ;; + ru*) w_warn "Неверный диск [${_W_volname}]. Пожалуйста, вставьте диск [${_W_expected_volname}]" ;; + uk*) w_warn "Неправильний диск [${_W_volname}]. Будь ласка, вставте диск [${_W_expected_volname}]" ;; + zh_CN*) w_warn " [${_W_volname}] 光盘插入错误,请插入光盘 [${_W_expected_volname}]" ;; + zh_TW*|zh_HK*) w_warn " [${_W_volname}] 光碟插入錯誤,請插入光碟 [${_W_expected_volname}]" ;; + *) w_warn "Wrong disc [${_W_volname}] inserted. Please insert disc [${_W_expected_volname}]" ;; + esac + + sleep 10 + else + break + fi + done + + # Copy disc to .iso file, display progress every 5 seconds + # Use conv=noerror,sync to replace unreadable blocks with zeroes + case ${WINETRICKS_OPT_DD} in + dd) + ${WINETRICKS_OPT_DD} if=${WINETRICKS_DEV} of="${W_CACHE}"/temp.iso bs=2048 conv=noerror,sync & + WINETRICKS_DD_PID=$! + ;; + ddrescue) + if [ ! -x "$(command -v ddrescue)" ]; then + w_die "Please install ddrescue first." + fi + ${WINETRICKS_OPT_DD} -v -b 2048 ${WINETRICKS_DEV} "${W_CACHE}"/temp.iso & + WINETRICKS_DD_PID=$! + ;; + esac + + echo "${WINETRICKS_DD_PID}" > "${WINETRICKS_WORKDIR}"/dd-pid + + # Note: if user presses ^C, winetricks_cleanup will call winetricks_iso_cleanup + # FIXME: add progress bar for kde, too + case ${WINETRICKS_GUI} in + none|kdialog) + while ps -p "${WINETRICKS_DD_PID}" > /dev/null 2>&1; do + sleep 5 + ls -l "${W_CACHE}"/temp.iso + done + ;; + zenity) + while ps -p "${WINETRICKS_DD_PID}" > /dev/null 2>&1; do + echo 1 + sleep 2 + done | ${WINETRICKS_GUI} --title "Copying to ${_W_expected_volname}.iso" --progress --pulsate --auto-kill + ;; + esac + rm "${WINETRICKS_WORKDIR}"/dd-pid + + mv "${W_CACHE}"/temp.iso "${WINETRICKS_IMG}" + + eject ${WINETRICKS_DEV} || true # punt if eject not found (as on cygwin) +} + +winetricks_load_vcdmount() +{ + if test "${WINE}" != ""; then + return + fi + + # Call only on real Windows. + # Sets VCD_DIR and W_ISO_MOUNT_ROOT + + # The only free mount tool I know for Windows Vista is Virtual CloneDrive, + # which can be downloaded at + # http://www.slysoft.com/en/virtual-clonedrive.html + # FIXME: actually install it here + + # Locate vcdmount.exe. + VCD_DIR="Elaborate Bytes/VirtualCloneDrive" + if test ! -x "${W_PROGRAMS_UNIX}/${VCD_DIR}/vcdmount.exe" && test ! -x "${W_PROGRAMS_X86_UNIX}/${VCD_DIR}/vcdmount.exe"; then + w_warn "Installing Virtual CloneDrive" + w_download_to vcd http://static.slysoft.com/SetupVirtualCloneDrive.exe + # have to use cmd else vista won't let cygwin run .exe's? + chmod +x "${W_CACHE}"/vcd/SetupVirtualCloneDrive.exe + w_try_cd "${W_CACHE}/vcd" + cmd /c SetupVirtualCloneDrive.exe + fi + if test -x "${W_PROGRAMS_UNIX}/${VCD_DIR}/vcdmount.exe"; then + VCD_DIR="${W_PROGRAMS_UNIX}/${VCD_DIR}" + elif test -x "${W_PROGRAMS_X86_UNIX}/${VCD_DIR}/vcdmount.exe"; then + VCD_DIR="${W_PROGRAMS_X86_UNIX}/${VCD_DIR}" + else + w_die "can't find Virtual CloneDrive?" + fi + # FIXME: Use WMI to locate the drive named + # "ELBY CLONEDRIVE..." using WMI as described in + # https://delphihaven.wordpress.com/2009/07/05/using-wmi-to-get-a-drive-friendly-name/ +} + +winetricks_mount_cached_iso() +{ + # On entry, WINETRICKS_IMG is already set + w_umount + + if test "${WINE}" = ""; then + winetricks_load_vcdmount + my_img_win="$(w_pathconv -w "${WINETRICKS_IMG}" | tr '\012' ' ' | sed 's/ $//')" + w_try_cd "${VCD_DIR}" + w_try vcdmount.exe /l="${letter}" "${my_img_win}" + + tries=0 + while test ${tries} -lt 20; do + for W_ISO_MOUNT_LETTER in e f g h i j k; do + # let user blacklist drive letters + echo "${WINETRICKS_MOUNT_LETTER_IGNORE}" | grep -q "${W_ISO_MOUNT_LETTER}" && continue + W_ISO_MOUNT_ROOT=/cygdrive/${W_ISO_MOUNT_LETTER} + if find ${W_ISO_MOUNT_ROOT} -iname 'setup*' -o -iname '*.exe' -o -iname '*.msi'; then + break 2 + fi + done + tries=$((tries + 1)) + echo "Waiting for mount to finish mounting" + sleep 1 + done + else + if test "${W_USE_USERMOUNT}"; then + # Linux (FUSE-based tools), macOS (hdiutil) + if test "${WINETRICKS_ISO_MOUNT}" = "none"; then + # If no tools found, fall back to sudo + mount + w_warn "No user mount tools detected, using sudo + mount" + unset W_USE_USERMOUNT + winetricks_mount_cached_iso + return + fi + echo "Running mkdir -p ${W_ISO_USER_MOUNT_ROOT}" + mkdir -p "${W_ISO_USER_MOUNT_ROOT}" + if test $? -ne 0; then + w_warn "mkdir -p ${W_ISO_USER_MOUNT_ROOT} failed, falling back to sudo + mount" + unset W_USE_USERMOUNT + winetricks_mount_cached_iso + return + fi + case "${WINETRICKS_ISO_MOUNT}" in + fuseiso) + echo "Running ${WINETRICKS_ISO_MOUNT} ${WINETRICKS_IMG} ${W_ISO_USER_MOUNT_ROOT}" + ${WINETRICKS_ISO_MOUNT} "${WINETRICKS_IMG}" "${W_ISO_USER_MOUNT_ROOT}" + ;; + archivemount) + echo "Running ${WINETRICKS_ISO_MOUNT} ${WINETRICKS_IMG} ${W_ISO_USER_MOUNT_ROOT} -o readonly" + ${WINETRICKS_ISO_MOUNT} "${WINETRICKS_IMG}" "${W_ISO_USER_MOUNT_ROOT}" -o readonly + ;; + hdiutil) + echo "Running ${WINETRICKS_ISO_MOUNT} attach -mountpoint ${W_ISO_USER_MOUNT_ROOT} ${WINETRICKS_IMG}" + ${WINETRICKS_ISO_MOUNT} attach -mountpoint "${W_ISO_USER_MOUNT_ROOT}" "${WINETRICKS_IMG}" + ;; + *) + w_warn "Unknown ISO mount tool ${WINETRICKS_ISO_MOUNT}, using sudo + mount" + unset W_USE_USERMOUNT + winetricks_mount_cached_iso + return + ;; + esac + if test $? -ne 0; then + w_warn "${WINETRICKS_ISO_MOUNT} failed, falling back to sudo + mount" + unset W_USE_USERMOUNT + winetricks_mount_cached_iso + return + fi + + echo "Mounting as drive ${W_ISO_MOUNT_LETTER}:" + # Gotta provide a symlink to the raw disc, else installers that check volume names will fail + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:"* + ln -sf "${WINETRICKS_IMG}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}::" + ln -sf "${W_ISO_USER_MOUNT_ROOT}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:" + # Gotta set the type to "cdrom", else "wine eject" will fail + cat > "${W_TMP}"/set_type_cdrom.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives] +"${W_ISO_MOUNT_LETTER}:"="cdrom" +_EOF_ + w_try_regedit "${W_TMP}"/set_type_cdrom.reg + # The new drive is not recognized without waiting + # FIXME: not sure if the duration is appropriate + sleep 5 + + W_ISO_MOUNT_ROOT="${W_ISO_USER_MOUNT_ROOT}" + else + # Linux (sudo + mount) + _W_USERID=$(id -u) + # WINETRICKS_IMG may contain spaces and needs to be quoted + case "${WINETRICKS_SUDO}" in + gksu*|kdesudo) + w_try ${WINETRICKS_SUDO} "mkdir -p ${W_ISO_MOUNT_ROOT}" + w_try ${WINETRICKS_SUDO} "mount -o ro,loop,uid=${_W_USERID},unhide '${WINETRICKS_IMG}' ${W_ISO_MOUNT_ROOT}" + ;; + kdesu) + w_try ${WINETRICKS_SUDO} -c "mkdir -p ${W_ISO_MOUNT_ROOT}" + w_try ${WINETRICKS_SUDO} -c "mount -o ro,loop,uid=${_W_USERID},unhide '${WINETRICKS_IMG}' ${W_ISO_MOUNT_ROOT}" + ;; + *) + w_try ${WINETRICKS_SUDO} mkdir -p "${W_ISO_MOUNT_ROOT}" + w_try ${WINETRICKS_SUDO} mount -o ro,loop,uid="${_W_USERID}",unhide "${WINETRICKS_IMG}" "${W_ISO_MOUNT_ROOT}" + ;; + esac + + echo "Mounting as drive ${W_ISO_MOUNT_LETTER}:" + # Gotta provide a symlink to the raw disc, else installers that check volume names will fail + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:"* + ln -sf "${WINETRICKS_IMG}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}::" + ln -sf "${W_ISO_MOUNT_ROOT}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:" + unset _W_USERID + fi + fi +} + +# List the currently mounted UDF or iso9660 filesystems that match the given pattern +# Output format: +# dev mountpoint +# dev mountpoint +# ... +# Mount points may contain spaces. + +winetricks_list_mounts() +{ + mount | grep -E 'udf|iso9660' | sed 's,^\([^ ]*\) on \(.*\) type .*,\1 \2,'| grep "$1\$" +} + +# Return success and set _W_dev _W_mountpoint if volume $1 is mounted +# Note: setting variables as a way of returning results from a +# shell function exposed several bugs in most shells (except ksh!) +# related to implicit subshells. It would be better to output +# one string to stdout instead. +winetricks_is_mounted() +{ + # First, check for matching mountpoint + _W_tmp="$(winetricks_list_mounts "$1")" + if test "${_W_tmp}"; then + _W_dev=$(echo "${_W_tmp}" | sed 's/ .*//') + _W_mountpoint="$(echo "${_W_tmp}" | sed 's/^[^ ]* //')" + # Volume found! + return "${TRUE}" + fi + + # If that fails, read volume name the hard way for each volume + # Have to use file to return results from implicit subshell + rm -f "${W_TMP_EARLY}/_W_tmp.${LOGNAME}" + winetricks_list_mounts . | while true; do + IFS= read -r _W_tmp + + _W_dev=$(echo "${_W_tmp}" | sed 's/ .*//') + test "${_W_dev}" || break + _W_mountpoint="$(echo "${_W_tmp}" | sed 's/^[^ ]* //')" + _W_volname=$(winetricks_volname "${_W_dev}") + if test "$1" = "${_W_volname}"; then + # Volume found! Want to return from function here, but can't + echo "${_W_tmp}" > "${W_TMP_EARLY}/_W_tmp.${LOGNAME}" + break + fi + done + + if test -f "${W_TMP_EARLY}/_W_tmp.${LOGNAME}"; then + # Volume found! Return from function. + _W_dev=$(sed 's/ .*//' "${W_TMP_EARLY}/_W_tmp.${LOGNAME}") + _W_mountpoint="$(sed 's/^[^ ]* //' "${W_TMP_EARLY}/_W_tmp.${LOGNAME}")" + rm -f "${W_TMP_EARLY}/_W_tmp.${LOGNAME}" + return "${TRUE}" + fi + + # Volume not found + unset _W_dev _W_mountpoint _W_volname + return "${FALSE}" +} + +winetricks_mount_real_volume() +{ + _W_expected_volname="$1" + + # Wait for user to insert disc. + + case ${LANG} in + da*)_W_mountmsg="Indsæt venligst disken '${_W_expected_volname}' (krævet af pakken '${W_PACKAGE}')" ;; + de*)_W_mountmsg="Bitte Disk '${_W_expected_volname}' einlegen (für Paket '${W_PACKAGE}')" ;; + pl*) _W_mountmsg="Proszę włożyć dysk '${_W_expected_volname}' (potrzebny paczce '${W_PACKAGE}')" ;; + pt*) _W_mountmsg="Por favor insira o volume '${_W_expected_volname}' (necessário para o pacote '${W_PACKAGE}')" ;; + ru*) _W_mountmsg="Пожалуйста, вставьте том '${_W_expected_volname}' (требуется для пакета '${W_PACKAGE}')" ;; + uk*) _W_mountmsg="Будь ласка, вставте том '${_W_expected_volname}' (потрібний для пакунка '${W_PACKAGE}')" ;; + zh_CN*) _W_mountmsg="请插入卷 '${_W_expected_volname}' (为包 '${W_PACKAGE} 所需')" ;; + zh_TW*|zh_HK*) _W_mountmsg="請插入卷 '${_W_expected_volname}' (為包 '${W_PACKAGE} 所需')" ;; + *) _W_mountmsg="Please insert volume '${_W_expected_volname}' (needed for package '${W_PACKAGE}')" ;; + esac + + if test "${WINE}" = ""; then + # Assume already mounted, just get drive letter + W_ISO_MOUNT_LETTER=$(awk '/iso/ {print $1}' < /proc/mounts | tr -d :) + W_ISO_MOUNT_ROOT=$(awk '/iso/ {print $2}' < /proc/mounts) + else + while ! winetricks_is_mounted "${_W_expected_volname}"; do + w_try w_warn_cancel "${_W_mountmsg}" + # In non-gui case, give user two seconds to futz with disc drive before spamming him again + sleep 2 + done + WINETRICKS_DEV=${_W_dev} + W_ISO_MOUNT_ROOT="${_W_mountpoint}" + + # Gotta provide a symlink to the raw disc, else installers that check volume names will fail + rm -f "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:"* + ln -sf "${WINETRICKS_DEV}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}::" + ln -sf "${W_ISO_MOUNT_ROOT}" "${WINEPREFIX}/dosdevices/${W_ISO_MOUNT_LETTER}:" + fi + + # FIXME: need to remount some discs with unhide option, + # add that as option to w_mount + + unset _W_mountmsg +} + +winetricks_cleanup() +{ + # We don't want to run this multiple times, so unfortunately we have to run it here: + if test "${W_NGEN_CMD}"; then + "${W_NGEN_CMD}" + fi + + set +e + if test -f "${WINETRICKS_WORKDIR}/dd-pid"; then + # shellcheck disable=SC2046 + kill $(cat "${WINETRICKS_WORKDIR}/dd-pid") + fi + test "${WINETRICKS_CACHE_SYMLINK}" && rm -f "${WINETRICKS_CACHE_SYMLINK}" + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${WINETRICKS_WORKDIR}" + # if $W_TMP_EARLY was created by mktemp, remove it (but not if W_OPT_NOCLEAN is set to 1): + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${W_TMP_EARLY}" + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${WINEPREFIX}"/wrapper.cfg +} + +winetricks_set_unattended() +{ + case "$1" in + 1) W_OPT_UNATTENDED=1;; + *) unset W_OPT_UNATTENDED;; + esac +} + +# Usage: winetricks_print_wineprefix_info +# Print some useful info about $WINEPREFIX if things fail in winetricks_set_wineprefix() +winetricks_print_wineprefix_info() +{ + printf "WINEPREFIX INFO:\\n" + printf "Drive C: %s\\n\\n" "$(ls -al1 "${WINEPREFIX}/drive_c")" + printf "Registry info:\\n" + for regfile in "${WINEPREFIX}"/*.reg; do + printf "%s:%s\\n" "${regfile}" "$(grep '#arch=' "${regfile}")" + done +} + +# Force creation of 32 or 64bit wineprefix on 64 bit systems. +# On 32bit systems, trying to create a 64bit wineprefix will fail. +# This must be called prior to winetricks_set_wineprefix() +winetricks_set_winearch() +{ + if [ "$1" = "32" ] || [ "$1" = "win32" ]; then + export WINEARCH=win32 + elif [ "$1" = "64" ] || [ "$1" = "win64" ]; then + export WINEARCH=win64 + else + w_die "arch: Invalid architecture: $1" + fi +} + +# Usage: winetricks_set_wineprefix [bottlename] +# Bottlename must not contain spaces, slashes, or other special characters +# If bottlename is omitted, the default bottle (~/.wine) is used. +# +# shellcheck disable=SC2034 +winetricks_set_wineprefix() +{ + # Note: these are arch independent, but are needed by some arch dependent variables + # Defining here to avoid having two arch checks: + if ! test "$1"; then + WINEPREFIX="${WINETRICKS_ORIGINAL_WINEPREFIX}" + else + WINEPREFIX="${W_PREFIXES_ROOT}/$1" + fi + + export WINEPREFIX + w_try mkdir -p "$(dirname "${WINEPREFIX}")" + + case "${W_PLATFORM}" in + windows_cmd) + W_DRIVE_C="/cygdrive/c" ;; + *) + W_DRIVE_C="${WINEPREFIX}/dosdevices/c:" ;; + esac + W_WINDIR_UNIX="${W_DRIVE_C}/windows" + + if [ ! -d "${WINEPREFIX}" ] && [ -n "${WINEARCH}" ]; then + w_info "Creating WINEPREFIX \"${WINEPREFIX}\" with WINEARCH=${WINEARCH}" + "${WINE}" wineboot + # apparently wineboot doesn't wait for the prefix to be ready + # (to reproduce, run 'wine wineboot ; ls ~/.wine' it will often return before the .reg files are present + "${WINESERVER}" -w + fi + + # Make sure the prefix is initialized: + w_try winetricks_early_wine cmd /c "echo init" > /dev/null 2>&1 + + # Win(e) 32/64? + # Using the variable W_SYSTEM32_DLLS instead of SYSTEM32 because some stuff does go under system32 for both arch's + # e.g., spool/drivers/color + if test -d "${W_DRIVE_C}/windows/syswow64"; then + # Probably need fancier handling/checking, but for a basic start: + # Note 'wine' may be named 'wine-stable'/'wine-staging'/etc.): + # WINE64 = wine64, available on 64-bit prefixes + # WINE_ARCH = the native wine for the prefix (wine for 32-bit, wine64 for 64-bit) + # WINE_MULTI = generic wine, new name + if [ -n "${WINE64}" ]; then + true + elif [ "${WINE%??}64" = "${WINE}" ]; then + WINE64="${WINE}" + elif command -v "${WINE}64" >/dev/null 2>&1; then + WINE64="${WINE}64" + else + # Handle case where wine binaries (or binary wrappers) have a suffix + WINE64="$(dirname "${WINE}")/" + [ "${WINE64}" = "./" ] && WINE64="" + WINE64="${WINE64}$(basename "${WINE}" | sed 's/^wine/wine64/')" + fi + WINE_ARCH="${WINE64}" + WINE_MULTI="${WINE}" + W_ARCH=win64 + + W_PROGRAMS_WIN="$(w_expand_env ProgramFiles)" + W_PROGRAMS_UNIX="$(w_pathconv -u "${W_PROGRAMS_WIN}")" + + # Common variable for 32-bit dlls on win32/win64: + W_SYSTEM32_DLLS="${W_WINDIR_UNIX}/syswow64" + W_SYSTEM32_DLLS_WIN="C:\\windows\\syswow64" + + W_SYSTEM64_DLLS="${W_WINDIR_UNIX}/system32" + W_SYSTEM64_DLLS_WIN32="C:\\windows\\sysnative" # path to access 64-bit dlls from 32-bit apps + W_SYSTEM64_DLLS_WIN64="C:\\windows\\system32" # path to access 64-bit dlls from 64-bit apps + + # There's also ProgramW6432, which =%ProgramFiles%(but only available when running under a 64 bit OS) + # See https://ss64.com/nt/syntax-variables.html + W_PROGRAMW6432_WIN="$(w_expand_env ProgramW6432)" + W_PROGRAMW6432_UNIX="$(w_pathconv -u "${W_PROGRAMW6432_WIN}")" + + # 64-bit Windows has a second directory for program files + W_PROGRAMS_X86_WIN="${W_PROGRAMS_WIN} (x86)" + W_PROGRAMS_X86_UNIX="${W_PROGRAMS_UNIX} (x86)" + + W_COMMONFILES_X86_WIN="$(w_expand_env CommonProgramFiles\(x86\))" + W_COMMONFILES_X86="$(w_pathconv -u "${W_COMMONFILES_X86_WIN}")" + W_COMMONFILES_WIN="$(w_expand_env CommonProgramW6432)" + W_COMMONFILES="$(w_pathconv -u "${W_COMMONFILES_WIN}")" + + # 64-bit prefixes still have plenty of issues: + case ${LANG} in + ru*) w_warn "Вы используете 64-битный WINEPREFIX. Важно: многие ветки устанавливают только 32-битные версии пакетов. Если у вас возникли проблемы, пожалуйста, проверьте еще раз на чистом 32-битном WINEPREFIX до отправки отчета об ошибке." ;; + pt*) w_warn "Você está usando um WINEPREFIX de 64-bit. Observe que muitos casos instalam apenas versões de pacotes de 32-bit. Se você encontrar problemas, teste novamente em um WINEPREFIX limpo de 32-bit antes de relatar um bug." ;; + *) w_warn "You are using a 64-bit WINEPREFIX. Note that many verbs only install 32-bit versions of packages. If you encounter problems, please retest in a clean 32-bit WINEPREFIX before reporting a bug." ;; + esac + else + WINE64="false" + WINE_ARCH="${WINE}" + WINE_MULTI="${WINE}" + W_ARCH=win32 + + W_PROGRAMS_WIN="$(w_expand_env ProgramFiles)" + W_PROGRAMS_UNIX="$(w_pathconv -u "${W_PROGRAMS_WIN}")" + + # Common variable for 32-bit dlls on win32/win64: + W_SYSTEM32_DLLS="${W_WINDIR_UNIX}/system32" + W_SYSTEM32_DLLS_WIN="C:\\windows\\system32" + + # These don't exist on win32, but are defined in case they are used on 32-bit. + # W_SYSTEM64_DLLS_WIN64 in particular is needed by w_metadata() + W_SYSTEM64_DLLS="/dev/null" + W_SYSTEM64_DLLS_WIN32="C:\\does-not-exist-on-win32" # path to access 64-bit dlls from 32-bit apps + W_SYSTEM64_DLLS_WIN64="C:\\does-not-exist-on-win32" # path to access 64-bit dlls from 64-bit apps + + W_PROGRAMS_X86_WIN="${W_PROGRAMS_WIN}" + W_PROGRAMS_X86_UNIX="${W_PROGRAMS_UNIX}" + + W_COMMONFILES_X86_WIN="$(w_expand_env CommonProgramFiles)" + W_COMMONFILES_X86="$(w_pathconv -u "${W_COMMONFILES_X86_WIN}")" + W_COMMONFILES_WIN="$(w_expand_env CommonProgramFiles)" + W_COMMONFILES="$(w_pathconv -u "${W_COMMONFILES_WIN}")" + fi + + ## Arch independent variables: + + # Note: using AppData since it's arch indepedent + W_APPDATA_WIN="$(w_expand_env AppData)" + W_APPDATA_UNIX="$(w_pathconv -u "${W_APPDATA_WIN}")" + + case "${W_APPDATA_WIN}" in + "") w_info "$(winetricks_print_wineprefix_info)" ; w_die "${WINE} cmd.exe /c echo '%AppData%' returned empty string, error message \"$(cat ${W_TMP_EARLY}/early_wine.err.txt)\" ";; + %*) w_info "$(winetricks_print_wineprefix_info)" ; w_die "${WINE} cmd.exe /c echo '%AppData%' returned unexpanded string '${W_PROGRAMS_WIN}' ... this can be caused by a corrupt wineprefix (\`wineboot -u\` may help), by an old wine, or by not owning ${WINEPREFIX}" ;; + esac + + # Kludge: use Temp instead of temp to avoid \t expansion in w_try + # but use temp in Unix path because that's what Wine creates, and having both temp and Temp + # causes confusion (e.g. makes vc2005trial fail) + if ! test "$1"; then + W_TMP="${W_DRIVE_C}/windows/temp" + W_TMP_WIN="C:\\windows\\Temp" + else + # Verbs can rely on W_TMP being empty at entry, deleted after return, and a subdir of C: + W_TMP="${W_DRIVE_C}/windows/temp/_$1" + W_TMP_WIN="C:\\windows\\Temp\\_$1" + fi + + case "${W_PLATFORM}" in + "windows_cmd|wine_cmd") W_CACHE_WIN="$(w_pathconv -w "${W_CACHE}")" ;; + *) + # For case where Z: doesn't exist or / is writable (!), + # make a drive letter for W_CACHE. Clean it up on exit. + test "${WINETRICKS_CACHE_SYMLINK}" && rm -f "${WINETRICKS_CACHE_SYMLINK}" + for letter in y x w v u t s r q p o n m; do + if ! test -d "${WINEPREFIX}"/dosdevices/${letter}:; then + mkdir -p "${WINEPREFIX}"/dosdevices + WINETRICKS_CACHE_SYMLINK="${WINEPREFIX}"/dosdevices/${letter}: + ln -sf "${W_CACHE}" "${WINETRICKS_CACHE_SYMLINK}" + break + fi + done + W_CACHE_WIN="${letter}:" + ;; + esac + + W_WINDIR_UNIX="${W_DRIVE_C}/windows" + + # FIXME: get fonts path from SHGetFolderPath + # See also https://blogs.msdn.microsoft.com/oldnewthing/20031103-00/?p=41973/ + W_FONTSDIR_WIN="c:\\windows\\Fonts" + + # FIXME: just convert path from Windows to Unix? + # Did the user rename Fonts to fonts? + if test ! -d "${W_WINDIR_UNIX}"/Fonts && test -d "${W_WINDIR_UNIX}"/fonts; then + W_FONTSDIR_UNIX="${W_WINDIR_UNIX}"/fonts + else + W_FONTSDIR_UNIX="${W_WINDIR_UNIX}"/Fonts + fi + mkdir -p "${W_FONTSDIR_UNIX}" + + + # Unset WINEARCH which might be set from winetricks_set_winearch(). + # It is no longer necessary after the new wineprefix was created + # and even may cause trouble when using 64bit wineprefixes afterwards. + unset WINEARCH +} + +winetricks_annihilate_wineprefix() +{ + w_skip_windows "No wineprefix to delete on windows" && return + + case ${LANG} in + uk*) w_askpermission "Бажаєте видалити '${WINEPREFIX}'?" ;; + pl*) w_askpermission "Czy na pewno chcesz usunąć prefiks ${WINEPREFIX} i wszystkie jego elementy?" ;; + pt*) w_askpermission "Apagar ${WINEPREFIX}, Estes apps, ícones e ítens do menu?" ;; + *) w_askpermission "Delete ${WINEPREFIX}, its apps, icons, and menu items?" ;; + esac + + rm -rf "${WINEPREFIX}" + + # Also remove menu items. + find "${XDG_DATA_HOME}/applications" -type f -name '*.desktop' -exec grep -q -l "${WINEPREFIX}" '{}' ';' -exec rm '{}' ';' + + # Also remove desktop items. + # Desktop might be synonym for home directory, so only go one level + # deep to avoid extreme slowdown if user has lots of files + ( + if ! test "${XDG_DESKTOP_DIR}" && test -f "${XDG_CONFIG_HOME}/user-dirs.dirs"; then + # shellcheck disable=SC1090,SC1091 + . "${XDG_CONFIG_HOME}/user-dirs.dirs" + fi + find "${XDG_DESKTOP_DIR}" -maxdepth 1 -type f -name '*.desktop' -exec grep -q -l "${WINEPREFIX}" '{}' ';' -exec rm '{}' ';' + ) + + # FIXME: recover more nicely. At moment, have to restart to avoid trouble. + exit 0 +} + +winetricks_init() +{ + #---- Private Variables ---- + + if ! test "${USERNAME}"; then + # Posix only requires LOGNAME to be defined, and sure enough, when + # logging in via console and startx in Ubuntu 11.04, USERNAME isn't set! + # And even normal logins in Ubuntu 13.04 doesn't set it. + # I tried using only LOGNAME in this script, but it's so easy to slip + # and use USERNAME, so define it here if needed. + USERNAME="${LOGNAME}" + fi + + # Running Wine as root is (generally) bad, mmkay? + if [ "$(id -u)" = 0 ]; then + w_warn "Running Wine/winetricks as root is highly discouraged. See https://wiki.winehq.org/FAQ#Should_I_run_Wine_as_root.3F" + fi + + # Ephemeral files for this run + WINETRICKS_WORKDIR="${W_TMP_EARLY}/w.${LOGNAME}.$$" + test "${W_OPT_NOCLEAN}" = 1 || rm -rf "${WINETRICKS_WORKDIR}" + + # Registering a verb creates a file in WINETRICKS_METADATA + WINETRICKS_METADATA="${WINETRICKS_WORKDIR}/metadata" + + # The list of categories is also hardcoded in winetricks_mainmenu() :-( + WINETRICKS_CATEGORIES="apps benchmarks dlls fonts games settings mkprefix" + for _W_cat in ${WINETRICKS_CATEGORIES}; do + mkdir -p "${WINETRICKS_METADATA}/${_W_cat}" + done + + # Which subdirectory of WINETRICKS_METADATA is currently active (or main, if none) + WINETRICKS_CURMENU=prefix + + # Delete work directory after each run, on exit either graceful or abrupt + trap winetricks_cleanup EXIT HUP INT QUIT ABRT + + # Whether to always cache cached iso's (1) or only use cache if present (0) + # Can be inherited from environment or set via -k, defaults to off + WINETRICKS_OPT_KEEPISOS=${WINETRICKS_OPT_KEEPISOS:-0} + + # what program to use to make disc image (dd or ddrescue) + WINETRICKS_OPT_DD=${WINETRICKS_OPT_DD:-dd} + + # whether to use shared wineprefix (1) or unique wineprefix for each app (0) + WINETRICKS_OPT_SHAREDPREFIX=${WINETRICKS_OPT_SHAREDPREFIX:-0} + + winetricks_get_sha256sum_prog + + winetricks_get_platform + + # Workaround SIP DYLD_stripping + # See https://support.apple.com/en-us/HT204899 + if [ -n "${WINETRICKS_FALLBACK_LIBRARY_PATH}" ]; then + export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" + fi + + #---- Public Variables ---- + + # Where application installers are cached + # See https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html + # OSX: https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html + + if test -d "${HOME}/Library"; then + # OS X + XDG_CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/Library/Caches}" + XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME}/Library/Preferences}" + else + XDG_CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}" + XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME}/.config}" + fi + + # shellcheck disable=SC2153 + if test "${WINETRICKS_DIR}"; then + # For backwards compatibility + W_CACHE="${W_CACHE:-${WINETRICKS_DIR}/cache}" + WINETRICKS_POST="${WINETRICKS_POST:-${WINETRICKS_DIR}/postinstall}" + else + W_CACHE="${W_CACHE:-${XDG_CACHE_HOME}/winetricks}" + WINETRICKS_POST="${WINETRICKS_POST:-${XDG_DATA_HOME}/winetricks/postinstall}" + fi + + WINETRICKS_AUTH="${WINETRICKS_AUTH:-${XDG_DATA_HOME}/winetricks/auth}" + + # Config options are currently opt-in and not required, so not creating the config + # directory unless there's demand: + WINETRICKS_CONFIG="${XDG_CONFIG_HOME}/winetricks" + #test -d "$WINETRICKS_CONFIG" || mkdir -p "$WINETRICKS_CONFIG" + + # Load country code from config file only when "--country=" option is not specified + if test -z "${W_COUNTRY}" -a -f "${WINETRICKS_CONFIG}"/country; then + W_COUNTRY="$(cat "${WINETRICKS_CONFIG}"/country)" + fi + + # Pin a task to a single cpu. Helps prevent race conditions. + # + # Linux/FreeBSD: supported + # OSX: doesn't have a utility for this + # Solaris: no access, PR welcome + + if [ -x "$(command -v taskset 2>/dev/null)" ]; then + W_TASKSET="taskset -c 0" + elif [ -x "$(command -v cpuset 2>/dev/null)" ]; then + W_TASKSET="cpuset -l 0" + else + # not using w_warn so we don't annoy everyone running via GUI, but still printed to terminal: + echo "warning: taskset/cpuset not available on your platform!" + W_TASKSET="" + fi + + # Whether to automate installs (0=no, 1=yes) + winetricks_set_unattended "${W_OPT_UNATTENDED:-0}" + + # We have to call this here, because it needs to be called before w_metadata + # Unfortunately, that means we run wine before the gui runs. Avoiding that would take quite the refactor.. + winetricks_wine_setup "$@" +} + +winetricks_wine_setup() +{ + # This used to be part of winetricks_init(), factored out because not everything needs Wine. + if [ -n "${_W_wine_not_needed}" ]; then + # no-op + : + return + fi + + winetricks_latest_version_check + + # Overridden for windows + W_ISO_MOUNT_ROOT=/mnt/winetricks + W_ISO_USER_MOUNT_ROOT="${HOME}"/winetricks-iso + W_ISO_MOUNT_LETTER=i + + ###################### + # System-specific variables + case "${W_PLATFORM}" in + windows_cmd) + WINE="" + WINE64="" + WINE_ARCH="" + WINE_MULTI="" + WINESERVER="" + W_DRIVE_C="C:/" + ;; + *) + WINE="${WINE:-wine}" + # Find wineserver. + # Some distributions (Debian before wine 1.8-2) don't have it on the path. + for x in \ + "${WINESERVER}" \ + "${WINE}server" \ + "$(command -v wineserver 2> /dev/null)" \ + "$(dirname "${WINE}")/server/wineserver" \ + /usr/bin/wineserver-development \ + /usr/lib/wine/wineserver \ + /usr/lib/i386-kfreebsd-gnu/wine/wineserver \ + /usr/lib/i386-linux-gnu/wine/wineserver \ + /usr/lib/powerpc-linux-gnu/wine/wineserver \ + /usr/lib/i386-kfreebsd-gnu/wine/bin/wineserver \ + /usr/lib/i386-linux-gnu/wine/bin/wineserver \ + /usr/lib/powerpc-linux-gnu/wine/bin/wineserver \ + /usr/lib/x86_64-linux-gnu/wine/bin/wineserver \ + /usr/lib/i386-kfreebsd-gnu/wine-development/wineserver \ + /usr/lib/i386-linux-gnu/wine-development/wineserver \ + /usr/lib/powerpc-linux-gnu/wine-development/wineserver \ + /usr/lib/x86_64-linux-gnu/wine-development/wineserver \ + file-not-found; do + + if test -x "${x}"; then + case "${x}" in + /usr/lib/*/wine-development/wineserver|/usr/bin/wineserver-development) + if test -x /usr/bin/wine-development; then + WINE="/usr/bin/wine-development" + fi + ;; + esac + break + fi + done + + case "${x}" in + file-not-found) w_die "wineserver not found!" ;; + *) WINESERVER="${x}" ;; + esac + + if test "${WINEPREFIX}"; then + WINETRICKS_ORIGINAL_WINEPREFIX="${WINEPREFIX}" + else + WINETRICKS_ORIGINAL_WINEPREFIX="${HOME}/.wine" + fi + _abswine="$(command -v "${WINE}" 2>/dev/null)" + if ! test -x "${_abswine}" || ! test -f "${_abswine}"; then + w_die "WINE is ${WINE}, which is neither on the path nor an executable file" + fi + unset _abswine + ;; + esac + + WINETRICKS_WINE_VERSION=${WINETRICKS_WINE_VERSION:-$(winetricks_early_wine --version | sed 's/.*wine/wine/')} + WINETRICKS_ORIG_WINE_VERSION="${WINETRICKS_WINE_VERSION}" + + # Need to account for lots of variations: + # wine-1.9.22 + # wine-1.9.22 (Debian 1.9.22-1) + # wine-1.9.22 (Staging) + # wine-2.0 (Debian 2.0-1) + # wine-2.0-rc1 + # wine-2.8 + _wine_version_stripped="$(echo "${WINETRICKS_WINE_VERSION}" | cut -d ' ' -f1 | sed -e 's/wine-//' -e 's/-rc.*//')" + + # If WINE is < 5.0, warn user: + # 5.0 doesn't do what I thought it would + if w_wine_version_in ,4.99 ; then + w_warn "Your version of wine ${_wine_version_stripped} is no longer supported upstream. You should upgrade to 5.x" + fi + + winetricks_set_wineprefix "$1" + + if [ -z "${WINETRICKS_SUPER_QUIET}" ] ; then + echo "Using winetricks $(winetricks_print_version) with ${WINETRICKS_ORIG_WINE_VERSION} and WINEARCH=${W_ARCH}" + fi +} + +winetricks_usage() +{ + case ${LANG} in + da*) + cat <<_EOF_ +Brug: $0 [tilvalg] [verbum|sti-til-verbum] ... +Kører de angivne verber. Hvert verbum installerer et program eller ændrer en indstilling. +Tilvalg: + --country=CC Set country code to CC and don't detect your IP address +-f, --force Don't check whether packages were already installed + --gui Show gui diagnostics even when driven by commandline + --isolate Install each app or game in its own bottle (WINEPREFIX) + --self-update Update this application to the last version + --update-rollback Rollback the last self update +-k, --keep_isos lagr iso'er lokalt (muliggør senere installation uden disk) + --no-clean Don't delete temp directories (useful during debugging) +-q, --unattended stil ingen spørgsmål, installér bare automatisk +-r, --ddrescue brug alternativ disk-tilgangsmetode (hjælper i tilfælde af en ridset disk) +-t, --torify Run downloads under torify, if available + --verify Run (automated) GUI tests for verbs, if available +-v, --verbose vis alle kommandoer som de bliver udført +-V, --version vis programversionen og afslut +-h --help vis denne besked og afslut + +Diverse verber: +list vis en liste over alle verber +list-all list all categories and their verbs +apps list list verbs in category 'applications' +benchmarks list list verbs in category 'benchmarks' +dlls list list verbs in category 'dlls' +fonts list list verbs in category 'fonts' +games list list verbs in category 'games' +settings list list verbs in category 'settings' +list-cached vis en liste over verber for allerede-hentede installationsprogrammer +list-download vis en liste over verber for programmer der kan hentes +list-manual-download list applications which can be downloaded with some help from the user +list-installed list already-installed applications +arch=32|64 create wineprefix with 32 or 64 bit, this option must be + given before prefix=foobar and will not work in case of + the default wineprefix. +prefix=foobar select WINEPREFIX=${W_PREFIXES_ROOT}/foobar +annihilate Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX +_EOF_ + ;; + de*) + cat <<_EOF_ +Benutzung: $0 [options] [Kommando|Verb|Pfad-zu-Verb] ... +Angegebene Verben ausführen. +Jedes Verb installiert eine Anwendung oder ändert eine Einstellung. + +Optionen: + --country=CC Ländercode auf CC setzen und IP Adresse nicht auslesen +-f, --force Nicht prüfen ob Pakete bereits installiert wurden + --gui GUI Diagnosen anzeigen, auch wenn von der Kommandozeile gestartet + --isolate Jedes Programm oder Spiel in eigener Bottle (WINEPREFIX) installieren + --self-update Dieses Programm auf die neueste Version aktualisieren + --update-rollback Rollback des letzten Self Update +-k, --keep_isos ISOs local speichern (erlaubt spätere Installation ohne Disk) + --no-clean Temp Verzeichnisse nicht löschen (nützlich beim debuggen) +-q, --unattended Keine Fragen stellen, alles automatisch installieren +-r, --ddrescue Alternativer Zugriffsmodus (hilft bei zerkratzten Disks) +-t --torify Wenn möglich Downloads unter torify ausführen + --verify Wenn möglich automatische GUI Tests für Verben starten +-v, --verbose Alle ausgeführten Kommandos anzeigen +-h, --help Diese Hilfemeldung anzeigen +-V, --version Programmversion anzeigen und Beenden + +Kommandos: +list Kategorien auflisten +list-all Alle Kategorien und deren Verben auflisten +apps list Verben der Kategorie 'Anwendungen' auflisten +benchmarks list Verben der Kategorie 'Benchmarks' auflisten +dlls list Verben der Kategorie 'DLLs' auflisten +fonts list list verbs in category 'fonts' +games list Verben der Kategorie 'Spiele' auflisten +settings list Verben der Kategorie 'Einstellungen' auflisten +list-cached Verben für bereits gecachte Installers auflisten +list-download Verben für automatisch herunterladbare Anwendungen auflisten +list-manual-download Verben für vom Benutzer herunterladbare Anwendungen auflisten +list-installed Bereits installierte Verben auflisten +arch=32|64 Neues wineprefix mit 32 oder 64 bit erstellen, diese Option + muss vor prefix=foobar angegeben werden und funktioniert + nicht im Falle des Standard Wineprefix. +prefix=foobar WINEPREFIX=${W_PREFIXES_ROOT}/foobar auswählen +annihilate ALLE DATEIEN UND PROGRAMME IN DIESEM WINEPREFIX Löschen +_EOF_ + ;; + *) + cat <<_EOF_ +Usage: $0 [options] [command|verb|path-to-verb] ... +Executes given verbs. Each verb installs an application or changes a setting. + +Options: + --country=CC Set country code to CC and don't detect your IP address +-f, --force Don't check whether packages were already installed + --gui Show gui diagnostics even when driven by commandline + --gui=OPT Set OPT to kdialog or zenity to override GUI engine + --isolate Install each app or game in its own bottle (WINEPREFIX) + --self-update Update this application to the last version + --update-rollback Rollback the last self update +-k, --keep_isos Cache isos (allows later installation without disc) + --no-clean Don't delete temp directories (useful during debugging) +-q, --unattended Don't ask any questions, just install automatically +-r, --ddrescue Retry hard when caching scratched discs +-t --torify Run downloads under torify, if available + --verify Run (automated) GUI tests for verbs, if available +-v, --verbose Echo all commands as they are executed +-h, --help Display this message and exit +-V, --version Display version and exit + +Commands: +list list categories +list-all list all categories and their verbs +apps list list verbs in category 'applications' +benchmarks list list verbs in category 'benchmarks' +dlls list list verbs in category 'dlls' +fonts list list verbs in category 'fonts' +games list list verbs in category 'games' +settings list list verbs in category 'settings' +list-cached list cached-and-ready-to-install verbs +list-download list verbs which download automatically +list-manual-download list verbs which download with some help from the user +list-installed list already-installed verbs +arch=32|64 create wineprefix with 32 or 64 bit, this option must be + given before prefix=foobar and will not work in case of + the default wineprefix. +prefix=foobar select WINEPREFIX=${W_PREFIXES_ROOT}/foobar +annihilate Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX +_EOF_ + ;; + esac +} + +winetricks_handle_option() +{ + case "$1" in + --country=*) W_COUNTRY="${1##--country=}" ;; + -f|--force) WINETRICKS_FORCE=1;; + --gui*) winetricks_detect_gui "${1##--gui=}";; + -h|--help) winetricks_usage ; exit 0 ;; + --isolate) WINETRICKS_OPT_SHAREDPREFIX=0 ;; + -k|--keep_isos) WINETRICKS_OPT_KEEPISOS=1 ;; + --no-clean) W_OPT_NOCLEAN=1 ;; + --no-isolate) WINETRICKS_OPT_SHAREDPREFIX=1 ;; + --optin) WINETRICKS_STATS_REPORT=1;; + --optout) WINETRICKS_STATS_REPORT=0;; + -q|--unattended) winetricks_set_unattended 1 ;; + -r|--ddrescue) WINETRICKS_OPT_DD=ddrescue ;; + --self-update) winetricks_selfupdate;; + -t|--torify) WINETRICKS_OPT_TORIFY=1 ;; + --update-rollback) winetricks_selfupdate_rollback;; + -v|--verbose) WINETRICKS_OPT_VERBOSE=1 ; set -x;; + -V|--version) winetricks_print_version ; exit 0;; + --verify) WINETRICKS_VERIFY=1 ;; + -vv|--really-verbose) WINETRICKS_OPT_VERBOSE=2 ; set -x ;; + -*) w_die "unknown option $1" ;; + prefix=*) export WINEPREFIX="${W_PREFIXES_ROOT}/${1##prefix=}" ;; + *) return "${FALSE}" ;; + esac + return "${TRUE}" +} + +# Test whether temporary directory is valid - before initialising script +[ -d "${W_TMP_EARLY}" ] || w_die "temporary directory: '${W_TMP_EARLY}' ; does not exist" +[ -w "${W_TMP_EARLY}" ] || w_die "temporary directory: '${W_TMP_EARLY}' ; is not user writeable" + +# Must initialize variables before calling w_metadata +if ! test "${WINETRICKS_LIB}"; then + WINETRICKS_SRCDIR=$(dirname "$0") + WINETRICKS_SRCDIR=$(w_try_cd "${WINETRICKS_SRCDIR}"; pwd) + + # Which GUI helper to use (none/zenity/kdialog). See winetricks_detect_gui. + WINETRICKS_GUI=none + # Default to a shared prefix: + WINETRICKS_OPT_SHAREDPREFIX=${WINETRICKS_OPT_SHAREDPREFIX:-1} + + # Handle options before init, to avoid starting wine for --help or --version + while winetricks_handle_option "$1"; do + shift + done + + # Super gross, but I couldn't find a cleaner way. This needs to be set for the list verbs (maybe others) + # while also supporting `dlls list` (etc.) + # This used by w_metadata() to skip checking installed files if wine isn't available/needed + if echo "$*" | grep -v list-installed | grep -q -w list; then + export _W_wine_not_needed=1 + fi + + # Workaround for https://github.com/Winetricks/winetricks/issues/599 + # If --isolate is used, pass verb to winetricks_init, so it can set the wineprefix using winetricks_set_wineprefix() + # Otherwise, an arch mismatch between ${WINEPREFIX:-$HOME/.wine} and the prefix to be made for the isolated app would cause it to fail + case ${WINETRICKS_OPT_SHAREDPREFIX} in + 0) winetricks_init "$1" ;; + *) winetricks_init ;; + esac +fi + +winetricks_install_app() +{ + case ${LANG} in + da*) fail_msg="Installationen af pakken $1 fejlede" ;; + de*) fail_msg="Installieren von Paket $1 gescheitert" ;; + pl*) fail_msg="Niepowodzenie przy instalacji paczki $1" ;; + pt*) fail_msg="Falha ao instalar o pacote $1" ;; + ru*) fail_msg="Ошибка установки пакета $1" ;; + uk*) fail_msg="Помилка встановлення пакунка $1" ;; + zh_CN*) fail_msg="$1 安装失败" ;; + zh_TW*|zh_HK*) fail_msg="$1 安裝失敗" ;; + *) fail_msg="Failed to install package $1" ;; + esac + + # FIXME: initialize a new wineprefix for this app, set lots of global variables + if ! w_do_call "$1" "$2"; then + w_die "${fail_msg}" + fi +} + +winetricks_verify() +{ + "verify_${cmd}" 2>/dev/null + verify_status=$? + case ${verify_status} in + 0) w_warn "verify_${cmd} succeeded!" ;; + 127) echo "verify_${cmd} not found, not verifying ${cmd}" ;; + *) w_die "verify_${cmd} failed!" ;; + esac +} + +#---- Builtin Verbs ---- + +#---------------------------------------------------------------- +# Runtimes +#---------------------------------------------------------------- + +#----- common download for several verbs +# Note: please put a file list $(cabextract -l $foo) / $(unzip -l $foo) at ./misc/filelists/${helper}.txt + +# Filelist at ./misc/filelists/directx-feb2010.txt +helper_directx_dl() +{ + # February 2010 DirectX 9c User Redistributable + # https://www.microsoft.com/en-us/download/details.aspx?id=9033 + # FIXME: none of the verbs that use this will show download status right + # until file1 metadata is extended to handle common cache dir + # 2021/01/28: https://download.microsoft.com/download/E/E/1/EE17FF74-6C45-4575-9CF4-7FC2597ACD18/directx_feb2010_redist.exe + w_download_to directx9 https://files.holarse-linuxgaming.de/mirrors/microsoft/directx_feb2010_redist.exe f6d191e89a963d7cca34f169d30f49eab99c1ed3bb92da73ec43617caaa1e93f + + DIRECTX_NAME=directx_feb2010_redist.exe +} + +# Filelist at ./misc/filelists/directx-jun2010.txt +helper_directx_Jun2010() +{ + # June 2010 DirectX 9c User Redistributable + # https://www.microsoft.com/en-us/download/details.aspx?id=8109 + # 2021/01/28: https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe + w_download_to directx9 https://files.holarse-linuxgaming.de/mirrors/microsoft/directx_Jun2010_redist.exe 8746ee1a84a083a90e37899d71d50d5c7c015e69688a466aa80447f011780c0d + + DIRECTX_NAME=directx_Jun2010_redist.exe +} + +# Filelist at ./misc/filelists/directx-jun2010.txt +helper_d3dx9_xx() +{ + dllname=d3dx9_$1 + + helper_directx_Jun2010 + + # Even kinder, less invasive directx - only extract and override d3dx9_xx.dll + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native "${dllname}" +} + +# Filelist at ./misc/filelists/vb6sp6.txt +helper_vb6sp6() +{ + # $1 - directory to extract to + # $2 .. $n - files to extract from the archive + + destdir="$1" + shift + + w_download_to vb6sp6 https://download.microsoft.com/download/5/6/3/5635D6A9-885E-4C80-A2E7-8A7F4488FBF1/VB60SP6-KB2708437-x86-ENU.msi 350602b2e084b39c97d1394c8594b18e41ef622315d4a9635c5e8ea6aa977b5e + w_try_7z "${destdir}" "${W_CACHE}"/vb6sp6/VB60SP6-KB2708437-x86-ENU.msi "$@" +} + +# Filelist at ./misc/filelists/win2ksp4.txt +helper_win2ksp4() +{ + filename=$1 + + # Originally at https://www.microsoft.com/en-us/download/details.aspx?id=4127 + # Mirror list at http://www.filewatcher.com/m/w2ksp4_en.exe.135477136-0.html + # This URL doesn't need rename from w2ksp4_en.exe to W2KSP4_EN.EXE + # to avoid users having to redownload for a file rename + # 2020/12/09: https://ftp.gnome.org/mirror/archive/ftp.sunet.se/pub/security/vendor/microsoft/win2000/Service_Packs/usa/W2KSP4_EN.EXE + w_download_to win2ksp4 http://x3270.bgp.nu/download/specials/W2KSP4_EN.EXE 167bb78d4adc957cc39fb4902517e1f32b1e62092353be5f8fb9ee647642de7e + w_try_cabextract -d "${W_TMP}" -L -F "${filename}" "${W_CACHE}"/win2ksp4/W2KSP4_EN.EXE +} + +# Filelist at ./misc/filelists/winxpsp2_support_tools.txt +helper_winxpsp2_support_tools() +{ + filename="$1" + + # https://www.microsoft.com/en-us/download/details.aspx?id=18546 + w_download_to winxpsp2_support_tools https://web.archive.org/web/20070104163903/https://download.microsoft.com/download/d/3/8/d38066aa-4e37-4ae8-bce3-a4ce662b2024/WindowsXP-KB838079-SupportTools-ENU.exe 7927e87af616d2fb8d4ead0db0103eb845a4e6651b20a5bffea9eebc3035c24d + + w_try_cabextract -d "${W_TMP}" -L -F support.cab "${W_CACHE}"/winxpsp2_support_tools/WindowsXP-KB838079-SupportTools-ENU.exe + w_try_cabextract -d "${W_TMP}" -L -F "${filename}" "${W_TMP}"/support.cab +} + +# Filelist at ./misc/filelists/winxpsp3.txt +helper_winxpsp3() +{ + filename=$1 + + # 2017/03/15: helper was renamed from winxpsp3 to winxpsp3, to match win2k/win7 service pack helpers + # To minimize user impact, renaming directory automagically. + # This could be removed after a transition period (1 year or so): + if [ -d "${W_CACHE}/xpsp3" ] ; then + w_try mv "${W_CACHE}/xpsp3" "${W_CACHE}/winxpsp3" + fi + + # Formerly at: + # https://www.microsoft.com/en-us/download/details.aspx?id=24 + # https://download.microsoft.com/download/d/3/0/d30e32d8-418a-469d-b600-f32ce3edf42d/WindowsXP-KB936929-SP3-x86-ENU.exe + # Mirror list: http://www.filewatcher.com/m/WindowsXP-KB936929-SP3-x86-ENU.exe.331805736-0.html + # 2018/04/04: http://www.download.windowsupdate.com/msdownload/update/software/dflt/2008/04/windowsxp-kb936929-sp3-x86-enu_c81472f7eeea2eca421e116cd4c03e2300ebfde4.exe + # 2020/12/09: https://ftp.gnome.org/mirror/archive/ftp.sunet.se/pub/security/vendor/microsoft/winxp/Service_Packs/WindowsXP-KB936929-SP3-x86-ENU.exe + w_download_to winxpsp3 http://www.download.windowsupdate.com/msdownload/update/software/dflt/2008/04/windowsxp-kb936929-sp3-x86-enu_c81472f7eeea2eca421e116cd4c03e2300ebfde4.exe 62e524a552db9f6fd22d469010ea4d7e28ee06fa615a1c34362129f808916654 WindowsXP-KB936929-SP3-x86-ENU.exe + + w_try_cabextract -d "${W_TMP}" -L -F "${filename}" "${W_CACHE}"/winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe +} + +# Filelist at ./misc/filelists/win7sp1.txt +helper_win7sp1() +{ + filename=$1 + + # Formerly at: + # https://www.microsoft.com/en-us/download/details.aspx?id=5842 + # 2020/08/27: https://download.microsoft.com/download/0/A/F/0AFB5316-3062-494A-AB78-7FB0D4461357/windows6.1-KB976932-X86.exe + w_download_to win7sp1 http://download.windowsupdate.com/msdownload/update/software/svpk/2011/02/windows6.1-kb976932-x86_c3516bc5c9e69fee6d9ac4f981f5b95977a8a2fa.exe e5449839955a22fc4dd596291aff1433b998f9797e1c784232226aba1f8abd97 windows6.1-KB976932-X86.exe + + w_try_cabextract -d "${W_TMP}" -L -F "${filename}" "${W_CACHE}"/win7sp1/windows6.1-KB976932-X86.exe +} + +# Filelist at ./misc/filelists/win7sp1_x64.txt +helper_win7sp1_x64() +{ + filename=$1 + + # Formerly at: + # https://www.microsoft.com/en-us/download/details.aspx?id=5842 + # 2020/08/27: https://download.microsoft.com/download/0/A/F/0AFB5316-3062-494A-AB78-7FB0D4461357/windows6.1-KB976932-X64.exe + w_download_to win7sp1 http://download.windowsupdate.com/msdownload/update/software/svpk/2011/02/windows6.1-kb976932-x64_74865ef2562006e51d7f9333b4a8d45b7a749dab.exe f4d1d418d91b1619688a482680ee032ffd2b65e420c6d2eaecf8aa3762aa64c8 windows6.1-KB976932-X64.exe + + w_try_cabextract -d "${W_TMP}" -L -F "${filename}" "${W_CACHE}"/win7sp1/windows6.1-KB976932-X64.exe +} + +####################### +# dlls +####################### + +#--------------------------------------------------------- + +w_metadata amstream dlls \ + title="MS amstream.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/amstream.dll" + +load_amstream() +{ + helper_win7sp1 x86_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_0f58f1e53efca91e/amstream.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_0f58f1e53efca91e/amstream.dll" "${W_SYSTEM32_DLLS}/amstream.dll" + + w_override_dlls native,builtin amstream + + w_try_regsvr amstream.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_6b778d68f75a1a54/amstream.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_6b778d68f75a1a54/amstream.dll" "${W_SYSTEM64_DLLS}/amstream.dll" + w_try_regsvr64 amstream.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata art2kmin dlls \ + title="MS Access 2000 runtime" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="art2kmin.exe" \ + installed_file1="${W_COMMONFILES_X86_WIN}/Microsoft Shared/MSDesigners98/MDT2DBNS.DLL" + +load_art2kmin() +{ + w_download http://download.microsoft.com/download/office2000dev/art2kmin/1/win98/en-us/art2kmin.exe c6bf34dfac8d22b5d4ba8a4b14256dc25215f1ce769049c7f25c40850b5e5b81 + w_try_7z "${W_TMP}" "${W_CACHE}/${W_PACKAGE}"/art2kmin.exe + w_try_cd "${W_TMP}" + w_try "${WINE}" Setup.exe INSTALLPFILES=1 /wait ${W_OPT_UNATTENDED:+/q} +} + +w_metadata art2k7min dlls \ + title="MS Access 2007 runtime" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="AccessRuntime.exe" \ + installed_file1="${W_COMMONFILES_X86_WIN}/Microsoft Shared/OFFICE12/ACEES.DLL" + +load_art2k7min() +{ + # See https://www.microsoft.com/en-us/download/details.aspx?id=4438 + # Originally at https://download.microsoft.com/download/D/2/A/D2A2FC8B-0447-491C-A5EF-E8AA3A74FB98/AccessRuntime.exe + # 2019/11/22: moved to https://www.fmsinc.com/microsoftaccess/runtime/AccessRuntime2007.exe + w_download https://www.fmsinc.com/microsoftaccess/runtime/AccessRuntime2007.exe a00a92fdc4ddc0dcf5d1964214a8d7e4c61bb036908a4b43b3700063eda9f4fb AccessRuntime.exe + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" AccessRuntime.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata atmlib dlls \ + title="Adobe Type Manager" \ + publisher="Adobe" \ + year="2009" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/atmlib.dll" + +load_atmlib() +{ + helper_win2ksp4 i386/atmlib.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/atmlib.dl_ +} + +#---------------------------------------------------------------- + +w_metadata avifil32 dlls \ + title="MS avifil32" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/avifil32.dll" + +load_avifil32() +{ + helper_winxpsp3 i386/avifil32.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/avifil32.dl_ + + w_override_dlls native avifil32 +} + +#---------------------------------------------------------------- + +w_metadata cabinet dlls \ + title="Microsoft cabinet.dll" \ + publisher="Microsoft" \ + year="2002" \ + media="download" \ + file1="MDAC_TYP.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/cabinet.dll" + +load_cabinet() +{ + # https://www.microsoft.com/downloads/en/details.aspx?FamilyId=9AD000F2-CAE7-493D-B0F3-AE36C570ADE8&displaylang=en + # Originally at: https://download.microsoft.com/download/3/b/f/3bf74b01-16ba-472d-9a8c-42b2b4fa0d76/mdac_typ.exe + # Mirror list: http://www.filewatcher.com/m/MDAC_TYP.EXE.5389224-0.html (5.14 MB MDAC_TYP.EXE) + # 2018/08/09: ftp.gunadarma.ac.id is dead, moved to archive.org + w_download https://web.archive.org/web/20060718123742/http://ftp.gunadarma.ac.id/pub/driver/itegno/USB%20Software/MDAC/MDAC_TYP.EXE 36d2a3099e6286ae3fab181a502a95fbd825fa5ddb30bf09b345abc7f1f620b4 + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_dll "${W_TMP}/cabinet.dll" "${W_SYSTEM32_DLLS}/cabinet.dll" + + w_override_dlls native,builtin cabinet +} + +#---------------------------------------------------------------- + +w_metadata cmd dlls \ + title="MS cmd.exe" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="Q811493_W2K_SP4_X86_EN.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/cmd.exe" + +load_cmd() +{ + w_download https://web.archive.org/web/20150526022037/http://download.microsoft.com/download/8/d/c/8dc79965-dfbc-4b25-9546-e23bc4b791c6/Q811493_W2K_SP4_X86_EN.exe b5574b3516a724c2cba0d864162a3d1d684db1cf30de8db4b0e0ea6a1f6f1480 + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_CACHE}/${W_PACKAGE}/${file1}" -F cmd.exe + w_override_dlls native,builtin cmd.exe +} + +#---------------------------------------------------------------- + +w_metadata cnc_ddraw dlls \ + title="Reimplentation of ddraw for CnC games" \ + homepage="https://github.com/CnCNet/cnc-ddraw" \ + publisher="CnCNet" \ + year="2021" \ + media="download" \ + file1="cnc-ddraw.zip" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/Shaders/readme.txt" + +load_cnc_ddraw() +{ + # Note: only works if ddraw.ini contains settings for the executable + w_download https://github.com/CnCNet/cnc-ddraw/releases/download/v4.4.4.0/cnc-ddraw.zip 15b1f5ff38558869af651e3f10ab9e7728fa8f48d03b721e923f35fb417c55eb + w_try_unzip "${W_SYSTEM32_DLLS}" "${W_CACHE}/${W_PACKAGE}/${file1}" + + w_override_dlls native,builtin ddraw +} + +#---------------------------------------------------------------- + +w_metadata comctl32 dlls \ + title="MS common controls 5.80" \ + publisher="Microsoft" \ + year="2001" \ + media="download" \ + file1="CC32inst.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/comctl32.dll" + +load_comctl32() +{ + # Microsoft has removed. Mirrors can be found at http://www.filewatcher.com/m/CC32inst.exe.587496-0.html + # 2011/01/17: https://www.microsoft.com/en-us/download/details.aspx?id=14672 + # 2012/08/11: w_download https://download.microsoft.com/download/platformsdk/redist/5.80.2614.3600/w9xnt4/en-us/cc32inst.exe d68c0cca721870aed39f5f2efd80dfb74f3db66d5f9a49e7578b18279edfa4a7 + # 2016/01/07: w_download ftp://ftp.ie.debian.org/disk1/download.sourceforge.net/pub/sourceforge/p/po/pocmin/Win%2095_98%20Controls/Win%2095_98%20Controls/CC32inst.exe + # 2017/03/12: w_download https://downloads.sourceforge.net/project/pocmin/Win%2095_98%20Controls/Win%2095_98%20Controls/CC32inst.exe + + w_download https://downloads.sourceforge.net/project/pocmin/Win%2095_98%20Controls/Win%2095_98%20Controls/CC32inst.exe d68c0cca721870aed39f5f2efd80dfb74f3db66d5f9a49e7578b18279edfa4a7 + + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}/${file1}" "/T:${W_TMP_WIN}" /c ${W_OPT_UNATTENDED:+/q} + w_try_unzip "${W_TMP}" "${W_TMP}"/comctl32.exe + w_try "${WINE}" "${W_TMP}"/x86/50ComUpd.Exe "/T:${W_TMP_WIN}" /c ${W_OPT_UNATTENDED:+/q} + w_try_cp_dll "${W_TMP}"/comcnt.dll "${W_SYSTEM32_DLLS}"/comctl32.dll + + w_override_dlls native,builtin comctl32 + + # some builtin apps don't like native comctl32 + w_override_app_dlls winecfg.exe builtin comctl32 + w_override_app_dlls explorer.exe builtin comctl32 + w_override_app_dlls iexplore.exe builtin comctl32 +} + +#---------------------------------------------------------------- + +w_metadata comctl32ocx dlls \ + title="MS comctl32.ocx and mscomctl.ocx, comctl32 wrappers for VB6" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mscomctl.ocx" + +load_comctl32ocx() +{ + helper_vb6sp6 "${W_SYSTEM32_DLLS}" comctl32.ocx mscomctl.ocx mscomct2.ocx + + w_try_regsvr comctl32.ocx + w_try_regsvr mscomctl.ocx + w_try_regsvr mscomct2.ocx +} + +#---------------------------------------------------------------- + +w_metadata comdlg32ocx dlls \ + title="Common Dialog ActiveX Control for VB6" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/comdlg32.ocx" + +load_comdlg32ocx() +{ + helper_vb6sp6 "${W_TMP}" ComDlg32.ocx + w_try mv "${W_TMP}/ComDlg32.ocx" "${W_SYSTEM32_DLLS}/comdlg32.ocx" + w_try_regsvr comdlg32.ocx +} + +#---------------------------------------------------------------- + +w_metadata crypt32 dlls \ + title="MS crypt32" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/crypt32.dll" + +load_crypt32() +{ + w_call msasn1 + + helper_winxpsp3 i386/crypt32.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/crypt32.dl_ + + w_override_dlls native crypt32 +} + +#---------------------------------------------------------------- + +w_metadata binkw32 dlls \ + title="RAD Game Tools binkw32.dll" \ + publisher="RAD Game Tools, Inc." \ + year="2000" \ + media="download" \ + file1="__32-binkw32.dll3.0.0.0.zip" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/binkw32.dll" + +load_binkw32() +{ + # Mirror: https://www.dlldump.com/download-dll-files_new.php/dllfiles/B/binkw32.dll/1.0q/download.html + # sha256sum of the decompressed file: 1fd7ef7873c8a3be7e2f127b306d0d24d7d88e20cf9188894eff87b5af0d495f + # + # Zip sha256sum: + # 2015/12/27: 1d5efda8e4af796319b94034ba67b453cbbfddd81eb7d94fd059b40e237fa75d + w_download https://web.archive.org/web/20160221223726if_/http://www.down-dll.com/dll/b/__32-binkw32.dll3.0.0.0.zip 1d5efda8e4af796319b94034ba67b453cbbfddd81eb7d94fd059b40e237fa75d + + w_try_unzip "${W_TMP}" "${W_CACHE}"/binkw32/__32-binkw32.dll3.0.0.0.zip + w_try_cp_dll "${W_TMP}"/binkw32.dll "${W_SYSTEM32_DLLS}"/binkw32.dll + + w_override_dlls native binkw32 +} + +#---------------------------------------------------------------- + +w_metadata d3dcompiler_42 dlls \ + title="MS d3dcompiler_42.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dcompiler_42.dll" + +load_d3dcompiler_42() +{ + dllname=d3dcompiler_42 + + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native ${dllname} +} + +#---------------------------------------------------------------- + +w_metadata d3dcompiler_43 dlls \ + title="MS d3dcompiler_43.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dcompiler_43.dll" + +load_d3dcompiler_43() +{ + if w_workaround_wine_bug 24013 "Native d3dcompiler_43 may cause some d3d10 apps to crash, see https://bugs.winehq.org/show_bug.cgi?id=24013" ,5.4; then + : + fi + + dllname=d3dcompiler_43 + + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native ${dllname} +} + +#---------------------------------------------------------------- + +w_metadata d3dcompiler_46 dlls \ + title="MS d3dcompiler_46.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dcompiler_46.dll" + +load_d3dcompiler_46() +{ + # See https://bugs.winehq.org/show_bug.cgi?id=50350#c13 + + w_download http://download.microsoft.com/download/F/1/3/F1300C9C-A120-4341-90DF-8A52509B23AC/standalonesdk/Installers/2630bae9681db6a9f6722366f47d055c.cab + w_try_cabextract -d "${W_TMP}" -L -F "fil47ed91e900f4b9d9659b66a211b57c39" "${W_CACHE}/${W_PACKAGE}/2630bae9681db6a9f6722366f47d055c.cab" + w_try mv "${W_TMP}/fil47ed91e900f4b9d9659b66a211b57c39" "${W_SYSTEM32_DLLS}/d3dcompiler_46.dll" + + if [ "${W_ARCH}" = "win64" ]; then + w_download http://download.microsoft.com/download/F/1/3/F1300C9C-A120-4341-90DF-8A52509B23AC/standalonesdk/Installers/61d57a7a82309cd161a854a6f4619e52.cab + w_try_cabextract -d "${W_TMP}" -L -F "fil8c20206095817436f8df4a711faee5b7" "${W_CACHE}/${W_PACKAGE}/61d57a7a82309cd161a854a6f4619e52.cab" + w_try mv "${W_TMP}/fil8c20206095817436f8df4a711faee5b7" "${W_SYSTEM64_DLLS}/d3dcompiler_46.dll" + fi + + w_override_dlls native d3dcompiler_46 +} + +#---------------------------------------------------------------- + +w_metadata d3dcompiler_47 dlls \ + title="MS d3dcompiler_47.dll" \ + publisher="Microsoft" \ + year="FIXME" \ + media="download" \ + file1="FirefoxSetup62.0.3-win32.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dcompiler_47.dll" + +load_d3dcompiler_47() +{ + # FIXME: would be awesome to find a small download that has both 32/64bit dlls, but this works for now: + + w_download https://download-installer.cdn.mozilla.net/pub/firefox/releases/62.0.3/win32/ach/Firefox%20Setup%2062.0.3.exe "d6edb4ff0a713f417ebd19baedfe07527c6e45e84a6c73ed8c66a33377cc0aca" "FirefoxSetup62.0.3-win32.exe" + w_try_7z "${W_TMP}/win32" "${W_CACHE}/d3dcompiler_47/FirefoxSetup62.0.3-win32.exe" "core/d3dcompiler_47.dll" + w_try_cp_dll "${W_TMP}/win32/core/d3dcompiler_47.dll" "${W_SYSTEM32_DLLS}/d3dcompiler_47.dll" + + if [ "${W_ARCH}" = "win64" ]; then + w_download https://download-installer.cdn.mozilla.net/pub/firefox/releases/62.0.3/win64/ach/Firefox%20Setup%2062.0.3.exe "721977f36c008af2b637aedd3f1b529f3cfed6feb10f68ebe17469acb1934986" "FirefoxSetup62.0.3-win64.exe" + w_try_7z "${W_TMP}/win64" "${W_CACHE}/d3dcompiler_47/FirefoxSetup62.0.3-win64.exe" "core/d3dcompiler_47.dll" + w_try_cp_dll "${W_TMP}/win64/core/d3dcompiler_47.dll" "${W_SYSTEM64_DLLS}/d3dcompiler_47.dll" + fi + + w_override_dlls native d3dcompiler_47 +} + +#---------------------------------------------------------------- + +w_metadata d3drm dlls \ + title="MS d3drm.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3drm.dll" + +load_d3drm() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F "dxnt.cab" "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "d3drm.dll" "${W_TMP}/dxnt.cab" + + w_override_dlls native d3drm +} + +#---------------------------------------------------------------- + +w_metadata d3dx9 dlls \ + title="MS d3dx9_??.dll from DirectX 9 redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_43.dll" + +load_d3dx9() +{ + helper_directx_Jun2010 + + # Kinder, less invasive directx - only extract and override d3dx9_??.dll + w_try_cabextract -d "${W_TMP}" -L -F '*d3dx9*x86*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'd3dx9*.dll' "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F '*d3dx9*x64*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'd3dx9*.dll' "${x}" + done + fi + + # For now, not needed, but when Wine starts preferring our builtin dll over native it will be. + w_override_dlls native d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 d3dx9_28 d3dx9_29 d3dx9_30 + w_override_dlls native d3dx9_31 d3dx9_32 d3dx9_33 d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37 + w_override_dlls native d3dx9_38 d3dx9_39 d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_24 dlls \ + title="MS d3dx9_24.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_24.dll" + +load_d3dx9_24() +{ + helper_d3dx9_xx 24 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_25 dlls \ + title="MS d3dx9_25.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_25.dll" + +load_d3dx9_25() +{ + helper_d3dx9_xx 25 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_26 dlls \ + title="MS d3dx9_26.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_26.dll" + +load_d3dx9_26() +{ + helper_d3dx9_xx 26 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_27 dlls \ + title="MS d3dx9_27.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_27.dll" + +load_d3dx9_27() +{ + helper_d3dx9_xx 27 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_28 dlls \ + title="MS d3dx9_28.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_28.dll" + +load_d3dx9_28() +{ + helper_d3dx9_xx 28 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_29 dlls \ + title="MS d3dx9_29.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_29.dll" + +load_d3dx9_29() +{ + helper_d3dx9_xx 29 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_30 dlls \ + title="MS d3dx9_30.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_30.dll" + +load_d3dx9_30() +{ + helper_d3dx9_xx 30 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_31 dlls \ + title="MS d3dx9_31.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_31.dll" + +load_d3dx9_31() +{ + helper_d3dx9_xx 31 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_32 dlls \ + title="MS d3dx9_32.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_32.dll" + +load_d3dx9_32() +{ + helper_d3dx9_xx 32 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_33 dlls \ + title="MS d3dx9_33.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_33.dll" + +load_d3dx9_33() +{ + helper_d3dx9_xx 33 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_34 dlls \ + title="MS d3dx9_34.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_34.dll" + +load_d3dx9_34() +{ + helper_d3dx9_xx 34 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_35 dlls \ + title="MS d3dx9_35.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_35.dll" + +load_d3dx9_35() +{ + helper_d3dx9_xx 35 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_36 dlls \ + title="MS d3dx9_36.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_36.dll" + +load_d3dx9_36() +{ + helper_d3dx9_xx 36 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_37 dlls \ + title="MS d3dx9_37.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_37.dll" + +load_d3dx9_37() +{ + helper_d3dx9_xx 37 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_38 dlls \ + title="MS d3dx9_38.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_38.dll" + +load_d3dx9_38() +{ + helper_d3dx9_xx 38 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_39 dlls \ + title="MS d3dx9_39.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_39.dll" + +load_d3dx9_39() +{ + helper_d3dx9_xx 39 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_40 dlls \ + title="MS d3dx9_40.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_40.dll" + +load_d3dx9_40() +{ + helper_d3dx9_xx 40 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_41 dlls \ + title="MS d3dx9_41.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_41.dll" + +load_d3dx9_41() +{ + helper_d3dx9_xx 41 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_42 dlls \ + title="MS d3dx9_42.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_42.dll" + +load_d3dx9_42() +{ + helper_d3dx9_xx 42 +} + +#---------------------------------------------------------------- + +w_metadata d3dx9_43 dlls \ + title="MS d3dx9_43.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx9_43.dll" + +load_d3dx9_43() +{ + helper_d3dx9_xx 43 +} + +#---------------------------------------------------------------- + +w_metadata d3dx11_42 dlls \ + title="MS d3dx11_42.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx11_42.dll" + +load_d3dx11_42() +{ + dllname=d3dx11_42 + + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native ${dllname} +} + +#---------------------------------------------------------------- + +w_metadata d3dx11_43 dlls \ + title="MS d3dx11_43.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx11_43.dll" + +load_d3dx11_43() +{ + dllname=d3dx11_43 + + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native ${dllname} +} + +#---------------------------------------------------------------- + +w_metadata d3dx10 dlls \ + title="MS d3dx10_??.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx10_33.dll" + +load_d3dx10() +{ + helper_directx_Jun2010 + + # Kinder, less invasive directx10 - only extract and override d3dx10_??.dll + w_try_cabextract -d "${W_TMP}" -L -F '*d3dx10*x86*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'd3dx10*.dll' "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F '*d3dx10*x64*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'd3dx10*.dll' "${x}" + done + fi + + # For now, not needed, but when Wine starts preferring our built-in DLL over native it will be. + w_override_dlls native d3dx10_33 d3dx10_34 d3dx10_35 d3dx10_36 d3dx10_37 + w_override_dlls native d3dx10_38 d3dx10_39 d3dx10_40 d3dx10_41 d3dx10_42 d3dx10_43 +} + +#---------------------------------------------------------------- + +w_metadata d3dx10_43 dlls \ + title="MS d3dx10_43.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dx10_43.dll" + +load_d3dx10_43() +{ + dllname=d3dx10_43 + + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x86*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "${dllname}.dll" "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F "*${dllname}*x64*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F "${dllname}.dll" "${x}" + done + fi + + w_override_dlls native ${dllname} +} + +#---------------------------------------------------------------- + +w_metadata d3dxof dlls \ + title="MS d3dxof.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3dxof.dll" + +load_d3dxof() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F 'dxnt.cab' "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'd3dxof.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native d3dxof +} + +#---------------------------------------------------------------- + +w_metadata dbghelp dlls \ + title="MS dbghelp" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dbghelp.dll" + +load_dbghelp() +{ + helper_winxpsp3 i386/dbghelp.dll + + w_try_cp_dll "${W_TMP}"/i386/dbghelp.dll "${W_SYSTEM32_DLLS}" + + w_override_dlls native dbghelp +} + +#---------------------------------------------------------------- + +w_metadata devenum dlls \ + title="MS devenum.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/devenum.dll" + +load_devenum() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F 'dxnt.cab' "${W_CACHE}/directx9/${DIRECTX_NAME}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'devenum.dll' "${W_TMP}/dxnt.cab" + w_override_dlls native devenum + w_try_regsvr devenum.dll +} + +#---------------------------------------------------------------- + +w_metadata dinput dlls \ + title="MS dinput.dll; breaks mouse, use only on Rayman 2 etc." \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dinput.dll" + +load_dinput() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F 'dxnt.cab' "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dinput.dll' "${W_TMP}/dxnt.cab" + w_override_dlls native dinput + w_try_regsvr dinput +} + +#---------------------------------------------------------------- + +w_metadata dinput8 dlls \ + title="MS DirectInput 8 from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dinput8.dll" + +load_dinput8() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F 'dxnt.cab' "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dinput8.dll' "${W_TMP}/dxnt.cab" + + # Don't try to register native dinput8; it doesn't export DllRegisterServer(). + #w_try_regsvr32 dinput8 + w_override_dlls native dinput8 +} + +#---------------------------------------------------------------- + +w_metadata directmusic dlls \ + title="MS DirectMusic from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmusic.dll" + +load_directmusic() +{ + # Untested. Based off https://bugs.winehq.org/show_bug.cgi?id=4805 and https://bugs.winehq.org/show_bug.cgi?id=24911 + + w_warn "You can specify individual DirectMusic verbs instead. e.g. 'winetricks dmsynth dmusic'" + + w_call dmband + w_call dmcompos + w_call dmime + w_call dmloader + w_call dmscript + w_call dmstyle + w_call dmsynth + w_call dmusic + w_call dmusic32 + w_call dsound + w_call dswave + + # FIXME: dxnt.cab doesn't contain this DLL. Is this really needed? + w_override_dlls native streamci +} + +#---------------------------------------------------------------- + +w_metadata directshow dlls \ + title="DirectShow runtime DLLs (amstream, qasf, qcap, qdvd, qedit, quartz)" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" + +load_directshow() +{ + w_warn "You can specify individual DirectShow verbs instead. e.g. 'winetricks quartz'" + + w_call amstream + w_call qasf + w_call qcap + w_call qdvd + w_call qedit + w_call quartz +} + +#---------------------------------------------------------------- + +w_metadata directplay dlls \ + title="MS DirectPlay from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dplayx.dll" + +load_directplay() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dplaysvr.exe' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dplayx.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpmodemx.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpnet.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpnhpast.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpnhupnp.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpnsvr.exe' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpwsockx.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dplaysvr.exe dplayx dpmodemx dpnet dpnhpast dpnhupnp dpnsvr.exe dpwsockx + + w_try_regsvr dplayx.dll + w_try_regsvr dpnet.dll + w_try_regsvr dpnhpast.dll + w_try_regsvr dpnhupnp.dll +} + +#---------------------------------------------------------------- + +w_metadata directx9 dlls \ + title="MS DirectX 9 (Deprecated, no-op)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" + +load_directx9() +{ + # There are 54 as of 2019/04/23, so listing them all (especially in GUI) would be hard. + # Besides, that would probably encourage people to install more native stuff than necessary. + w_warn "directx9 is deprecated. Please install individual directx components (e.g., \`$0 d3dx9\`) instead." +} + +#---------------------------------------------------------------- + +w_metadata dpvoice dlls \ + title="Microsoft dpvoice dpvvox dpvacm Audio dlls" \ + publisher="Microsoft" \ + year="2002" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dpvoice.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dpvvox.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dpvacm.dll" + +load_dpvoice() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F 'dxnt.cab' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpvoice.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpvvox.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dpvacm.dll' "${x}" + done + w_override_dlls native dpvoice dpvvox dpvacm + w_try_regsvr dpvoice.dll + w_try_regsvr dpvvox.dll + w_try_regsvr dpvacm.dll +} + +#---------------------------------------------------------------- + +w_metadata dsdmo dlls \ + title="MS dsdmo.dll" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dsdmo.dll" + +load_dsdmo() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dsdmo.dll' "${W_TMP}/dxnt.cab" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dsdmoprp.dll' "${W_TMP}/dxnt.cab" + w_try_regsvr dsdmo.dll + w_try_regsvr dsdmoprp.dll +} + +#---------------------------------------------------------------- + +w_metadata dxsdk_nov2006 apps \ + title="MS DirectX SDK, November 2006 (developers only)" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="dxsdk_aug2006.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft DirectX SDK (August 2006)/Lib/x86/d3d10.lib" + +load_dxsdk_nov2006() +{ + w_download https://download.microsoft.com/download/9/e/5/9e5bfc66-a621-4e0d-8bfe-6688058c3f00/dxsdk_aug2006.exe ab8d7d895089a88108d4148ef0f7e214b7a23c1ee9ba720feca78c7d4ca16c00 + + # dxview.dll uses mfc42u while registering + w_call mfc42 + + w_try_cabextract "${W_CACHE}"/dxsdk_nov2006/dxsdk_aug2006.exe + w_try_unzip "${W_TMP}" dxsdk.exe + w_try_cd "${W_TMP}" + w_try "${WINE}" msiexec /i Microsoft_DirectX_SDK.msi ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata dxsdk_jun2010 apps \ + title="MS DirectX SDK, June 2010 (developers only)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="DXSDK_Jun10.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft DirectX SDK (June 2010)/Lib/x86/d3d11.lib" + +load_dxsdk_jun2010() +{ + w_download https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe 9f818a977c32b254af5d649a4cec269ed8762f8a49ae67a9f01101a7237ae61a + + # Without dotnet20, install aborts halfway through + w_call dotnet20 + + w_try_cd "${W_TMP}" + w_try "${WINE}" "${W_CACHE}"/dxsdk_jun2010/DXSDK_Jun10.exe ${W_OPT_UNATTENDED:+/U} +} + +#---------------------------------------------------------------- + +w_metadata dxtrans dlls \ + title="MS dxtrans.dll" \ + publisher="Microsoft" \ + year="2002" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dxtrans.dll" \ + +load_dxtrans() +{ + helper_winxpsp3 i386/dxtrans.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/dxtrans.dl_ + w_override_dlls native,builtin dxtrans + w_try_regsvr dxtrans.dll +} + +#---------------------------------------------------------------- + +# $1 - dxvk archive name (required) +# $2 - minimum Wine version (required) +# $3 - minimum Vulkan API version (required) +# $4 - [dxgi,][d3d9,][d3d10core,][d3d10,]d3d11 (required) +helper_dxvk_d9vk() +{ + _W_package_archive="${1}" + _W_min_wine_version="${2}" + _W_min_vulkan_version="${3}" + _W_dll_overrides="$(echo "${4}" | sed 's/,/ /g')" + + _W_supported_overrides="dxgi d3d9 d3d10core d3d10 d3d11" + _W_invalid_overrides="$(echo "${_W_dll_overrides}" | awk -vvalid_overrides_regex="$(echo "${_W_supported_overrides}" | sed 's/ /|/g')" '{ gsub(valid_overrides_regex,""); sub("[ ]*",""); print $0 }')" + if [ "${_W_invalid_overrides}" != "" ]; then + w_die "parameter (4) unsupported dll override: '${_W_invalid_overrides}' ; supported dll overrides: ${_W_supported_overrides}" + fi + + _W_dll_overrides="$(echo "${_W_dll_overrides}" | sed 's/d3d10 /&d3d10_1 /')" + + case "${_W_package_archive}" in + d9vk*) + # dvk9 repository, for d3d9/d3d10/d3d11 support + _W_repository="Joshua-Ashton/d9vk" + ;; + dxvk*) + # dxvk repository, for d3d9/d3d10/d3d11 support + _W_repository="doitsujin/dxvk" + ;; + *) + w_die "parameter (1): unsupported package archive repository: '${_W_package_archive}'; supported: d9vk dxvk" + ;; + esac + + case "${_W_package_archive}" in + *master*) + _W_package_dir="build/dxvk-release" + _W_package_version="master" + w_warn "Using master ${_W_repository} build" + ;; + *) + _W_package_dir="${_W_package_archive%.tar.gz}" + _W_package_version="${_W_package_dir#*-}" + w_warn "Please refer to ${_W_repository#*/} version ${_W_package_version} release notes... See: https://github.com/${_W_repository}/releases/tag/${_W_package_version}" + ;; + esac + w_warn "Please refer to current dxvk base graphics driver requirements... See: https://github.com/doitsujin/dxvk/wiki/Driver-support" + + if w_wine_version_in ",${_W_min_wine_version}" ; then + # shellcheck disable=SC2140 + w_warn "${_W_repository#*/} ${_W_package_version} does not support wine version ${_wine_version_stripped} . "\ + "${_W_repository#*/} ${_W_package_version} requires wine version ${_W_min_wine_version} (or newer). "\ + "Vulkan ${_W_min_vulkan_version} API (or newer) support is recommended." + fi + + if [ "${_W_package_archive##*.}" = "zip" ]; then + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}" + else + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}" + fi + + for _W_dll in ${_W_dll_overrides}; do + w_try mv "${W_TMP}/${_W_package_dir}/x32/${_W_dll}.dll" "${W_SYSTEM32_DLLS}/" + [ "${_W_dll}" = "d3d9" ] && _W_d3d9_support="1" + done + if test "${W_ARCH}" = "win64"; then + for _W_dll in ${_W_dll_overrides}; do + w_try mv "${W_TMP}/${_W_package_dir}/x64/${_W_dll}.dll" "${W_SYSTEM64_DLLS}/" + done + fi + # shellcheck disable=SC2086 + w_override_dlls native ${_W_dll_overrides} + if [ -n "${_W_d3d9_support}" ]; then + w_call d3dcompiler_43 + w_call d3dx9 + fi + + unset _W_d3d9_support _W_dll _W_dll_overrides _W_invalid_overrides _W_min_vulkan_version _W_min_wine_version \ + _W_package_archive _W_package_dir _W_package_version \ + _W_repository _W_supported_overrides +} + + +#---------------------------------------------------------------- + +w_metadata dxvk0054 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.54)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.54.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0054() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.54/dxvk-0.54.tar.gz" 1c2f186baaa01d2de7b832f6f05021bdd29eccb65fc197c8b15adfd4e08f9640 + helper_dxvk_d9vk "${file1}" "3.10" "1.1.72" "dxgi,d3d11" +} + +w_metadata dxvk0060 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.60)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.60.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0060() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.60/dxvk-0.60.tar.gz" 27d6f700241d3ec3b6c002c3d739bb0e3f210ec916ecb5a62d9204e9e50f2c4a + helper_dxvk_d9vk "${file1}" "3.10" "1.1.72" "dxgi,d3d11" +} + +w_metadata dxvk0061 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.61)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.61.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0061() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.61/dxvk-0.61.tar.gz" d04388f026dc0d8b276b08f7db74fb3556cbbc8f762401eb5ef52629ee39ded1 + helper_dxvk_d9vk "${file1}" "3.10" "1.1.72" "dxgi,d3d11" +} + +w_metadata dxvk0062 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.62)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.62.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0062() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.62/dxvk-0.62.tar.gz" b9dbb57908e24b094b68f665ad729b6ee277eecc8ba04a6e6e4f8a4d2dfd94e3 + helper_dxvk_d9vk "${file1}" "3.10" "1.1.72" "dxgi,d3d11" +} + +w_metadata dxvk0063 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.63)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.63.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0063() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.63/dxvk-0.63.tar.gz" 696df816bd9640770dee14f932bc641a16261fccf76be7c28d812a64ca6040fa + helper_dxvk_d9vk "${file1}" "3.18" "1.1.80" "dxgi,d3d11" +} + +w_metadata dxvk0064 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.64)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.64.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0064() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.64/dxvk-0.64.tar.gz" 2e03e40ff0a9d36f96a06137f3fa9110ebaea230d0bf6c22cf6399e16e97fb9c + helper_dxvk_d9vk "${file1}" "3.18" "1.1.80" "dxgi,d3d11" +} + +w_metadata dxvk0065 dlls \ + title="Vulkan-based D3D11 implementation for Linux / Wine (0.65)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.65.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0065() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.65/dxvk-0.65.tar.gz" 7b4eb42e693f925d0aff90bae261b20c50428602382ee94a3e3860b2ad1ebad0 + helper_dxvk_d9vk "${file1}" "3.18" "1.1.80" "dxgi,d3d11" +} + +w_metadata dxvk0070 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.70)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.70.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0070() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.70/dxvk-0.70.tar.gz" 310546d530be494a35cae49b707fef4b073269d811aac25bdf72899ed1df4e9f + helper_dxvk_d9vk "${file1}" "3.18" "1.1.80" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0071 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.71)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.71.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0071() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.71/dxvk-0.71.tar.gz" fbe66337d1450f366961a7699253cd7a96c12a88c2fcda64b79be1cbb13d37d5 + helper_dxvk_d9vk "${file1}" "3.18" "1.1.80" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0072 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.72)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.72.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0072() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.72/dxvk-0.72.tar.gz" bc84f48f99cf5add3c8919a43d7a9c0bf208c994dc58326a636b56b8db650c52 + helper_dxvk_d9vk "${file1}" "3.18" "1.1.84" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0080 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.80)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.80.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0080() +{ + # https://github.com/doitsujin/dxvk + # 2017/09/23: f9e736cdbf1e83e45ca748652a94a3a189fc5accde1eac549b2ba5af8f7acacb + # 2017/11/17: 7058a834bb006cad5462933110449b434df561e67d83f68d3965ecc74e2e1cbc + # See: https://github.com/doitsujin/dxvk/issues/773 + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.80/dxvk-0.80.tar.gz" 7058a834bb006cad5462933110449b434df561e67d83f68d3965ecc74e2e1cbc + helper_dxvk_d9vk "${file1}" "3.18" "1.1.84" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0081 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.81)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.81.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0081() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.81/dxvk-0.81.tar.gz" 9bf6eda9ae4ee74b509e07dfe9cc003dfa4bba192b519dacdd542a57f6a43869 + helper_dxvk_d9vk "${file1}" "3.18" "1.1.84" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0090 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.90)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.90.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0090() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.90/dxvk-0.90.tar.gz" 15bce7b282065054ff9233b33738bf1d2c74b16829361cbd6843bc2f5dfe4509 + helper_dxvk_d9vk "${file1}" "3.19" "1.1.87" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0091 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.91)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.91.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0091() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.91/dxvk-0.91.tar.gz" 5296106ac3a8c631d7f26fa46dbff4be1332cda14fa493fd89ccf97e050c4855 + helper_dxvk_d9vk "${file1}" "3.19" "1.1.87" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0092 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.92)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.92.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0092() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.92/dxvk-0.92.tar.gz" e22c0ae4693aac88562c7a9a97b3316e086b9048c9f8f9e128923ac1611a5c49 + helper_dxvk_d9vk "${file1}" "3.19" "1.1.87" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0093 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.93)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.93.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0093() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.93/dxvk-0.93.tar.gz" 4d964e4e10e67ba7705312496e472ae9859520a78d8742d6d377886318c95e53 + helper_dxvk_d9vk "${file1}" "4.0" "1.1.93" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0094 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.94)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.94.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0094() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.94/dxvk-0.94.tar.gz" 1f06bfac5b435b62b972806fb3bbd86f7ccae2399b4451e85ae414e03d3712a3 + helper_dxvk_d9vk "${file1}" "4.0" "1.1.93" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0095 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.95)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.95.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0095() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.95/dxvk-0.95.tar.gz" 1eea48149f6e94c3c74ecddd92df4f9daa67ab28d0fca548bde5cd40f0e486bf + helper_dxvk_d9vk "${file1}" "4.0" "1.1.93" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk0096 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (0.96)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-0.96.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk0096() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v0.96/dxvk-0.96.tar.gz" 9d054c1e7a4f59825c651b14d3cfbf0d8c724763f485b3d59c89f1d7194b2206 + helper_dxvk_d9vk "${file1}" "4.0" "1.1.93" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1000 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.0)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.0.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1000() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.0/dxvk-1.0.tar.gz" 8c8d26544609532201c10e6f5309bf5e913b5ca5b985932928ef9ab238de6dc2 + helper_dxvk_d9vk "${file1}" "4.5" "1.1.101" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1001 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.0.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.0.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1001() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.0.1/dxvk-1.0.1.tar.gz" 739847cdd14b302dac600c66bc6617d7814945df6d4d7b6c91fecfa910e3b1b1 + helper_dxvk_d9vk "${file1}" "4.5" "1.1.101" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1002 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.0.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.0.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1002() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.0.2/dxvk-1.0.2.tar.gz" f9504b188488d1102cba7e82c28681708f39e151af1c1ef7ebeac82d729c01ac + helper_dxvk_d9vk "${file1}" "4.5" "1.1.101" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1003 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.0.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.0.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1003() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.0.3/dxvk-1.0.3.tar.gz" 984d28ab3a112be207d6339da19113d1117e56731ed413d0e202e6fd1391a6ae + helper_dxvk_d9vk "${file1}" "4.5" "1.1.101" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1011 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.1.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.1.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1011() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.1.1/dxvk-1.1.1.tar.gz" 346c523953f72ac5885071c4384039faf01f6f43a88d5b0c12d94bfaa9598c1d + helper_dxvk_d9vk "${file1}" "4.5" "1.1.104" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1020 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1020() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.2/dxvk-1.2.tar.gz" 414751a810143ced34d1f4f0eb2a40e79b4c9726318994b244b70d1b3a6f8b32 + helper_dxvk_d9vk "${file1}" "4.5" "1.1.104" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1021 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.2.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.2.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1021() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.2.1/dxvk-1.2.1.tar.gz" 192beca0a34d13f101e9c2545d9533cf84830a23b566bed185c022ed754c3daa + helper_dxvk_d9vk "${file1}" "4.5" "1.1.104" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1022 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.2.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.2.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1022() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.2.2/dxvk-1.2.2.tar.gz" dfe620a387222dc117a6722171e0bca400755a3e1c6459350c710dfda40b6701 + helper_dxvk_d9vk "${file1}" "4.5" "1.1.104" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1023 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.2.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.2.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1023() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.2.3/dxvk-1.2.3.tar.gz" 29ce345b3d962dbd8ec8bfda190635a21f62124e3e46f06e89aa2f3b1e230321 + helper_dxvk_d9vk "${file1}" "4.5" "1.1.104" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1030 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1030() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.3/dxvk-1.3.tar.gz" d15fac6503ea614986237052d554d7cbd2dbf5f3486feb6217e64bae83cfc2cf + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1031 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.3.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.3.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1031() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.3.1/dxvk-1.3.1.tar.gz" 2f6636dbd591ea9de20b30a33c9c8c0985a4939f6503f90ca5c7edafd01524a3 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1032 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.3.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.3.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1032() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.3.2/dxvk-1.3.2.tar.gz" aa70890a17b48be27648d15cb837b5167c99f75ee32ae0c94a85ec1f1fdc4675 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1033 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.3.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.3.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1033() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.3.3/dxvk-1.3.3.tar.gz" 828171ad1dbb6b51f367fa46cf33f8db4a0b1b990cd2e95654d6a65500d230b7 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1034 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.3.4)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.3.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1034() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.3.4/dxvk-1.3.4.tar.gz" 4683e2ad4221b16572b0d939da5a05ab9a16b2b62c2f4e0c8bf3b2cdb27918ff + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1040 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1040() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4/dxvk-1.4.tar.gz" bf22785de1ce728bbdcfb4615035924112b4718049ca2cade5861b03735181de + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1041 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1041() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.1/dxvk-1.4.1.tar.gz" 574ec4dc5201e45d70472228f0c6695426f0392503ec7a47d6092600aac53a07 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1042 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1042() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.2/dxvk-1.4.2.tar.gz" 5adfd71ee0299798af4402f09f113f88929af429b6889af334cff5b84b84dbe6 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1043 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1043() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.3/dxvk-1.4.3.tar.gz" e4b9e7fc8faf2dd1ddf5206e14939a822034a85778d54a6950767d68909726f7 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1044 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.4)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1044() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.4/dxvk-1.4.4.tar.gz" a845285c8dfc63c7d00c14520b58fc6048796fef69fea49617edb46662a0ba31 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1045 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.5)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.5.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1045() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.5/dxvk-1.4.5.tar.gz" 566c93dce84c3c2f39938428ddcca27a5bb2f5068eb4f868ff2126389b965cd1 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1046 dlls \ + title="Vulkan-based D3D10/D3D11 implementation for Linux / Wine (1.4.6)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.4.6.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1046() +{ + # https://github.com/doitsujin/dxvk + # Original sha256sum: 1aa069f5ea7d3d6e374bda332d12f9207f1a21e9811c4d4d82487416420ee73e + # Upstream later rebuilt with commit 1ae7d4b30283d2eb06b467c581aafdbbd9d36cdf: c9e3a96d8c5e693e20f69f27ac3f8b55198449fddd24205195476d6af7e8a339 + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.4.6/dxvk-1.4.6.tar.gz" c9e3a96d8c5e693e20f69f27ac3f8b55198449fddd24205195476d6af7e8a339 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1050 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1050() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5/dxvk-1.5.tar.gz" 90cfae0bb43fed1e46442d20e2ab3bf448ebdff1e9f4f59841dc922aa3a36d3b + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1051 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1051() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5.1/dxvk-1.5.1.tar.gz" 474ce9995edd47a3bd347a8f3263f35cf8df2676f5b16668bf38efa298d75c01 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1052 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1052() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5.2/dxvk-1.5.2.tar.gz" 684ba886b5ed922c2417753d8178f923c695258c69cc8f778bb59b99bbf62477 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1053 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1053() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5.3/dxvk-1.5.3.tar.gz" b845c9c492e32648dee44d058c189eff8534e5490a80a3b2a921248bc72e33bd + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1054 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5.4)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1054() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5.4/dxvk-1.5.4.tar.gz" 8e4fd15525def9bcaa9cc1b4496f76a2664ba4806b02a5ac0eddd703d7bbdea7 + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1055 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.5.5)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.5.5.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d10.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10_1.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file5="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1055() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.5.5/dxvk-1.5.5.tar.gz" f4c57274ac85d71b192e2a0ac095f285e26cc054c87c6c34c081f919147539eb + helper_dxvk_d9vk "${file1}" "4.20" "1.1.113" "dxgi,d3d9,d3d10core,d3d10,d3d11" +} + +w_metadata dxvk1060 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.6)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.6.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1060() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.6/dxvk-1.6.tar.gz" a493e0802e02629244672c44ad92c40fa0813b38908677ae14ee07feefcf7227 + helper_dxvk_d9vk "${file1}" "5.3" "1.1.113" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1061 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.6.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.6.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1061() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.6.1/dxvk-1.6.1.tar.gz" cdef8735313ed9ccb7af23b37bcceaad54553e29505c269246d5e347f1359136 + helper_dxvk_d9vk "${file1}" "5.3" "1.1.113" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1070 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.7)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.7.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1070() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.7/dxvk-1.7.tar.gz" 67d78239906c24bd50a5ecbc2fd792c1721e274a7a60dd22f74b21b08ca4c7a1 + helper_dxvk_d9vk "${file1}" "5.8" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1071 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.7.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.7.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1071() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.7.1/dxvk-1.7.1.tar.gz" 6ce66c4e01196ed022604e90383593aea02c9016bde92c6840aa58805d5fc588 + helper_dxvk_d9vk "${file1}" "5.8" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1072 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.7.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.7.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1072() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.7.2/dxvk-1.7.2.tar.gz" 1662f6bda93faf4f6c8b57d656779b08925889dd6b794114be874d6deb97e15b + helper_dxvk_d9vk "${file1}" "5.8" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1073 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.7.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.7.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1073() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.7.3/dxvk-1.7.3.tar.gz" e4c2444256b7ad63455fa6329638e3f42900ec7462dc9c26da56187a2040aba0 + helper_dxvk_d9vk "${file1}" "5.8" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1080 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.8)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.8.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1080() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.8/dxvk-1.8.tar.gz" e84f7ac494ac7f5013976744470899226d145e29617c407ff52870055bda476e + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1081 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.8.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.8.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1081() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.8.1/dxvk-1.8.1.tar.gz" 756a09c46f8279ade84456e3af038f64613a51e00a2d4cfffa4c91c10ede60e8 + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1090 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.9)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.9.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1090() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.9/dxvk-1.9.tar.gz" 433868f8783887192a04b788203d6b4effe3168be762dd60df1c1b564421a6ed + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1091 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.9.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.9.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1091() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.9.1/dxvk-1.9.1.tar.gz" ef7591d6effcca8a8352cea4fa50fe73aa1f10fd89cb475f2f14236e4340a007 + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1092 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.9.2)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.9.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1092() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.9.2/dxvk-1.9.2.tar.gz" 24bcee655767f4731b8d3883dd93ba4edc7f1e87421e15fab19499d57236b8e9 + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1093 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.9.3)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.9.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1093() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.9.3/dxvk-1.9.3.tar.gz" cfcf4fac1f6bfc5a09183e77362a0af7fead4e54961bb548aef3e6cddadbe9bf + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1094 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.9.4)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.9.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1094() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.9.4/dxvk-1.9.4.tar.gz" 854f564c3b58a4cdf7b16eb9a4b6bc6ddc0f83d68c4f979a529fc23f7a770502 + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1100 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.10)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.10.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1100() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.10/dxvk-1.10.tar.gz" a15bc7c1df66158a205c498883b0b216390d58f4a128657990af357431b9ce77 + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +w_metadata dxvk1101 dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.10.1)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + file1="dxvk-1.10.1.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk1101() +{ + # https://github.com/doitsujin/dxvk + w_download "https://github.com/doitsujin/dxvk/releases/download/v1.10.1/dxvk-1.10.1.tar.gz" dc349482cb0a73d4e29c82f8e9ff6031e09e176e84a97ffe91eac64422b307aa + helper_dxvk_d9vk "${file1}" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" +} + +#---------------------------------------------------------------- + +w_metadata dxvk dlls \ + title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (latest)" \ + publisher="Philip Rebohle" \ + year="2017" \ + media="download" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/d3d10core.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/d3d11.dll" \ + installed_file4="${W_SYSTEM32_DLLS_WIN}/dxgi.dll" + +load_dxvk() +{ + # https://github.com/doitsujin/dxvk + _W_dxvk_version="$(w_get_github_latest_release doitsujin dxvk)" + _W_dxvk_version="${_W_dxvk_version#v}" + w_linkcheck_ignore=1 w_download "https://github.com/doitsujin/dxvk/releases/download/v${_W_dxvk_version}/dxvk-${_W_dxvk_version}.tar.gz" + helper_dxvk_d9vk "dxvk-${_W_dxvk_version}.tar.gz" "5.14" "1.2.140" "dxgi,d3d9,d3d10core,d3d11" + unset _W_dxvk_version +} + +#---------------------------------------------------------------- + +# $1 - vkd3d-proton archive name (required) +helper_vkd3d_proton() +{ + _W_package_archive="${1}" + + _W_dll_overrides="d3d12" + + case "${_W_package_archive}" in + vkd3d-proton*) + _W_repository="HansKristian-Work/vkd3d-proton" + ;; + *) + w_die "parameter (1): unsupported package archive repository: '${_W_package_archive}'; supported: vkd3d-proton" + ;; + esac + + case "${_W_package_archive}" in + *master*) + _W_package_dir="build/vkd3d-proton-release" + _W_package_version="master" + w_warn "Using master ${_W_repository} build" + ;; + *) + _W_package_dir="${_W_package_archive%.tar.zst}" + _W_package_version="${_W_package_dir#*-}" + _W_package_version="${_W_package_version#*-}" + w_warn "Please refer to ${_W_repository#*/} version ${_W_package_version} release notes... See: https://github.com/${_W_repository}/releases/tag/${_W_package_version}" + ;; + esac + w_warn "Please refer to current vkd3d-proton base graphics driver requirements... See: https://github.com/HansKristian-Work/vkd3d-proton#drivers" + + if [ "${_W_package_archive##*.}" = "zip" ]; then + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}" + elif [ "${_W_package_archive##*.}" = "zst" ]; then + w_try_cd "${W_TMP}" + w_try tar -I zstd -xvf "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}" + else + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}" + fi + + for _W_dll in ${_W_dll_overrides}; do + w_try mv "${W_TMP}/${_W_package_dir}/x86/${_W_dll}.dll" "${W_SYSTEM32_DLLS}/" + done + if test "${W_ARCH}" = "win64"; then + for _W_dll in ${_W_dll_overrides}; do + w_try mv "${W_TMP}/${_W_package_dir}/x64/${_W_dll}.dll" "${W_SYSTEM64_DLLS}/" + done + fi + # shellcheck disable=SC2086 + w_override_dlls native ${_W_dll_overrides} + + unset _W_dll _W_dll_overrides _W_package_archive _W_package_dir \ + _W_package_version _W_repository +} + +#---------------------------------------------------------------- + +w_metadata vkd3d dlls \ + title="Vulkan-based D3D12 implementation for Linux / Wine (latest)" \ + publisher="Hans-Kristian Arntzen " \ + year="2020" \ + media="download" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d12.dll" + +load_vkd3d() +{ + # https://github.com/HansKristian-Work/vkd3d-proton + _W_vkd3d_proton_version="$(w_get_github_latest_release HansKristian-Work vkd3d-proton)" + _W_vkd3d_proton_version="${_W_vkd3d_proton_version#v}" + w_linkcheck_ignore=1 w_download "https://github.com/HansKristian-Work/vkd3d-proton/releases/download/v${_W_vkd3d_proton_version}/vkd3d-proton-${_W_vkd3d_proton_version}.tar.zst" + helper_vkd3d_proton "vkd3d-proton-${_W_vkd3d_proton_version}.tar.zst" + unset _W_vkd3d_proton_version +} + +#---------------------------------------------------------------- + +w_metadata dmusic32 dlls \ + title="MS dmusic32.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="../directx9/directx_apr2006_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmusic32.dll" + +load_dmusic32() +{ + w_download_to directx9 https://web.archive.org/web/20100920035904/https://download.microsoft.com/download/3/9/7/3972f80c-5711-4e14-9483-959d48a2d03b/directx_apr2006_redist.exe dd8c3d401efe4561b67bd88475201b2f62f43cd23e4acc947bb34a659fa74952 + + w_try_cabextract -d "${W_TMP}" -F DirectX.cab "${W_CACHE}"/directx9/directx_apr2006_redist.exe + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F dmusic32.dll "${W_TMP}"/DirectX.cab + + w_override_dlls native dmusic32 +} + +#---------------------------------------------------------------- + +w_metadata dmband dlls \ + title="MS dmband.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmband.dll" + +load_dmband() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmband.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmband + w_try_regsvr dmband.dll +} + +#---------------------------------------------------------------- + +w_metadata dmcompos dlls \ + title="MS dmcompos.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmcompos.dll" + +load_dmcompos() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmcompos.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmcompos + w_try_regsvr dmcompos.dll +} + +#---------------------------------------------------------------- + +w_metadata dmime dlls \ + title="MS dmime.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmime.dll" + +load_dmime() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmime.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmime + w_try_regsvr dmime.dll +} + +#---------------------------------------------------------------- + +w_metadata dmloader dlls \ + title="MS dmloader.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmloader.dll" + +load_dmloader() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmloader.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmloader + w_try_regsvr dmloader.dll +} + +#---------------------------------------------------------------- + +w_metadata dmscript dlls \ + title="MS dmscript.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmscript.dll" + +load_dmscript() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmscript.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmscript + w_try_regsvr dmscript.dll +} + +#---------------------------------------------------------------- + +w_metadata dmstyle dlls \ + title="MS dmstyle.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmstyle.dll" + +load_dmstyle() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmstyle.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmstyle + w_try_regsvr dmstyle.dll +} + +#---------------------------------------------------------------- + +w_metadata dmsynth dlls \ + title="MS dmsynth.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmsynth.dll" + +load_dmsynth() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmsynth.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmsynth + w_try_regsvr dmsynth.dll +} + +#---------------------------------------------------------------- + +w_metadata dmusic dlls \ + title="MS dmusic.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dmusic.dll" + +load_dmusic() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dmusic.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dmusic + w_try_regsvr dmusic.dll +} + +#---------------------------------------------------------------- + +w_metadata dswave dlls \ + title="MS dswave.dll from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dswave.dll" + +load_dswave() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dswave.dll' "${W_TMP}/dxnt.cab" + + w_override_dlls native dswave + w_try_regsvr dswave.dll +} + +#---------------------------------------------------------------- + +w_metadata dotnet11 dlls \ + title="MS .NET 1.1" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + conflicts="dotnet20sdk" \ + file1="dotnetfx.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v1.1.4322/ndpsetup.ico" + +load_dotnet11() +{ + # The installer itself doesn't support 64-bit + w_package_unsupported_win64 + + # https://www.microsoft.com/en-us/download/details.aspx?id=26 + w_download https://web.archive.org/web/20210505032023/http://download.microsoft.com/download/a/a/c/aac39226-8825-44ce-90e3-bf8203e74006/dotnetfx.exe ba0e58ec93f2ffd54fc7c627eeca9502e11ab3c6fc85dcbeff113bd61d995bce + + w_call remove_mono + w_call corefonts + w_call fontfix + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + # Use builtin regsvcs.exe to work around https://bugs.winehq.org/show_bug.cgi?id=25120 + if [ -n "${W_OPT_UNATTENDED}" ]; then + WINEDLLOVERRIDES="regsvcs.exe=b" w_ahk_do " + SetTitleMatchMode, 2 + run, dotnetfx.exe /q /C:\"install /q\" + + Loop + { + sleep 1000 + ifwinexist, Fatal error, Failed to delay load library + { + WinClose, Fatal error, Failed to delay load library + continue + } + Process, exist, dotnetfx.exe + dotnet_pid = %ErrorLevel% ; Save the value immediately since ErrorLevel is often changed. + if dotnet_pid = 0 + { + break + } + } + " + else + WINEDLLOVERRIDES="regsvcs.exe=b" w_try "${WINE}" dotnetfx.exe + fi + + w_override_dlls native mscorwks + w_override_dlls native fusion + + W_NGEN_CMD="w_try ${WINE} ${W_DRIVE_C}/windows/Microsoft.NET/Framework/v1.1.4322/ngen.exe executequeueditems" +} + +verify_dotnet11() +{ + w_dotnet_verify dotnet11 +} + +#---------------------------------------------------------------- + +w_metadata dotnet11sp1 dlls \ + title="MS .NET 1.1 SP1" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="NDP1.1sp1-KB867460-X86.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v1.1.4322/CONFIG/web_hightrust.config.default" + +load_dotnet11sp1() +{ + # The installer itself doesn't support 64-bit + w_package_unsupported_win64 + + w_download https://download.microsoft.com/download/8/b/4/8b4addd8-e957-4dea-bdb8-c4e00af5b94b/NDP1.1sp1-KB867460-X86.exe 2c0a35409ff0873cfa28b70b8224e9aca2362241c1f0ed6f622fef8d4722fd9a + + w_call remove_mono + w_call dotnet11 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + # Use builtin regsvcs.exe to work around https://bugs.winehq.org/show_bug.cgi?id=25120 + if [ -n "${W_OPT_UNATTENDED}" ]; then + WINEDLLOVERRIDES="regsvcs.exe=b" w_ahk_do " + SetTitleMatchMode, 2 + run, NDP1.1sp1-KB867460-X86.exe /q /C:"install /q" + + Loop + { + sleep 1000 + ifwinexist, Fatal error, Failed to delay load library + { + WinClose, Fatal error, Failed to delay load library + continue + } + Process, exist, dotnetfx.exe + dotnet_pid = %ErrorLevel% ; Save the value immediately since ErrorLevel is often changed. + if dotnet_pid = 0 + { + break + } + } + " + else + WINEDLLOVERRIDES="regsvcs.exe=b" w_try "${WINE}" "${W_CACHE}"/dotnet11sp1/NDP1.1sp1-KB867460-X86.exe + fi + + w_override_dlls native mscorwks + + W_NGEN_CMD="w_try ${WINE} ${W_DRIVE_C}/windows/Microsoft.NET/Framework/v1.1.4322/ngen.exe executequeueditems" +} + +verify_dotnet11sp1() +{ + w_dotnet_verify dotnet11sp1 +} + +#---------------------------------------------------------------- + +w_metadata dotnet20 dlls \ + title="MS .NET 2.0" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + conflicts="dotnet20sp1 dotnet20sp2 dotnet30sp1 dotnet35" \ + file1="dotnetfx.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v2.0.50727/MSBuild.exe" + +load_dotnet20() +{ + w_call remove_mono + w_call fontfix + + if [ "${W_ARCH}" = "win32" ]; then + # https://www.microsoft.com/en-us/download/details.aspx?id=19 + w_download https://download.lenovo.com/ibmdl/pub/pc/pccbbs/thinkvantage_en/dotnetfx.exe 46693d9b74d12454d117cc61ff2e9481cabb100b4d74eb5367d3cf88b89a0e71 + + # Needed for https://bugs.winehq.org/show_bug.cgi?id=12401 + w_set_winver win2k + + # if dotnet11 if installed there is a warning dialog, but it still verifies + # dotnet11 doesn't work on 64-bit, so no need to run there + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if [ -n "${W_OPT_UNATTENDED}" ]; then + w_ahk_do " + SetTitleMatchMode, 2 + ; FIXME: this isn't silent? + run, dotnetfx.exe /q /c:\"install.exe /q\" + + Loop + { + sleep 1000 + ifwinexist, .NET Framework Initialization Error + { + WinClose, .NET Framework Initialization Error + continue + } + + Process, exist, dotnetfx.exe + dotnet_pid = %ErrorLevel% + if dotnet_pid = 0 + { + break + } + } + " + else + w_try_ms_installer "${WINE}" dotnetfx.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + fi + + w_set_winver 'default' + + # We can't stop installing dotnet20 in win2k mode until Wine supports + # reparse/junction points + # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 ) + # so for now just remove the bogus msvc*80.dll files it installs. + # See also https://bugs.winehq.org/show_bug.cgi?id=16577 + # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967 + rm -f "${W_SYSTEM32_DLLS}"/msvc?80.dll + elif [ "${W_ARCH}" = "win64" ]; then + w_download https://download.microsoft.com/download/a/3/f/a3f1bf98-18f3-4036-9b68-8e6de530ce0a/NetFx64.exe 7ea86dca8eeaedcaa4a17370547ca2cea9e9b6774972b8e03d2cb1fb0e798669 + + # validates successfully in win7 mode wine-3.19, so not setting winversion + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" NetFx64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + fi + + w_override_dlls native mscorwks + + W_NGEN_CMD="w_try ${WINE} ${W_DRIVE_C}/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems" +} + +verify_dotnet20() +{ + w_package_broken_win64 https://bugs.winehq.org/show_bug.cgi?id=49550 5.7 + + w_dotnet_verify dotnet20 +} + +#---------------------------------------------------------------- + +w_metadata dotnet20sdk apps \ + title="MS .NET 2.0 SDK" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + conflicts="dotnet11 dotnet20sp1 dotnet20sp2 dotnet30 dotnet40" \ + file1="setup.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft.NET/SDK/v2.0/Bin/cordbg.exe" + +load_dotnet20sdk() +{ + w_package_unsupported_win64 + + # https://www.microsoft.com/en-us/download/details.aspx?id=19988 + w_download https://download.microsoft.com/download/c/4/b/c4b15d7d-6f37-4d5a-b9c6-8f07e7d46635/setup.exe 1d7337bfbb2c65f43c82d188688ce152af403bcb67a2cc2a3cc68a580ecd8200 + + w_call remove_mono + + w_call dotnet20 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, setup.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + + Loop + { + sleep 1000 + ifwinexist, Microsoft Document Explorer, Application Data folder + { + WinClose, Microsoft Document Explorer, Application Data folder + continue + } + ifwinexist, Microsoft CLR Debugger, Application Data folder + { + WinClose, Microsoft CLR Debugger, Application Data folder + continue + } + ; FIXME: only appears if dotnet30sp1 is run first? + ifwinexist, Microsoft .NET Framework 2.0 SDK Setup, This wizard will guide + { + ControlClick, Button22, Microsoft .NET Framework 2.0 SDK Setup + Winwait, Microsoft .NET Framework 2.0 SDK Setup, By clicking + sleep 100 + ControlClick, Button21 + sleep 100 + ControlClick, Button18 + WinWait, Microsoft .NET Framework 2.0 SDK Setup, Select from + sleep 100 + ControlClick, Button12 + WinWait, Microsoft .NET Framework 2.0 SDK Setup, Type the path + sleep 100 + ControlClick, Button8 + WinWait, Microsoft .NET Framework 2.0 SDK Setup, successfully installed + sleep 100 + ControlClick, Button2 + sleep 100 + } + Process, exist, setup.exe + dotnet_pid = %ErrorLevel% + if dotnet_pid = 0 + { + break + } + } + " + +} + +#---------------------------------------------------------------- + +w_metadata dotnet20sp1 dlls \ + title="MS .NET 2.0 SP1" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + conflicts="dotnet20sp2" \ + file1="NetFx20SP1_x86.exe" \ + installed_file1="c:/windows/dotnet20sp1.installed.workaround" + +load_dotnet20sp1() +{ + w_call remove_mono + + # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0 + # Given that 3.x is deprecated, not worth looking into. + # See https://github.com/Winetricks/winetricks/pull/1271 + # https://bugs.winehq.org/show_bug.cgi?id=47484, et al + if w_wine_version_in 4.0, ; then + WINEDLLOVERRIDES="regsvcs.exe,mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + else + WINEDLLOVERRIDES="ngen.exe,regsvcs.exe,mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + fi + + if [ "${W_ARCH}" = "win32" ]; then + # https://www.microsoft.com/en-us/download/details.aspx?id=16614 + w_download https://download.microsoft.com/download/0/8/c/08c19fa4-4c4f-4ffb-9d6c-150906578c9e/NetFx20SP1_x86.exe c36c3a1d074de32d53f371c665243196a7608652a2fc6be9520312d5ce560871 + exe="NetFx20SP1_x86.exe" + + w_warn "Setting Windows version so installer works" + w_set_winver win2k + elif [ "${W_ARCH}" = "win64" ]; then + # https://www.microsoft.com/en-us/download/details.aspx?id=6041 + w_download https://download.microsoft.com/download/9/8/6/98610406-c2b7-45a4-bdc3-9db1b1c5f7e2/NetFx20SP1_x64.exe 1731e53de5f48baae0963677257660df1329549e81c48b4d7db7f7f3f2329aab + exe="NetFx20SP1_x64.exe" + + w_warn "Setting Windows version so installer works" + w_set_winver winxp + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try_ms_installer "${WINE}" "${exe}" ${W_OPT_UNATTENDED:+/q} + + if [ "${W_ARCH}" = "win32" ]; then + # We can't stop installing dotnet20sp1 in win2k mode until Wine supports + # reparse/junction points + # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 ) + # so for now just remove the bogus msvc*80.dll files it installs. + # See also https://bugs.winehq.org/show_bug.cgi?id=16577 + # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967 + rm -f "${W_SYSTEM32_DLLS}"/msvc?80.dll + + fi + + w_set_winver 'default' + + W_NGEN_CMD="w_try ${WINE} ${W_DRIVE_C}/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems" + + w_override_dlls native mscorwks + + # Installs the same file(name)s as dotnet35sp1, let users install dotnet35sp1 after dotnet20sp1 + w_try touch "${W_WINDIR_UNIX}/dotnet20sp1.installed.workaround" +} + +verify_dotnet20sp1() +{ + w_dotnet_verify dotnet20sp1 +} + +#---------------------------------------------------------------- + +w_metadata dotnet20sp2 dlls \ + title="MS .NET 2.0 SP2" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + conflicts="dotnet11" \ + file1="NetFx20SP2_x86.exe" \ + installed_file1="c:/windows/winsxs/manifests/x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.3053_x-ww_b80fa8ca.cat" + +load_dotnet20sp2() +{ + w_call remove_mono + + # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0 + # Given that 3.x is deprecated, not worth looking into. + # See https://github.com/Winetricks/winetricks/pull/1271 + # https://bugs.winehq.org/show_bug.cgi?id=47484, et al + if w_wine_version_in 4.0, ; then + WINEDLLOVERRIDES="regsvcs.exe,mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + else + WINEDLLOVERRIDES="ngen.exe,regsvcs.exe,mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + fi + w_warn "Setting Windows version so installer works" + w_set_winver winxp + + if [ "${W_ARCH}" = "win32" ]; then + # https://www.microsoft.com/en-us/download/details.aspx?id=1639 + w_download https://web.archive.org/web/20210329003118/http://download.microsoft.com/download/c/6/e/c6e88215-0178-4c6c-b5f3-158ff77b1f38/NetFx20SP2_x86.exe 6e3f363366e7d0219b7cb269625a75d410a5c80d763cc3d73cf20841084e851f + exe="NetFx20SP2_x86.exe" + elif [ "${W_ARCH}" = "win64" ]; then + # https://www.microsoft.com/en-us/download/details.aspx?id=1639 + w_download https://web.archive.org/web/20210328110521/http://download.microsoft.com/download/c/6/e/c6e88215-0178-4c6c-b5f3-158ff77b1f38/NetFx20SP2_x64.exe 430315c97c57ac158e7311bbdbb7130de3e88dcf5c450a25117c74403e558fbe + exe="NetFx20SP2_x64.exe" + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try_ms_installer "${WINE}" "${exe}" ${W_OPT_UNATTENDED:+ /q /c:"install.exe /q"} + + if [ "${W_ARCH}" = "win32" ]; then + # We can't stop installing dotnet20sp1 in win2k mode until Wine supports + # reparse/junction points + # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 ) + # so for now just remove the bogus msvc*80.dll files it installs. + # See also https://bugs.winehq.org/show_bug.cgi?id=16577 + # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967 + rm -f "${W_SYSTEM32_DLLS}"/msvc?80.dll + fi + + w_set_winver 'default' + w_override_dlls native mscorwks + + W_NGEN_CMD="w_try ${WINE} ${W_DRIVE_C}/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems" +} + +verify_dotnet20sp2() +{ + w_dotnet_verify dotnet20sp2 +} + +#---------------------------------------------------------------- + +w_metadata dotnet30 dlls \ + title="MS .NET 3.0" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + conflicts="dotnet11 dotnet30sp1 dotnet35 dotnet35sp1" \ + file1="dotnetfx3.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v3.0/Microsoft .NET Framework 3.0/logo.bmp" + +load_dotnet30() +{ + # I can't find a 64-bit installer anywhere + w_package_unsupported_win64 + + # Originally at https://msdn.microsoft.com/en-us/netframework/bb264589.aspx + # No longer on microsoft.com, and archive.org is unreliable. Choose amongst the oldest/most reliable looking from + # http://www.filewatcher.com/m/dotnetfx3.exe.52770576-0.html + # (and verify sha256sum, of course ;)) + # 2017/04/20: http://descargas.udenar.edu.co/Framework.net/dotnetfx3.exe + # 2019/08/18: ftp://support.danbit.dk/I/IPP15-C2D/Net%20Framework%203.0/dotnetfx3.exe + # 2020/04/12: couldn't find a working mirror, so back to archive.org for now: + w_download https://web.archive.org/web/20061130220825/http://download.microsoft.com/download/3/F/0/3F0A922C-F239-4B9B-9CB0-DF53621C57D9/dotnetfx3.exe 6cf8921e00f52bbd888aa7a520a7bac47e818e2a850bcc44494c64d6cbfafdac + + w_call remove_mono + + if test -f /proc/sys/kernel/yama/ptrace_scope; then + case $(cat /proc/sys/kernel/yama/ptrace_scope) in + 0) ;; + *) w_warn "If install fails, set /proc/sys/kernel/yama/ptrace_scope to 0. See https://bugs.winehq.org/show_bug.cgi?id=30410" ;; + esac + fi + + case "${W_PLATFORM}" in + windows_cmd) + osver=$(cmd /c ver) + case "${osver}" in + *Version?6*) w_die "Vista and up bundle .NET 3.0, so you can't install it like this" ;; + esac + ;; + esac + + # AF's workaround to avoid long pause + LANGPACKS_BASE_PATH="${W_WINDIR_UNIX}/SYSMSICache/Framework/v3.0" + test -d "${LANGPACKS_BASE_PATH}" || mkdir -p "${LANGPACKS_BASE_PATH}" + # shellcheck disable=SC1010 + for lang in ar cs da de el es fi fr he it jp ko nb nl pl pt-BR pt-PT ru sv tr zh-CHS zh-CHT; do + ln -sf "${W_SYSTEM32_DLLS}/spupdsvc.exe" "${LANGPACKS_BASE_PATH}/dotnetfx3langpack${lang}.exe" + done + + w_set_winver winxp + + # Delete FontCache 3.0 service, it's in Wine for Mono, breaks native .NET + # OK if this fails, that just means you have an older Wine. + "${WINE}" sc delete "FontCache3.0.0.0" + + # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0 + # Given that 3.x is deprecated, not worth looking into. + # See https://github.com/Winetricks/winetricks/pull/1271 + # https://bugs.winehq.org/show_bug.cgi?id=47484, et al + if w_wine_version_in 4.0, ; then + WINEDLLOVERRIDES="mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + else + WINEDLLOVERRIDES="ngen.exe,mscorsvw.exe=b;${WINEDLLOVERRIDES}" + export WINEDLLOVERRIDES + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_warn "Installing .NET 3.0 runtime silently, as otherwise it gets hidden behind taskbar. Installation usually takes about 3 minutes." + w_try "${WINE}" "${file1}" /q /c:"install.exe /q" + + w_override_dlls native mscorwks + w_set_winver 'default' + + # Doesn't install any ngen.exe + # W_NGEN_CMD="" +} + +verify_dotnet30() +{ + w_dotnet_verify dotnet30 +} + +#---------------------------------------------------------------- + +w_metadata dotnet30sp1 dlls \ + title="MS .NET 3.0 SP1" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + conflicts="dotnet11 dotnet20sdk" \ + file1="NetFx30SP1_x86.exe" \ + installed_file1="c:/windows/dotnet30sp1.installed.workaround" + +load_dotnet30sp1() +{ + # I can't find a 64-bit installer anywhere + w_package_unsupported_win64 + + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=47436" 4.8 4.15 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=48277" 4.16 4.21 + + # And a third way, but only with mingw enabled in wine-4.12.1 through wine-4.14 + w_package_broken_mingw "https://bugs.winehq.org/show_bug.cgi?id=47484" 4.12.1 4.14 + + # crashes on install: + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49831" 5.17 6.0 + + # XpsFilt.dll doesn't get installed (not sure what version exactly causes it, bug 49831 muddies things): + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=50463" 5.17 6.0 + + # FIXME: URL? + w_download https://download.microsoft.com/download/8/F/E/8FEEE89D-9E4F-4BA3-993E-0FFEA8E21E1B/NetFx30SP1_x86.exe 3100df4d4db3965ead9520c887a534115cf6fc7ba100abde45226958b865695b + # Recipe from https://bugs.winehq.org/show_bug.cgi?id=25060#c10 + # 2020/10/19: w_download https://download.microsoft.com/download/2/5/2/2526f55d-32bc-410f-be18-164ba67ae07d/XPSEP%20XP%20and%20Server%202003%2032%20bit.msi 630c86a202c40cbcd430701977d4f1fefa6151624ef9a4870040dff45e547dea "XPSEP XP and Server 2003 32 bit.msi" + w_download https://web.archive.org/web/20200810211554if_/https://download.microsoft.com/download/2/5/2/2526f55d-32bc-410f-be18-164ba67ae07d/XPSEP%20XP%20and%20Server%202003%2032%20bit.msi 630c86a202c40cbcd430701977d4f1fefa6151624ef9a4870040dff45e547dea "XPSEP XP and Server 2003 32 bit.msi" + + w_call remove_mono + w_call dotnet30 + w_wineserver -w + w_call dotnet20sp1 + w_wineserver -w + + if w_workaround_wine_bug 47436 "Installing native prntvpt" 4.11,4.15 ;then + w_call prntvpt + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + "${WINE}" reg add "HKLM\\Software\\Microsoft\\Net Framework Setup\\NDP\\v3.0" /v Version /t REG_SZ /d "3.0" /f + "${WINE}" reg add "HKLM\\Software\\Microsoft-\\Net Framework Setup\\NDP\\v3.0" /v SP /t REG_DWORD /d 0001 /f + + w_set_winver winxp + + "${WINE}" sc delete FontCache3.0.0.0 + + w_try_ms_installer "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/q} + + w_override_dlls native mscorwks + w_set_winver 'default' + + # Doesn't install any ngen.exe + # W_NGEN_CMD="" + + # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet30sp1.installed.workaround" +} + +verify_dotnet30sp1() +{ + w_dotnet_verify dotnet30sp1 +} + +#---------------------------------------------------------------- + +w_metadata dotnet35 dlls \ + title="MS .NET 3.5" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + conflicts="dotnet11 dotnet20sdk dotnet20sp2 dotnet30" \ + file1="dotnetfx35.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v3.5/MSBuild.exe" + +load_dotnet35() +{ + # actually, fixed in 6.0-rc2, but w_package_broken() doesn't handle rc versions well + w_package_broken_win64 https://bugs.winehq.org/show_bug.cgi?id=49690 5.12 6.0 + + w_verify_cabextract_available + + # https://www.microsoft.com/en-us/download/details.aspx?id=21 + w_download https://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe 3e3a4104bad9a0c270ed5cbe8abb986de9afaf0281a98998bdbdc8eaab85c3b6 + + w_call remove_mono + + w_set_winver winxp + + w_override_dlls native mscoree mscorwks + w_wineserver -w + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try_ms_installer "${WINE}" "${file1}" /lang:ENU ${W_OPT_UNATTENDED:+/q} + + w_set_winver 'default' + + # Doesn't install any ngen.exe + # W_NGEN_CMD="" +} + +verify_dotnet35() +{ + w_dotnet_verify dotnet35 +} + +#---------------------------------------------------------------- + +w_metadata dotnet35sp1 dlls \ + title="MS .NET 3.5 SP1" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + conflicts="dotnet11 dotnet20sp1" \ + file1="dotnetfx35.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v3.5/msbuild.exe.config" + +load_dotnet35sp1() +{ + w_package_broken_win64 https://bugs.winehq.org/show_bug.cgi?id=49690 5.12 6.0 + + w_verify_cabextract_available + + # Official version. See https://dotnet.microsoft.com/en-us/download/dotnet-framework/net35-sp1 + w_download https://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe 0582515bde321e072f8673e829e175ed2e7a53e803127c50253af76528e66bc1 + + w_call remove_mono + + w_set_winver winxp + + w_override_dlls native mscoree mscorwks + w_wineserver -w + + # The installer is braindead and picks the lowest drive letter that's writable + # winetricks_set_wineprefix(), which is called by w_do_call() sets up this symlink so that wine + # can make a windows path to the cache (which is removed during cleanup). + # To avoid that, we sylmink the executable directly and remove the symlink + # and then the installer leaves the cruft on C:\ instead (assuming there's no other drives mounted). + # + # If the user has other drives mounted (or maybe if Z:\ is writable), + # then they have to clean up the mess themselves, sorry. + w_try rm "${WINETRICKS_CACHE_SYMLINK}" + w_try_cd "${W_TMP}" + w_try ln -s "${W_CACHE}/${W_PACKAGE}/${file1}" . + w_try_ms_installer "${WINE}" dotnetfx35.exe /lang:ENU ${W_OPT_UNATTENDED:+/q} + w_try rm dotnetfx35.exe + + w_set_winver 'default' + + # Doesn't install any ngen.exe + # W_NGEN_CMD="" +} + +verify_dotnet35sp1() +{ + w_dotnet_verify dotnet35sp1 +} + +#---------------------------------------------------------------- + +w_metadata dotnet40 dlls \ + title="MS .NET 4.0" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + conflicts="dotnet20sdk" \ + file1="dotNetFx40_Full_x86_x64.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/ngen.exe" + +load_dotnet40() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + case "${W_PLATFORM}" in + windows_cmd) ;; + *) w_warn "dotnet40 does not yet fully work or install on wine. Caveat emptor." ;; + esac + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net40 + w_download https://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe 65e064258f2e418816b304f646ff9e87af101e4c9552ab064bb74d281c38659f + + w_call remove_mono + + w_call winxp + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" dotNetFx40_Full_x86_x64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + + w_override_dlls native mscoree + + "${WINE}" reg add "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full" /v Install /t REG_DWORD /d 0001 /f + "${WINE}" reg add "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full" /v Version /t REG_SZ /d "4.0.30319" /f + + W_NGEN_CMD="${WINE} ${WINEPREFIX}/drive_c/windows/Microsoft.NET/Framework/v4.0.30319/ngen.exe executequeueditems" + + # Avoid a popup on WINEPREFIX updates, see https://bugs.winehq.org/show_bug.cgi?id=41727#c5 + "${WINE}" reg add "HKLM\\Software\\Microsoft\\.NETFramework" /v OnlyUseLatestCLR /t REG_DWORD /d 0001 /f + + w_set_winver 'default' +} + +verify_dotnet40() +{ + w_dotnet_verify dotnet40 +} + +#---------------------------------------------------------------- + +w_metadata dotnet40_kb2468871 dlls \ + title="MS .NET 4.0 KB2468871" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + conflicts="dotnet20sdk" \ + file1="NDP40-KB2468871-v2-x86.exe" + +load_dotnet40_kb2468871() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_call dotnet40 + + # Install KB2468871: + if [ "${W_ARCH}" = "win32" ]; then + w_download https://download.microsoft.com/download/2/B/F/2BF4D7D1-E781-4EE0-9E4F-FDD44A2F8934/NDP40-KB2468871-v2-x86.exe 8822672fc864544e0766c80b635973bd9459d719b1af75f51483ff36cfb26f03 + w_try_7z "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/NDP40-KB2468871-v2-x86.exe" NDP40-KB2468871.msp + elif [ "${W_ARCH}" = "win64" ]; then + w_download https://download.microsoft.com/download/2/B/F/2BF4D7D1-E781-4EE0-9E4F-FDD44A2F8934/NDP40-KB2468871-v2-x64.exe b1b53c3953377b111fe394dd57592d342cfc8a3261a5575253b211c1c2e48ff8 + w_try_7z "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/NDP40-KB2468871-v2-x64.exe" NDP40-KB2468871.msp + fi + + w_try_cd "${W_TMP}" + w_try "${WINE}" msiexec /p NDP40-KB2468871.msp + + w_set_winver 'default' +} + +verify_dotnet40_kb2468871() +{ + w_dotnet_verify dotnet40 +} + +#---------------------------------------------------------------- + +w_metadata dotnet45 dlls \ + title="MS .NET 4.5" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + conflicts="dotnet20sdk" \ + file1="dotnetfx45_full_x86_x64.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Windows.ApplicationServer.Applications.45.man" + +load_dotnet45() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49897" 5.18 6.6 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + w_verify_cabextract_available + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net45 + w_download https://download.microsoft.com/download/b/a/4/ba4a7e71-2906-4b2d-a0e1-80cf16844f5f/dotnetfx45_full_x86_x64.exe a04d40e217b97326d46117d961ec4eda455e087b90637cb33dd6cc4a2c228d83 + + w_call remove_mono + + # See https://appdb.winehq.org/objectManager.php?sClass=version&iId=25478 for Focht's recipe + + # Seems unneeded in wine-2.0 + # w_call dotnet35 + w_call dotnet40 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" dotnetfx45_full_x86_x64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + + w_override_dlls native mscoree + + # Avoid a popup on WINEPREFIX updates, see https://bugs.winehq.org/show_bug.cgi?id=41727#c5 + "${WINE}" reg add "HKLM\\Software\\Microsoft\\.NETFramework" /v OnlyUseLatestCLR /t REG_DWORD /d 0001 /f + + w_warn "Setting Windows version to 2003, otherwise applications using .NET 4.5 will subtly fail" + w_set_winver win2k3 +} + +verify_dotnet45() +{ + w_dotnet_verify dotnet45 +} + +#---------------------------------------------------------------- + +w_metadata dotnet452 dlls \ + title="MS .NET 4.5.2" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + conflicts="dotnet20sdk dotnet46 dotnet462" \ + file1="NDP452-KB2901907-x86-x64-AllOS-ENU.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Windows.ApplicationServer.Applications.45.man" + +load_dotnet452() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49897" 5.18 6.6 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + w_verify_cabextract_available + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net452 + w_download https://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe 6c2c589132e830a185c5f40f82042bee3022e721a216680bd9b3995ba86f3781 + + w_call remove_mono + + # See https://appdb.winehq.org/objectManager.php?sClass=version&iId=25478 for Focht's recipe + + # Seems unneeded in wine-2.0 + # w_call dotnet35 + w_call dotnet40 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" NDP452-KB2901907-x86-x64-AllOS-ENU.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + + w_override_dlls native mscoree + + w_warn "Setting Windows version to 2003, otherwise applications using .NET 4.5 will subtly fail" + w_set_winver win2k3 +} + +verify_dotnet452() +{ + w_dotnet_verify dotnet452 +} + +#---------------------------------------------------------------- + +w_metadata dotnet46 dlls \ + title="MS .NET 4.6" \ + publisher="Microsoft" \ + year="2015" \ + media="download" \ + file1="NDP46-KB3045557-x86-x64-AllOS-ENU.exe" \ + conflicts="dotnet20sdk" \ + installed_file1="c:/windows/Migration/WTR/netfx45_upgradecleanup.inf" + +load_dotnet46() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net46 + w_download https://download.microsoft.com/download/6/F/9/6F9673B1-87D1-46C4-BF04-95F24C3EB9DA/enu_netfx/NDP46-KB3045557-x86-x64-AllOS-ENU_exe/NDP46-KB3045557-x86-x64-AllOS-ENU.exe b21d33135e67e3486b154b11f7961d8e1cfd7a603267fb60febb4a6feab5cf87 + + w_call remove_mono + + w_call dotnet45 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"} + + w_override_dlls native mscoree +} + +verify_dotnet46() +{ + w_dotnet_verify dotnet46 +} + +#---------------------------------------------------------------- + +w_metadata dotnet461 dlls \ + title="MS .NET 4.6.1" \ + publisher="Microsoft" \ + year="2015" \ + media="download" \ + file1="NDP461-KB3102436-x86-x64-AllOS-ENU.exe" \ + conflicts="dotnet20sdk" \ + installed_file1="c:/windows/dotnet461.installed.workaround" + +load_dotnet461() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net461 + w_download https://download.microsoft.com/download/E/4/1/E4173890-A24A-4936-9FC9-AF930FE3FA40/NDP461-KB3102436-x86-x64-AllOS-ENU.exe beaa901e07347d056efe04e8961d5546c7518fab9246892178505a7ba631c301 + + w_call remove_mono + + w_call dotnet46 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" "${file1}" /sfxlang:1027 ${W_OPT_UNATTENDED:+/q /norestart} + + w_override_dlls native mscoree + + # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet461.installed.workaround" +} + +verify_dotnet461() +{ + w_dotnet_verify dotnet461 +} + +#---------------------------------------------------------------- + +w_metadata dotnet462 dlls \ + title="MS .NET 4.6.2" \ + publisher="Microsoft" \ + year="2016" \ + media="download" \ + conflicts="dotnet20sdk" \ + installed_file1="c:/windows/dotnet462.installed.workaround" + +load_dotnet462() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net462 + w_download https://download.visualstudio.microsoft.com/download/pr/8e396c75-4d0d-41d3-aea8-848babc2736a/80b431456d8866ebe053eb8b81a168b3/NDP462-KB3151800-x86-x64-AllOS-ENU.exe b4cbb4bc9a3983ec3be9f80447e0d619d15256a9ce66ff414ae6e3856705e237 + file_package="NDP462-KB3151800-x86-x64-AllOS-ENU.exe" + + w_call remove_mono + + w_call dotnet461 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" "${file_package}" ${W_OPT_UNATTENDED:+/sfxlang:1027 /q /norestart} + + w_override_dlls native mscoree + + # Unfortunately, dotnet462 install the same files that dotnet461 does, but with different checksums + # The only unique files are temporary ones. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet462.installed.workaround" +} + +verify_dotnet462() +{ + w_dotnet_verify dotnet462 +} + +#---------------------------------------------------------------- + +w_metadata dotnet471 dlls \ + title="MS .NET 4.7.1" \ + publisher="Microsoft" \ + year="2017" \ + media="download" \ + file1="NDP471-KB4033342-x86-x64-AllOS-ENU.exe" \ + conflicts="dotnet20sdk dotnet30sp1" \ + installed_file1="c:/windows/dotnet471.installed.workaround" + +load_dotnet471() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net471 + w_download https://download.visualstudio.microsoft.com/download/pr/4312fa21-59b0-4451-9482-a1376f7f3ba4/9947fce13c11105b48cba170494e787f/NDP471-KB4033342-x86-x64-AllOS-ENU.exe df6e700d37ff416e2e1d8463dededdf76522ceaf5bb4cc3f197a7f2b9eccc4ad + + w_call remove_mono + + w_call dotnet462 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/sfxlang:1027 /q /norestart} + + w_override_dlls native mscoree + + # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet471.installed.workaround" +} + +verify_dotnet471() +{ + w_dotnet_verify dotnet471 +} + +#---------------------------------------------------------------- + +w_metadata dotnet472 dlls \ + title="MS .NET 4.7.2" \ + publisher="Microsoft" \ + year="2018" \ + media="download" \ + conflicts="dotnet20sdk" \ + installed_file1="c:/windows/dotnet472.installed.workaround" + +load_dotnet472() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52722" 7.5 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net472 + w_download https://download.visualstudio.microsoft.com/download/pr/1f5af042-d0e4-4002-9c59-9ba66bcf15f6/089f837de42708daacaae7c04b7494db/NDP472-KB4054530-x86-x64-AllOS-ENU.exe 5cb624b97f9fd6d3895644c52231c9471cd88aacb57d6e198d3024a1839139f6 + + w_call remove_mono + + w_call dotnet462 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" NDP472-KB4054530-x86-x64-AllOS-ENU.exe ${W_OPT_UNATTENDED:+/sfxlang:1027 /q /norestart} + + w_override_dlls native mscoree + + # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet472.installed.workaround" +} + +verify_dotnet472() +{ + w_dotnet_verify dotnet472 +} + +#---------------------------------------------------------------- + +w_metadata dotnet48 dlls \ + title="MS .NET 4.8" \ + publisher="Microsoft" \ + year="2019" \ + media="download" \ + file1="ndp48-x86-x64-allos-enu.exe" \ + conflicts="dotnet20sdk" \ + installed_file1="c:/windows/dotnet48.installed.workaround" + +load_dotnet48() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49532" 5.12 5.18 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49897" 5.18 6.6 + + w_package_warn_win64 + + # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net48 + w_download https://download.visualstudio.microsoft.com/download/pr/7afca223-55d2-470a-8edc-6a1739ae3252/abd170b4b0ec15ad0222a809b761a036/ndp48-x86-x64-allos-enu.exe 95889d6de3f2070c07790ad6cf2000d33d9a1bdfc6a381725ab82ab1c314fd53 + + w_call remove_mono + + w_call dotnet40 + w_set_winver win7 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + WINEDLLOVERRIDES=fusion=b w_try_ms_installer "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/sfxlang:1027 /q /norestart} + + w_override_dlls native mscoree + + # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed + w_try touch "${W_WINDIR_UNIX}/dotnet48.installed.workaround" +} + +verify_dotnet48() +{ + w_dotnet_verify dotnet48 +} + +#---------------------------------------------------------------- + +w_metadata dotnetcore2 dlls \ + title="MS .NET Core Runtime 2.1 LTS" \ + publisher="Microsoft" \ + year="2020" \ + media="download" \ + file1="dotnet-runtime-2.1.17-win-x86.exe" \ + installed_file1="${W_PROGRAMS_WIN}/dotnet/dotnet.exe" + +load_dotnetcore2() +{ + # Official version, see https://dotnet.microsoft.com/download/dotnet-core/2.1 + w_download https://download.visualstudio.microsoft.com/download/pr/73a0ea97-57d6-4263-ac36-ea3a9b373bcf/cd5f7e08e749c1d3468cdae89e4518de/dotnet-runtime-2.1.17-win-x86.exe 706a7f0ad998c3c1b321e89e4bcd6304bef31c95c83eda119e8d4adccccbc915 + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/quiet} + + if [ "${W_ARCH}" = "win64" ]; then + # Also install the 64-bit version + w_download https://download.visualstudio.microsoft.com/download/pr/cd223083-8c0e-4963-9fcd-fcf01a55e56c/15500e764899442ed6e014687caa34e9/dotnet-runtime-2.1.17-win-x64.exe 5a065ae6f9e031399cb7084c6315ce977342dec069cd6386caed1c5b69d49260 + w_try "${WINE}" "dotnet-runtime-2.1.17-win-x64.exe" ${W_OPT_UNATTENDED:+/quiet} + fi +} + +#---------------------------------------------------------------- + +w_metadata dotnetcore3 dlls \ + title="MS .NET Core Runtime 3.1 LTS" \ + publisher="Microsoft" \ + year="2020" \ + media="download" \ + file1="dotnet-runtime-3.1.10-win-x86.exe" \ + installed_file1="${W_PROGRAMS_WIN}/dotnet/dotnet.exe" + +load_dotnetcore3() +{ + # Official version, see https://dotnet.microsoft.com/download/dotnet-core/3.1 + w_download https://download.visualstudio.microsoft.com/download/pr/abb3fb5d-4e82-4ca8-bc03-ac13e988e608/b34036773a72b30c5dc5520ee6a2768f/dotnet-runtime-3.1.10-win-x86.exe 6ae8d2fb7a23ac4770fa815bc27614b2db0e89f5c078eb2744771bf5541cdba3 + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/quiet} + + if [ "${W_ARCH}" = "win64" ]; then + # Also install the 64-bit version + w_download https://download.visualstudio.microsoft.com/download/pr/9845b4b0-fb52-48b6-83cf-4c431558c29b/41025de7a76639eeff102410e7015214/dotnet-runtime-3.1.10-win-x64.exe 78ef39c732ec35e79a0c1a10010ea797733df2811d774709b0fde23dce02efdf + w_try "${WINE}" "dotnet-runtime-3.1.10-win-x64.exe" ${W_OPT_UNATTENDED:+/quiet} + fi +} + +#---------------------------------------------------------------- + +w_metadata dotnetcoredesktop3 dlls \ + title="MS .NET Core Desktop Runtime 3.1 LTS" \ + publisher="Microsoft" \ + year="2020" \ + media="download" \ + file1="windowsdesktop-runtime-3.1.10-win-x86.exe" \ + installed_file1="${W_PROGRAMS_WIN}/dotnet/dotnet.exe" + +load_dotnetcoredesktop3() +{ + # Official version, see https://dotnet.microsoft.com/download/dotnet-core/3.1 + w_download https://download.visualstudio.microsoft.com/download/pr/865d0be5-16e2-4b3d-a990-f4c45acd280c/ec867d0a4793c0b180bae85bc3a4f329/windowsdesktop-runtime-3.1.10-win-x86.exe 4da245d9048642ed3f25c04e8fa0156e1d2966b4d257c12a9a3d3a0c929102aa + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/quiet} + + if [ "${W_ARCH}" = "win64" ]; then + # Also install the 64-bit version + w_download https://download.visualstudio.microsoft.com/download/pr/513acf37-8da2-497d-bdaa-84d6e33c1fee/eb7b010350df712c752f4ec4b615f89d/windowsdesktop-runtime-3.1.10-win-x64.exe 32286b9a35d9a53d28807ef761f3dba43b71e602efd2b794f843fcf5ea8438a9 + w_try "${WINE}" "windowsdesktop-runtime-3.1.10-win-x64.exe" ${W_OPT_UNATTENDED:+/quiet} + fi +} + +#---------------------------------------------------------------- + +w_metadata dotnet_verifier dlls \ + title="MS .NET Verifier" \ + publisher="Microsoft" \ + year="2016" \ + media="download" \ + file1="netfx_setupverifier_new.zip" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/netfx_setupverifier.exe" + +load_dotnet_verifier() +{ + # https://blogs.msdn.microsoft.com/astebner/2008/10/13/net-framework-setup-verification-tool-users-guide/ + # 2016/10/26: sha256sum 1daf4b1b27669b65f613e17814da3c8342d3bfa9520a65a880c58d6a2a6e32b5, adds .NET Framework 4.6.{1,2} support + # 2017/06/12: sha256sum 310a0341fbe68f5b8601f2d8deef5d05ca6bce50df03912df391bc843794ef60, adds .NET Framework 4.7 support + # 2018/06/03: sha256sum 13fd683fd604f9de09a9e649df303100b81e6797f868024d55e5c2f3c14aa9a6, adds .NET Framework 4.7.{1,2} support + + w_download https://web.archive.org/web/20180802234935/https://msdnshared.blob.core.windows.net/media/2018/05/netfx_setupverifier_new.zip 13fd683fd604f9de09a9e649df303100b81e6797f868024d55e5c2f3c14aa9a6 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try_unzip "${W_SYSTEM32_DLLS}" netfx_setupverifier_new.zip netfx_setupverifier.exe + + w_warn "You can run the .NET Verifier with \"${WINE} netfx_setupverifier.exe\"" +} + +#---------------------------------------------------------------- + +w_metadata dx8vb dlls \ + title="MS dx8vb.dll from DirectX 8.1 runtime" \ + publisher="Microsoft" \ + year="2001" \ + media="download" \ + file1="DX81NTger.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dx8vb.dll" + +load_dx8vb() +{ + # https://www.microsoft.com/de-de/download/details.aspx?id=10968 + w_download https://download.microsoft.com/download/win2000pro/dx/8.1/NT5/DE/DX81NTger.exe 31513966a29dc100165072891d21b5c5e0dd2632abf3409a843cefb3a9886f13 + + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -F dx8vb.dll "${W_CACHE}/${W_PACKAGE}"/DX81NTger.exe + + w_override_dlls native dx8vb +} + +#---------------------------------------------------------------- + +w_metadata dxdiagn dlls \ + title="DirectX Diagnostic Library" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + conflicts="dxdiagn_feb2010" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dxdiagn.dll" + +load_dxdiagn() +{ + helper_win7sp1 x86_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_25cb021dbc0611db/dxdiagn.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_25cb021dbc0611db/dxdiagn.dll" "${W_SYSTEM32_DLLS}/dxdiagn.dll" + w_override_dlls native,builtin dxdiagn + w_try_regsvr dxdiagn.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_81e99da174638311/dxdiagn.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_81e99da174638311/dxdiagn.dll" "${W_SYSTEM64_DLLS}/dxdiagn.dll" + w_try_regsvr64 dxdiagn.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata dxdiagn_feb2010 dlls \ + title="DirectX Diagnostic Library (February 2010)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + conflicts="dxdiagn" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dxdiagn.dll" + +load_dxdiagn_feb2010() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dxdiagn.dll' "${W_TMP}/dxnt.cab" + w_override_dlls native dxdiagn + w_try_regsvr dxdiagn.dll +} + +#---------------------------------------------------------------- + +w_metadata dsound dlls \ + title="MS DirectSound from DirectX user redistributable" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dsound.dll" + +load_dsound() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'dsound.dll' "${W_TMP}/dxnt.cab" + + # Don't try to register native dsound; it doesn't export DllRegisterServer(). + #w_try_regsvr32 dsound.dll + w_override_dlls native dsound +} + +#---------------------------------------------------------------- + +w_metadata esent dlls \ + title="MS Extensible Storage Engine" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/esent.dll" + +load_esent() +{ + helper_win7sp1 x86_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_f3ebb0cc8a4dd814/esent.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_f3ebb0cc8a4dd814/esent.dll" "${W_SYSTEM32_DLLS}/esent.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_500a4c5042ab494a/esent.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_500a4c5042ab494a/esent.dll" "${W_SYSTEM64_DLLS}/esent.dll" + fi + + w_override_dlls native,builtin esent +} + +#---------------------------------------------------------------- + +# $1 - faudio archive name (required) +helper_faudio() +{ + faudio_archive="$1" + faudio_version="$(basename "${faudio_archive}" .tar.xz)" + + w_try_cd "${W_TMP}" + w_try tar -Jxf "${W_CACHE}/${W_PACKAGE}/${faudio_archive}" + + if [ -d "${faudio_version}/x32" ]; then + w_info "Installing 32-bit binaries since present; upstreams says they may be broken" + + # They ship an installation script, but it's bash (and we have all needed functionality already) + # Unless they add something more complex, this should suffice: + for dll in "${faudio_version}/x32/"*.dll; do + shortdll="$(basename "${dll}" .dll)" + w_try_cp_dll "${dll}" "${W_SYSTEM32_DLLS}" + w_override_dlls native "${shortdll}" + done + fi + + if [ "${W_ARCH}" = "win64" ]; then + for dll in "${faudio_version}/x64/"*.dll; do + # Note: 'libgcc_s_sjlj-1.dll' is not included in the 64-bit build + shortdll="$(basename "${dll}" .dll)" + w_try_cp_dll "${dll}" "${W_SYSTEM64_DLLS}" + w_override_dlls native "${shortdll}" + done + fi +} + +#---------------------------------------------------------------- + +w_metadata faudio1901 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.01)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.01.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1901() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.01/faudio-19.01.tar.xz f3439090ba36061ee47ebda93e409ae4b2d8886c780c86a197c66ff08b9b573f + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio1902 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.02)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.02.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1902() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.02/faudio-19.02.tar.xz 849fec35482748a2b441d8dd7e9a171c7c5c2207d1037c7ffd0265e65f2a4b2b + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio1903 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.03)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.03.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1903() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.03/faudio-19.03.tar.xz d5c62437fd5b185e82f464f6a82334af5d666cb506aba218358ea7a3697fdf63 + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio1904 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.04)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.04.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1904() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.04/faudio-19.04.tar.xz c364db1a18bfb6f6c0f375c641672ca40140b8e5db69dc2c8c9b41d79d0fc56f + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio1905 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.05)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.05.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1905() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.05/faudio-19.05.tar.xz 94b44c43c0b2260f8061dd699292c8d58ce56fae330a53314417804df4f5f723 + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio1906 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.06)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.06.tar.xz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/FAudio.dll" + +load_faudio1906() +{ + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.06/faudio-19.06.tar.xz 87639e30f9e913685829e05b925809598409e54c4c51e3d74b977cedd658aaf3 + helper_faudio "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata faudio190607 dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.06.07)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + file1="faudio-19.06.07.tar.xz" \ + installed_file1="${W_SYSTEM64_DLLS_WIN64}/FAudio.dll" + +load_faudio190607() +{ + # Starting in 19.06.07; before that ships them, but they're supposedly broken + w_package_unsupported_win32 + + w_download https://github.com/Kron4ek/FAudio-Builds/releases/download/19.06.07/faudio-19.06.07.tar.xz e17e3a9dadeb1017dc369fe0d46c3d1945ebceadb7ad2f94a3a1448435ab3f6c + helper_faudio "${file1}" +} +#---------------------------------------------------------------- + +w_metadata faudio dlls \ + title="FAudio (xaudio reimplementation, with xna support) builds for win32 (latest)" \ + publisher="Kron4ek" \ + year="2019" \ + media="download" \ + installed_file1="${W_SYSTEM64_DLLS_WIN64}/FAudio.dll" + +load_faudio() +{ + # Starting in 19.06.07; before that ships them, but they're supposedly broken + w_package_unsupported_win32 + + w_download_to "${W_TMP_EARLY}" "https://raw.githubusercontent.com/Kron4ek/FAudio-Builds/master/LATEST" + faudio_version="$(cat "${W_TMP_EARLY}/LATEST")" + w_linkcheck_ignore=1 w_download "https://github.com/Kron4ek/FAudio-Builds/releases/download/${faudio_version}/faudio-${faudio_version}.tar.xz" + helper_faudio "faudio-${faudio_version}.tar.xz" +} + +#---------------------------------------------------------------- + +w_metadata filever dlls \ + title="Microsoft's filever, for dumping file version info" \ + publisher="Microsoft" \ + year="20??" \ + media="download" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/filever.exe" + +load_filever() +{ + helper_winxpsp2_support_tools filever.exe + w_try_cp_dll "${W_TMP}/filever.exe" "${W_SYSTEM32_DLLS}/filever.exe" +} + +#---------------------------------------------------------------- + +# $1 - gallium nine standalone archive name (required) +helper_galliumnine() +{ + _W_galliumnine_archive="${1}" + _W_galliumnine_tmp="${W_TMP}/galliumnine" + + w_try rm -rf "${_W_galliumnine_tmp}" + w_try mkdir -p "${_W_galliumnine_tmp}" + w_try tar -C "${_W_galliumnine_tmp}" --strip-components=1 -zxf "${W_CACHE}/${W_PACKAGE}/${_W_galliumnine_archive}" + w_try mv "${_W_galliumnine_tmp}/lib32/d3d9-nine.dll.so" "${W_SYSTEM32_DLLS}/d3d9-nine.dll" + w_try mv "${_W_galliumnine_tmp}/bin32/ninewinecfg.exe.so" "${W_SYSTEM32_DLLS}/ninewinecfg.exe" + if test "${W_ARCH}" = "win64"; then + w_try mv "${_W_galliumnine_tmp}/lib64/d3d9-nine.dll.so" "${W_SYSTEM64_DLLS}/d3d9-nine.dll" + w_try mv "${_W_galliumnine_tmp}/bin64/ninewinecfg.exe.so" "${W_SYSTEM64_DLLS}/ninewinecfg.exe" + fi + w_try rm -rf "${_W_galliumnine_tmp}" + # use ninewinecfg to enable gallium nine + WINEDEBUG=-all w_try "${WINE_MULTI}" ninewinecfg -e + + unset _W_galliumnine_tmp _W_galliumnine_archive +} + +w_metadata galliumnine02 dlls \ + title="Gallium Nine Standalone (v0.2)" \ + publisher="Gallium Nine Team" \ + year="2019" \ + media="download" \ + file1="gallium-nine-standalone-v0.2.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine02() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49676" 5.13 + w_package_broken "https://github.com/iXit/wine-nine-standalone/issues/83" 5.14 + + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.2/gallium-nine-standalone-v0.2.tar.gz" 6818fe890e343aa32d3d53179bfeb63df40977797bd7b6263e85e2bb57559313 + helper_galliumnine "${file1}" +} + +w_metadata galliumnine03 dlls \ + title="Gallium Nine Standalone (v0.3)" \ + publisher="Gallium Nine Team" \ + year="2019" \ + media="download" \ + file1="gallium-nine-standalone-v0.3.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine03() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49676" 5.13 + w_package_broken "https://github.com/iXit/wine-nine-standalone/issues/83" 5.14 + + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.3/gallium-nine-standalone-v0.3.tar.gz" 8bb564073ab2198e5b9b870f7b8cac8d9bc20bc6accf66c4c798e4b450ec0c91 + helper_galliumnine "${file1}" +} + +w_metadata galliumnine04 dlls \ + title="Gallium Nine Standalone (v0.4)" \ + publisher="Gallium Nine Team" \ + year="2019" \ + media="download" \ + file1="gallium-nine-standalone-v0.4.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine04() +{ + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=49676" 5.13 + w_package_broken "https://github.com/iXit/wine-nine-standalone/issues/83" 5.14 + + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.4/gallium-nine-standalone-v0.4.tar.gz" 4423c32d46419830c8e68fea86d28e740f17f182c365250c379b5493176e19ab + helper_galliumnine "${file1}" +} + +w_metadata galliumnine05 dlls \ + title="Gallium Nine Standalone (v0.5)" \ + publisher="Gallium Nine Team" \ + year="2019" \ + media="download" \ + file1="gallium-nine-standalone-v0.5.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine05() +{ + w_package_broken "https://github.com/iXit/wine-nine-standalone/issues/83" 5.14 + + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.5/gallium-nine-standalone-v0.5.tar.gz" c46e06b13a3ba0adee75b27a8b54e9d772f83ed29dee5e203364460771fb1bcd + helper_galliumnine "${file1}" +} + +w_metadata galliumnine06 dlls \ + title="Gallium Nine Standalone (v0.6)" \ + publisher="Gallium Nine Team" \ + year="2020" \ + media="download" \ + file1="gallium-nine-standalone-v0.6.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine06() +{ + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.6/gallium-nine-standalone-v0.6.tar.gz" 1a085b5175791414fdd513b5adb5682985917fef81e84f0116ef2b4d5295ad1c + helper_galliumnine "${file1}" +} + +w_metadata galliumnine07 dlls \ + title="Gallium Nine Standalone (v0.7)" \ + publisher="Gallium Nine Team" \ + year="2020" \ + media="download" \ + file1="gallium-nine-standalone-v0.7.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine07() +{ + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.7/gallium-nine-standalone-v0.7.tar.gz" e0b3005280119732d2ca48a5aa5aad27eaf08e6e1dd5598652744a04554a9475 + helper_galliumnine "${file1}" +} + +w_metadata galliumnine08 dlls \ + title="Gallium Nine Standalone (v0.8)" \ + publisher="Gallium Nine Team" \ + year="2021" \ + media="download" \ + file1="gallium-nine-standalone-v0.8.tar.gz" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine08() +{ + w_download "https://github.com/iXit/wine-nine-standalone/releases/download/v0.8/gallium-nine-standalone-v0.8.tar.gz" 8d73dcf78e4b5edf7a3aea8c339459b5138acd1c957c91c5c06432cb2fc51893 + helper_galliumnine "${file1}" +} + +w_metadata galliumnine dlls \ + title="Gallium Nine Standalone (latest)" \ + publisher="Gallium Nine Team" \ + year="2019" \ + media="download" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/d3d9-nine.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/ninewinecfg.exe" \ + homepage="https://github.com/iXit/wine-nine-standalone" + +load_galliumnine() +{ + _W_galliumnine_version="$(w_get_github_latest_release iXit wine-nine-standalone)" + w_linkcheck_ignore=1 w_download "https://github.com/iXit/wine-nine-standalone/releases/download/${_W_galliumnine_version}/gallium-nine-standalone-${_W_galliumnine_version}.tar.gz" + helper_galliumnine "gallium-nine-standalone-${_W_galliumnine_version}.tar.gz" + unset _W_galliumnine_version +} + +#---------------------------------------------------------------- + +w_metadata gdiplus dlls \ + title="MS GDI+" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/gdiplus.dll" + +load_gdiplus() +{ + # gdiplus has changed in win7. See https://bugs.winehq.org/show_bug.cgi?id=32163#c3 + helper_win7sp1 x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80/gdiplus.dll + w_try_cp_dll "${W_TMP}/x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80/gdiplus.dll" "${W_SYSTEM32_DLLS}/gdiplus.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_2b24536c71ed437a/gdiplus.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_2b24536c71ed437a/gdiplus.dll" "${W_SYSTEM64_DLLS}/gdiplus.dll" + fi + + # For some reason, native, builtin isn't good enough...? + w_override_dlls native gdiplus +} + +#---------------------------------------------------------------- + +w_metadata gdiplus_winxp dlls \ + title="MS GDI+" \ + publisher="Microsoft" \ + year="2009" \ + media="manual_download" \ + file1="WindowsXP-KB975337-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/gdiplus.dll" + +load_gdiplus_winxp() +{ + # https://www.microsoft.com/en-us/download/details.aspx?id=5339 + w_download https://web.archive.org/web/20140615000000/http://download.microsoft.com/download/a/b/c/abc45517-97a0-4cee-a362-1957be2f24e1/WindowsXP-KB975337-x86-ENU.exe 699e76e9f100db3d50da8762c484a369df4698d4b84f7821d4df0e37ce68bcbe + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}/${file1}" /x:. /q + w_try_cp_dll "${W_CACHE}/${W_PACKAGE}/asms/10/msft/windows/gdiplus/gdiplus.dll" "${W_SYSTEM32_DLLS}/gdiplus.dll" + + # For some reason, native, builtin isn't good enough...? + w_override_dlls native gdiplus +} + +#---------------------------------------------------------------- + +w_metadata glidewrapper dlls \ + title="GlideWrapper" \ + publisher="Rolf Neuberger" \ + year="2005" \ + media="download" \ + file1="GlideWrapper084c.exe" \ + installed_file1="c:/windows/glide3x.dll" + +load_glidewrapper() +{ + w_download http://www.zeckensack.de/glide/archive/GlideWrapper084c.exe 3c4185bd7eac9bd50e0727a7b5165ec8273230455480cf94358e1bbd35921b69 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # The installer opens its README in a web browser, really annoying when doing make check/test: + # FIXME: maybe we should back up this key first? + if [ -n "${W_OPT_UNATTENDED}" ]; then + cat > "${W_TMP}"/disable-browser.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser] +"Browsers"="" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\disable-browser.reg + + fi + + # NSIS installer + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} + + if [ -n "${W_OPT_UNATTENDED}" ]; then + "${WINE}" reg delete "HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser" /v Browsers /f || true + fi +} + +#---------------------------------------------------------------- + +w_metadata gfw dlls \ + title="MS Games For Windows Live (xlive.dll)" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="gfwlivesetupmin.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/xlive.dll" + +load_gfw() +{ + # https://www.microsoft.com/games/en-us/live/pages/livejoin.aspx + # http://www.next-gen.biz/features/should-games-for-windows-live-die + w_download https://web.archive.org/web/20140730232216/https://download.microsoft.com/download/5/5/8/55846E20-4A46-4EF8-B272-7F988BC9090A/gfwlivesetupmin.exe b14609508e2f8dba0886ded84e2817ad532ebfa31f8a6d4be2e6a5a03a9d7c23 + + # Otherwise it leaves an arbitrarily named empty directory in ${W_CACHE} + w_try cp "${W_CACHE}/${W_PACKAGE}/gfwlivesetupmin.exe" "${W_TMP}" + w_try "${WINE}" "${W_TMP_WIN}\gfwlivesetupmin.exe" /nodotnet ${W_OPT_UNATTENDED:+/q} + + w_call msasn1 +} + +#---------------------------------------------------------------- + +w_metadata glut dlls \ + title="The glut utility library for OpenGL" \ + publisher="Mark J. Kilgard" \ + year="2001" \ + media="download" \ + file1="glut-3.7.6-bin.zip" \ + installed_file1="c:/glut-3.7.6-bin/glut32.lib" + +load_glut() +{ + w_download https://press.liacs.nl/researchdownloads/glut.win32/glut-3.7.6-bin.zip 788e97653bfd527afbdc69e1b7c6bcf9cb45f33d13ddf9d676dc070da92f80d4 + # FreeBSD unzip rm -rf's inside the target directory before extracting: + w_try_unzip "${W_TMP}" "${W_CACHE}"/glut/glut-3.7.6-bin.zip + w_try mv "${W_TMP}/glut-3.7.6-bin" "${W_DRIVE_C}" + w_try_cp_dll "${W_DRIVE_C}"/glut-3.7.6-bin/glut32.dll "${W_SYSTEM32_DLLS}" + w_warn "If you want to compile glut programs, add c:/glut-3.7.6-bin to LIB and INCLUDE" +} + +#---------------------------------------------------------------- + +w_metadata gmdls dlls \ + title="General MIDI DLS Collection" \ + publisher="Microsoft / Roland" \ + year="1999" \ + media="download" \ + file1="../directx9/directx_apr2006_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/drivers/gm.dls" + +load_gmdls() +{ + w_download_to directx9 https://web.archive.org/web/20100920035904/https://download.microsoft.com/download/3/9/7/3972f80c-5711-4e14-9483-959d48a2d03b/directx_apr2006_redist.exe dd8c3d401efe4561b67bd88475201b2f62f43cd23e4acc947bb34a659fa74952 + + w_try_cabextract -d "${W_TMP}" -F DirectX.cab "${W_CACHE}"/directx9/directx_apr2006_redist.exe + w_try_cabextract -d "${W_TMP}" -F gm16.dls "${W_TMP}"/DirectX.cab + + # When running in a 64bit prefix, syswow64/drivers doesn't exist + w_try mkdir -p "${W_SYSTEM32_DLLS}"/drivers + w_try mv "${W_TMP}"/gm16.dls "${W_SYSTEM32_DLLS}"/drivers/gm.dls + + if test "${W_ARCH}" = "win64"; then + w_try ln -s "${W_SYSTEM32_DLLS}"/drivers/gm.dls "${W_SYSTEM64_DLLS}"/drivers + fi +} + +#---------------------------------------------------------------- +# um, codecs are kind of clustered here. They probably deserve their own real category. + +w_metadata allcodecs dlls \ + title="All codecs (dirac, ffdshow, icodecs, cinepak, l3codecx, xvid) except wmp" \ + publisher="various" \ + year="1995-2009" \ + media="download" + +load_allcodecs() +{ + w_call dirac + w_call l3codecx + w_call ffdshow + w_call icodecs + w_call cinepak + w_call xvid +} + +#---------------------------------------------------------------- + +w_metadata dirac dlls \ + title="The Dirac directshow filter v1.0.2" \ + publisher="Dirac" \ + year="2009" \ + media="download" \ + file1="DiracDirectShowFilter-1.0.2.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Dirac/DiracDecoder.dll" + +load_dirac() +{ + w_download https://downloads.sourceforge.net/dirac/DiracDirectShowFilter-1.0.2.exe 7257de4be940405637bb5d11c1179f7db86f165f21fc0ba24f42a9ecbc55fe20 + + # Avoid mfc90 not found error. (DiracSplitter-libschroedinger.ax needs mfc90 to register itself, I think.) + w_call vcrun2008 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run DiracDirectShowFilter-1.0.2.exe + WinWait, Dirac, Welcome + if ( w_opt_unattended > 0 ) { + ControlClick, Button2 + WinWait, Dirac, License + Sleep 1000 + ControlClick, Button2 + WinWait, Dirac, Location + Sleep 1000 + ControlClick, Button2 + WinWait, Dirac, Components + Sleep 1000 + ControlClick, Button2 + WinWait, Dirac, environment + Sleep 1000 + ControlCLick, Button1 + WinWait, Dirac, installed + Sleep 1000 + ControlClick, Button2 + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata ffdshow dlls \ + title="ffdshow video codecs" \ + publisher="doom9 folks" \ + year="2010" \ + media="download" \ + file1="ffdshow_beta7_rev3154_20091209.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/ffdshow/ff_liba52.dll" \ + homepage="https://ffdshow-tryout.sourceforge.io/" + +load_ffdshow() +{ + w_download https://downloads.sourceforge.net/ffdshow-tryout/ffdshow_beta7_rev3154_20091209.exe 86fb22e9a79a1c83340a99fd5722974a4d03948109d404a383c4334fab8f8860 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" ffdshow_beta7_rev3154_20091209.exe ${W_OPT_UNATTENDED:+/silent} +} + +#---------------------------------------------------------------- + +w_metadata hid dlls \ + title="MS hid" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/hid.dll" + +load_hid() +{ + helper_win2ksp4 i386/hid.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/hid.dl_ + + w_override_dlls native hid +} + +#---------------------------------------------------------------- + +w_metadata icodecs dlls \ + title="Indeo codecs" \ + publisher="Intel" \ + year="1998" \ + media="download" \ + file1="codinstl.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/ir50_32.dll" + +load_icodecs() +{ + # Note: this codec is insecure, see + # https://support.microsoft.com/kb/954157 + # Original source, ftp://download.intel.com/support/createshare/camerapack/codinstl.exe, had same checksum + # 2010/11/14: http://codec.alshow.co.kr/Down/codinstl.exe + # 2014/04/11: http://www.cucusoft.com/codecdownload/codinstl.exe (linked from http://www.cucusoft.com/codec.asp) + w_download "http://www.cucusoft.com/codecdownload/codinstl.exe" 0979d43568111cadf0b3bf43cd8d746ac3de505759c14f381592b4f8439f6c95 + + # Extract the installer so that we can use the included Install Shield + # response file for unattended installations + w_try_cabextract -d "${W_TMP}/codinstl/" "${W_CACHE}/${W_PACKAGE}/codinstl.exe" + w_try_cd "${W_TMP}/codinstl/" + w_try "${WINE}" "setup.exe" ${W_OPT_UNATTENDED:+/s} + + # Work around bug in codec's installer? + # https://support.britannica.com/other/touchthesky/win/issues/TSTUw_150.htm + # https://appdb.winehq.org/objectManager.php?sClass=version&iId=7091 + w_try_regsvr ir50_32.dll + + # Apparently some codecs are missing, see https://github.com/Winetricks/winetricks/issues/302 + # Download at https://www.moviecodec.com/download-codec-packs/indeo-codecs-legacy-package-31/ + w_download https://s3.amazonaws.com/moviecodec/files/iv5setup.exe 51bec25488b5b94eb3ce49b0a117618c9526161fd0753817a7a724ce25ff0cad + + # Extract the installer so that we can create and use a pre-recorded + # Install Shield response file for unattended installations + w_try_cabextract -d "${W_TMP}/iv5setup/" "${W_CACHE}/${W_PACKAGE}/iv5setup.exe" + + # Create the response file with the following excluded components + # - IV5 Directshow plugin (gives error about missing Ivfsrc.ax) + # - Web browser (Netscape) plugin + # http://www.silentinstall.org/InstallShield + cat > "${W_TMP}/iv5setup/setup.iss" <<_EOF_ +[InstallShield Silent] +Version=v5.00.000 +File=Response File +[File Transfer] +OverwriteReadOnly=NoToAll +[DlgOrder] +Dlg0=SdWelcome-0 +Count=8 +Dlg1=SdLicense-0 +Dlg2=SdAskDestPath-0 +Dlg3=SdSetupTypeEx-0 +Dlg4=SdComponentDialog2-0 +Dlg5=AskYesNo-0 +Dlg6=SdStartCopy-0 +Dlg7=SdFinish-0 +[SdWelcome-0] +Result=1 +[SdLicense-0] +Result=1 +[SdAskDestPath-0] +szDir=C:\Program Files\Ligos\Indeo +Result=1 +[SdSetupTypeEx-0] +Result=Custom +[SdComponentDialog2-0] +Indeo Audio Codec-type=string +Indeo Audio Codec-count=1 +Indeo Audio Codec-0=Indeo Audio Codec\Indeo Audio Encoder +Component-type=string +Component-count=12 +Component-0=Indeo Video 5 Quick Compressors +Component-1=Indeo® Video 5 Codec +Component-2=Indeo Video 4 Codec +Component-3=Indeo Video 3.2 Codec +Component-4=Indeo Audio Codec +Component-5=Indeo Video Raw (YVU9) Codec +Component-6=Indeo Video 4 Quick Compressors +Component-7=Indeo Video 5 Compressor Help Files +Component-8=Indeo Video 4 Compressor Help Files +Component-9=Indeo Software Release Notes +Component-10=Indeo Software Installation Source Code +Component-11=Indeo Software Uninstallation +Result=1 +[AskYesNo-0] +Result=0 +[SdStartCopy-0] +Result=1 +[Application] +Name=Indeo® Software +Version=1.00.000 +Company=Ligos +Lang=0009 +[SdFinish-0] +Result=1 +bOpt1=0 +bOpt2=0 +_EOF_ + + w_try_cd "${W_TMP}/iv5setup/" + w_try "${WINE}" "setup.exe" ${W_OPT_UNATTENDED:+/s} + + # Note, this leaves a dangling explorer window. + # Wait for it to appear and kill it + while ! inode_pid=$(pgrep -f "explorer.exe.*Indeo"); do + sleep 1 + done + kill -HUP "${inode_pid}" +} + +#---------------------------------------------------------------- + +w_metadata iertutil dlls \ + title="MS Runtime Utility" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/iertutil.dll" + +load_iertutil() +{ + helper_win7sp1 x86_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_64655b7c61c841cb/iertutil.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_64655b7c61c841cb/iertutil.dll" "${W_SYSTEM32_DLLS}/iertutil.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_c083f7001a25b301/iertutil.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_c083f7001a25b301/iertutil.dll" "${W_SYSTEM64_DLLS}/iertutil.dll" + fi + + w_override_dlls native,builtin iertutil +} + +#---------------------------------------------------------------- + +w_metadata itircl dlls \ + title="MS itircl.dll" \ + publisher="Microsoft" \ + year="1999" \ + media="download" \ + file1="../hhw/htmlhelp.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/itircl.dll" + +load_itircl() +{ + # https://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx + w_download_to hhw https://web.archive.org/web/20160423015142if_/http://download.microsoft.com/download/0/a/9/0a939ef6-e31c-430f-a3df-dfae7960d564/htmlhelp.exe b2b3140d42a818870c1ab13c1c7b8d4536f22bd994fa90aade89729a6009a3ae + + w_try_cabextract -d "${W_TMP}" -F hhupd.exe "${W_CACHE}"/hhw/htmlhelp.exe + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -F itircl.dll "${W_TMP}"/hhupd.exe + w_override_dlls native itircl + w_try_regsvr itircl.dll +} + +#---------------------------------------------------------------- + +w_metadata itss dlls \ + title="MS itss.dll" \ + publisher="Microsoft" \ + year="1999" \ + media="download" \ + file1="../hhw/htmlhelp.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/itss.dll" + +load_itss() +{ + # https://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx + w_download_to hhw https://web.archive.org/web/20160423015142if_/http://download.microsoft.com/download/0/a/9/0a939ef6-e31c-430f-a3df-dfae7960d564/htmlhelp.exe b2b3140d42a818870c1ab13c1c7b8d4536f22bd994fa90aade89729a6009a3ae + + w_try_cabextract -d "${W_TMP}" -F hhupd.exe "${W_CACHE}"/hhw/htmlhelp.exe + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -F itss.dll "${W_TMP}"/hhupd.exe + w_override_dlls native itss + w_try_regsvr itss.dll +} + +#---------------------------------------------------------------- + +w_metadata cinepak dlls \ + title="Cinepak Codec" \ + publisher="Radius" \ + year="1995" \ + media="download" \ + file1="cvid32.zip" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/iccvid.dll" \ + homepage="http://www.probo.com/cinepak.php" + +load_cinepak() +{ + w_download "http://www.probo.com/pub/cinepak/cvid32.zip" a41984a954fe77557f228fa8a95cdc05db22bf9ff5429fe4307fd6fc51e11969 + + if [ -f "${W_SYSTEM32_DLLS}/iccvid.dll" ]; then + w_try rm -f "${W_SYSTEM32_DLLS}/iccvid.dll" + fi + + w_try_unzip "${W_SYSTEM32_DLLS}" "${W_CACHE}/${W_PACKAGE}/${file1}" ICCVID.DLL + + w_try mv -f "${W_SYSTEM32_DLLS}/ICCVID.DLL" "${W_SYSTEM32_DLLS}/iccvid_.dll" + w_try mv -f "${W_SYSTEM32_DLLS}/iccvid_.dll" "${W_SYSTEM32_DLLS}/iccvid.dll" + + w_override_dlls native iccvid +} + +#---------------------------------------------------------------- + +w_metadata jet40 dlls \ + title="MS Jet 4.0 Service Pack 8" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="jet40sp8_9xnt.exe" \ + installed_file1="${W_COMMONFILES_WIN}/Microsoft Shared/dao/dao360.dll" + +load_jet40() +{ + # Both mdac27/mdac28 are 32-bit only: + w_package_unsupported_win64 + + w_call mdac27 + w_call wsh57 + + # https://support.microsoft.com/kb/239114 + # See also https://bugs.winehq.org/show_bug.cgi?id=6085 + # FIXME: "failed with error 2" + w_download https://web.archive.org/web/20210225171713/http://download.microsoft.com/download/4/3/9/4393c9ac-e69e-458d-9f6d-2fe191c51469/Jet40SP8_9xNT.exe b060246cd499085a31f15873689d5fa7df817e407c8261a5c71fa6b9f7042560 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" jet40sp8_9xnt.exe ${W_OPT_UNATTENDED:+/q} +} + +# FIXME: verify_jet40() +# See https://github.com/Winetricks/winetricks/issues/327, +# https://en.wikibooks.org/wiki/JET_Database/Creating_and_connecting, and +# https://msdn.microsoft.com/en-us/library/ms677200%28v=vs.85%29.aspx + +#---------------------------------------------------------------- + +w_metadata ie8_kb2936068 dlls \ + title="Cumulative Security Update for Internet Explorer 8" \ + publisher="Microsoft" \ + year="2014" \ + media="download" \ + file1="IE8-WindowsXP-KB2936068-x86-ENU.exe" \ + installed_file1="c:/windows/KB2936068-IE8.log" + +load_ie8_kb2936068() +{ + # If we really need win64 support, should check if there's an x64 version of the hotfix + w_package_unsupported_win64 + + w_call ie8 + + w_download https://download.microsoft.com/download/3/8/C/38CE0ABB-01FD-4C0A-A569-BC5E82C34A17/IE8-WindowsXP-KB2936068-x86-ENU.exe 8bda23c78cdcd9d01c364a01c6d639dfb2d11550a5521b8a81c808c1a2b1824e + + w_set_winver winxp + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try_ms_installer "${WINE}" IE8-WindowsXP-KB2936068-x86-ENU.exe ${W_OPT_UNATTENDED:+/quiet /forcerestart} + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata l3codecx dlls \ + title="MPEG Layer-3 Audio Codec for Microsoft DirectShow" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/l3codecx.ax" + +load_l3codecx() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'l3codecx.ax' "${W_TMP}/dxnt.cab" + + w_try_regsvr l3codecx.ax +} + +#---------------------------------------------------------------- + +w_metadata lavfilters dlls \ + title="LAV Filters" \ + publisher="Hendrik Leppkes" \ + year="2019" \ + media="download" \ + conflicts="lavfilters702" \ + file1="LAVFilters-0.74.1-Installer.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/LAV Filters/x86/avfilter-lav-7.dll" \ + homepage="https://github.com/Nevcairiel/LAVFilters" + +load_lavfilters() +{ + w_download https://github.com/Nevcairiel/LAVFilters/releases/download/0.74.1/LAVFilters-0.74.1-Installer.exe 181e24428eaa34d0121cd53ec829c18e52d028689e12a7326f952989daa44ddb + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" LAVFilters-0.74.1-Installer.exe ${W_OPT_UNATTENDED:+ /VERYSILENT} +} + +#---------------------------------------------------------------- + +w_metadata lavfilters702 dlls \ + title="LAV Filters 0.70.2" \ + publisher="Hendrik Leppkes" \ + year="2017" \ + media="download" \ + conflicts="lavfilters" \ + file1="LAVFilters-0.70.2-Installer.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/LAV Filters/x86/avfilter-lav-6.dll" \ + homepage="https://github.com/Nevcairiel/LAVFilters" + +load_lavfilters702() +{ + w_download https://github.com/Nevcairiel/LAVFilters/releases/download/0.70.2/LAVFilters-0.70.2-Installer.exe 526e6f2de21759c0d5a60bfd2471880b5720cfb88a3b70163865a9d6cd2aa7cc + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" LAVFilters-0.70.2-Installer.exe ${W_OPT_UNATTENDED:+ /VERYSILENT} +} + +#---------------------------------------------------------------- + +# FIXME: installed location is +# $W_PROGRAMS_X86_WIN/Gemeinsame Dateien/System/ADO/msado26.tlb +# in German... need a variable W_COMMONFILES or something like that + +w_metadata mdac27 dlls \ + title="Microsoft Data Access Components 2.7 sp1" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="MDAC_TYP.EXE" \ + installed_file1="${W_COMMONFILES_X86_WIN}/System/ADO/msado26.tlb" + +load_mdac27() +{ + w_package_unsupported_win64 + + # https://www.microsoft.com/downloads/en/details.aspx?FamilyId=9AD000F2-CAE7-493D-B0F3-AE36C570ADE8&displaylang=en + # Originally at: https://download.microsoft.com/download/3/b/f/3bf74b01-16ba-472d-9a8c-42b2b4fa0d76/mdac_typ.exe + # Mirror list: http://www.filewatcher.com/m/MDAC_TYP.EXE.5389224-0.html (5.14 MB MDAC_TYP.EXE) + # 2018/08/09: ftp.gunadarma.ac.id is dead, moved to archive.org + w_download https://web.archive.org/web/20060718123742/http://ftp.gunadarma.ac.id/pub/driver/itegno/USB%20Software/MDAC/MDAC_TYP.EXE 36d2a3099e6286ae3fab181a502a95fbd825fa5ddb30bf09b345abc7f1f620b4 + + load_native_mdac + w_set_winver nt40 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/q /C:"setup /qnt"} + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata mdac28 dlls \ + title="Microsoft Data Access Components 2.8 sp1" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="MDAC_TYP.EXE" \ + installed_file1="${W_COMMONFILES_X86_WIN}/System/ADO/msado27.tlb" + +load_mdac28() +{ + w_package_unsupported_win64 + + # https://www.microsoft.com/en-us/download/details.aspx?id=5793 + w_download https://web.archive.org/web/20070127061938/https://download.microsoft.com/download/4/a/a/4aafff19-9d21-4d35-ae81-02c48dcbbbff/MDAC_TYP.EXE 157ebae46932cb9047b58aa849ac1885e8cbd2f218810cb83e57613b49c679d6 + load_native_mdac + w_set_winver nt40 + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" mdac_typ.exe ${W_OPT_UNATTENDED:+/q /C:"setup /qnt"} + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata mdx dlls \ + title="Managed DirectX" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="C:/windows/assembly/GAC/microsoft.directx/1.0.2902.0__31bf3856ad364e35/microsoft.directx.dll" + +load_mdx() +{ + helper_directx_Jun2010 + + w_try_cd "${W_TMP}" + + w_try_cabextract -F "*MDX*" "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -F "*.cab" ./*Archive.cab + + # Install assemblies + w_try_cabextract -d "${W_WINDIR_UNIX}/Microsoft.NET/DirectX for Managed Code/1.0.2902.0" -F "microsoft.directx*" ./*MDX1_x86.cab + for file in mdx_*.cab; do + ver="${file%%_x86.cab}" + ver="${ver##mdx_}" + w_try_cabextract -d "${W_WINDIR_UNIX}/Microsoft.NET/DirectX for Managed Code/${ver}" -F "microsoft.directx*" "${file}" + done + w_try_cabextract -d "${W_WINDIR_UNIX}/Microsoft.NET/DirectX for Managed Code/1.0.2911.0" -F "microsoft.directx.direct3dx*" ./*MDX1_x86.cab + + # Add them to GAC + w_try_cd "${W_WINDIR_UNIX}/Microsoft.NET/DirectX for Managed Code" + for ver in *; do + ( + w_try_cd "${ver}" + for asm in *.dll; do + name="${asm%%.dll}" + w_try mkdir -p "${W_WINDIR_UNIX}/assembly/GAC/${name}/${ver}__31bf3856ad364e35" + w_try cp "${asm}" "${W_WINDIR_UNIX}/assembly/GAC/${name}/${ver}__31bf3856ad364e35" + done + ) + done + + # AssemblyFolders + cat > "${W_TMP}"/asmfolders.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2902.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2902.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2903.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2903.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2904.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2904.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2905.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2905.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2906.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2906.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2907.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2907.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2908.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2908.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2909.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2909.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2910.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2910.0\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2911.0] +@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2911.0\\\\" +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\asmfolders.reg +} + +#---------------------------------------------------------------- + +w_metadata mf dlls \ + title="MS Media Foundation" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mf.dll" + +load_mf() +{ + helper_win7sp1 x86_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_9e6699276b03c38e/mf.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_9e6699276b03c38e/mf.dll" "${W_SYSTEM32_DLLS}/mf.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_fa8534ab236134c4/mf.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_fa8534ab236134c4/mf.dll" "${W_SYSTEM64_DLLS}/mf.dll" + fi + + w_override_dlls native,builtin mf +} + +#---------------------------------------------------------------- + +w_metadata mfc40 dlls \ + title="MS mfc40 (Microsoft Foundation Classes from win7sp1)" \ + publisher="Microsoft" \ + year="1999" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc40.dll" + +load_mfc40() +{ + helper_win7sp1 x86_microsoft-windows-mfc40_31bf3856ad364e35_6.1.7601.17514_none_5c06580240091047/mfc40.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-mfc40_31bf3856ad364e35_6.1.7601.17514_none_5c06580240091047/mfc40.dll" "${W_SYSTEM32_DLLS}/mfc40.dll" + + helper_win7sp1 x86_microsoft-windows-mfc40u_31bf3856ad364e35_6.1.7601.17514_none_f51a7bf0b3d25294/mfc40u.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-mfc40u_31bf3856ad364e35_6.1.7601.17514_none_f51a7bf0b3d25294/mfc40u.dll" "${W_SYSTEM32_DLLS}/mfc40u.dll" + + w_call msvcrt40 +} + +#---------------------------------------------------------------- + +w_metadata mfc70 dlls \ + title="Visual Studio (.NET) 2002 mfc70 library" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="VS7.0sp1-KB924642-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc70.dll" + +load_mfc70() +{ + w_download https://download.microsoft.com/download/6/b/e/6be11d8a-e0c7-429c-ac8c-9860e313ced9/VS7.0sp1-KB924642-X86.exe 7173a950169a58c56d7174811a7cd50e6092046f1f083db9d2b03315347fc0f4 + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" -F '*mfc*' + + w_try_cp_dll "${W_TMP}"/FL_mfc70_dll_____X86.3643236F_FC70_11D3_A536_0090278A1BB8 "${W_SYSTEM32_DLLS}"/mfc70.dll + w_try_cp_dll "${W_TMP}"/FL_mfc70u_dll_____X86.3643236F_FC70_11D3_A536_0090278A1BB8 "${W_SYSTEM32_DLLS}"/mfc70u.dll +} + +#---------------------------------------------------------------- + +w_metadata msaa dlls \ + title="MS Active Accessibility (oleacc.dll, oleaccrc.dll, msaatext.dll)" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="MSAA20_RDK.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/oleacc.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/oleaccrc.dll" \ + installed_file3="${W_SYSTEM32_DLLS_WIN}/msaatext.dll" + +load_msaa() +{ + w_download https://download.microsoft.com/download/c/1/c/c1cf13a6-4d7f-4b7d-9f67-51ef3a421fc7/MSAA20_RDK.exe 081e382f7e5b874ab143f0b073246fd31f84ae181df1838813b02935a951c9da + w_try_unzip "${W_TMP}/${W_PACKAGE}" "${W_CACHE}/${W_PACKAGE}"/MSAA20_RDK.exe + w_try cp "${W_TMP}/${W_PACKAGE}/oleaccW.dll" "${W_SYSTEM32_DLLS}/oleacc.dll" + w_try cp "${W_TMP}/${W_PACKAGE}/oleaccrc.dll" "${W_SYSTEM32_DLLS}/oleaccrc.dll" + w_try cp "${W_TMP}/${W_PACKAGE}/MSAATextW.dll" "${W_SYSTEM32_DLLS}/msaatext.dll" + w_override_dlls native,builtin oleacc oleaccrc msaatext +} + +#---------------------------------------------------------------- + +w_metadata msacm32 dlls \ + title="MS ACM32" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msacm32.dll" + +load_msacm32() +{ + helper_winxpsp3 i386/msacm32.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/msacm32.dl_ + w_override_dlls native,builtin msacm32 +} + +#---------------------------------------------------------------- + +w_metadata msasn1 dlls \ + title="MS ASN1" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msasn1.dll" + +load_msasn1() +{ + helper_win2ksp4 i386/msasn1.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/msasn1.dl_ +} + +#---------------------------------------------------------------- + +w_metadata msctf dlls \ + title="MS Text Service Module" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msctf.dll" + +load_msctf() +{ + helper_winxpsp3 i386/msctf.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/msctf.dl_ + w_override_dlls native,builtin msctf +} + +#---------------------------------------------------------------- + +w_metadata msdelta dlls \ + title="MSDelta differential compression library" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msdelta.dll" + +load_msdelta() +{ + helper_win7sp1 x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/msdelta.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/msdelta.dll" "${W_SYSTEM32_DLLS}/msdelta.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/msdelta.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/msdelta.dll" "${W_SYSTEM64_DLLS}/msdelta.dll" + fi + + w_override_dlls native,builtin msdelta +} + +#---------------------------------------------------------------- + +w_metadata msdxmocx dlls \ + title="MS Windows Media Player 2 ActiveX control for VB6" \ + publisher="Microsoft" \ + year="1999" \ + media="download" \ + file1="mpfull.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msdxm.ocx" + +load_msdxmocx() +{ + # Previously at https://www.oldapps.com/windows_media_player.php?old_windows_media_player=3?download + # 2015/12/01: Iceweasel gave a security warning (!), but clamscan and virustotal.com report it as clean + # + # 2016/02/18: Since then, oldapps.com removed it. It's on a Finnish mirror, where it's been since 2001/10/20 + # Found using http://www.filewatcher.com/m/mpfull.exe.3593680-0.html + # The sha256sum is different. Perhaps Iceweasel was right. This one is also clean according to clamscan/virustotal.com + + # 2017/09/28: define.fi is down, these sites have mpfull.exe with the original sha256: + # http://hell.pl/agnus/windows95/ + # http://zerosky.oldos.org/win9x.html + # https://sdfox7.com/win95/ + + w_download http://hell.pl/agnus/windows95/mpfull.exe a39b2b9735cedd513fcb78f8634695d35073e9d7e865e536a0da6db38c7225e4 + + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_regsvr msdxm.ocx +} + +#---------------------------------------------------------------- + +w_metadata msflxgrd dlls \ + title="MS FlexGrid Control (msflxgrd.ocx)" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msflxgrd.ocx" + +load_msflxgrd() +{ + helper_vb6sp6 "${W_TMP}" MSFlxGrd.ocx + w_try mv "${W_TMP}/MSFlxGrd.ocx" "${W_SYSTEM32_DLLS}/msflxgrd.ocx" + w_try_regsvr msflxgrd.ocx +} + +#---------------------------------------------------------------- + +w_metadata mshflxgd dlls \ + title="MS Hierarchical FlexGrid Control (mshflxgd.ocx)" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mshflxgd.ocx" + +load_mshflxgd() +{ + helper_vb6sp6 "${W_TMP}" MShflxgd.ocx + w_try mv "${W_TMP}/MShflxgd.ocx" "${W_SYSTEM32_DLLS}/mshflxgd.ocx" + w_try_regsvr mshflxgd.ocx +} + +#---------------------------------------------------------------- + +w_metadata mspatcha dlls \ + title="MS mspatcha" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_exe1="${W_SYSTEM32_DLLS_WIN}/mspatcha.dll" + +load_mspatcha() +{ + helper_win2ksp4 i386/mspatcha.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/mspatcha.dl_ + + w_override_dlls native,builtin mspatcha +} + +#---------------------------------------------------------------- + +w_metadata msscript dlls \ + title="MS Windows Script Control" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msscript.ocx" + +load_msscript() +{ + helper_winxpsp3 i386/msscript.oc_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/msscript.oc_ + w_override_dlls native,builtin i386/msscript.ocx +} + +#---------------------------------------------------------------- + +w_metadata msls31 dlls \ + title="MS Line Services" \ + publisher="Microsoft" \ + year="2001" \ + media="download" \ + file1="InstMsiW.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msls31.dll" + +load_msls31() +{ + # Needed by native RichEdit and Internet Explorer + # Originally at https://download.microsoft.com/download/WindowsInstaller/Install/2.0/NT45/EN-US/InstMsiW.exe + # Old mirror at https://ftp.hp.com/pub/softlib/software/msi/InstMsiW.exe + w_download https://web.archive.org/web/20160710055851if_/http://download.microsoft.com/download/WindowsInstaller/Install/2.0/NT45/EN-US/InstMsiW.exe 4c3516c0b5c2b76b88209b22e3bf1cb82d8e2de7116125e97e128952372eed6b + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}"/msls31/InstMsiW.exe + w_try_cp_dll "${W_TMP}"/msls31.dll "${W_SYSTEM32_DLLS}" +} + +#---------------------------------------------------------------- + +w_metadata msmask dlls \ + title="MS Masked Edit Control" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msmask32.ocx" + +load_msmask() +{ + helper_vb6sp6 "${W_TMP}" msmask32.ocx + w_try mv "${W_TMP}/msmask32.ocx" "${W_SYSTEM32_DLLS}/msmask32.ocx" + w_try_regsvr msmask32.ocx +} + + #---------------------------------------------------------------- + +w_metadata msftedit dlls \ + title="Microsoft RichEdit Control" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msftedit.dll" + +load_msftedit() +{ + helper_win7sp1 x86_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_d7d862f19573a5ff/msftedit.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_d7d862f19573a5ff/msftedit.dll" "${W_SYSTEM32_DLLS}/msftedit.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_33f6fe754dd11735/msftedit.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_33f6fe754dd11735/msftedit.dll" "${W_SYSTEM64_DLLS}/msftedit.dll" + fi + + w_override_dlls native,builtin msftedit +} + +#---------------------------------------------------------------- + +w_metadata msvcrt40 dlls \ + title="fixme" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msvcrt40.dll" + +load_msvcrt40() +{ + helper_winxpsp3 i386/msvcrt40.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/msvcrt40.dl_ + + w_override_dlls native,builtin msvcrt40 +} + +#---------------------------------------------------------------- + +w_metadata msxml3 dlls \ + title="MS XML Core Services 3.0" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="msxml3.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msxml3.dll" + +load_msxml3() +{ + # Service Pack 7 + # Originally at https://download.microsoft.com/download/8/8/8/888f34b7-4f54-4f06-8dac-fa29b19f33dd/msxml3.msi + # Mirror list: http://www.filewatcher.com/m/msxml3.msi.1070592-0.html + # Known bad sites (2017/06/11): + # ftp://support.danbit.dk/D/DVD-RW-USB2B/Driver/Installation/Data/Redist/msxml3.msi + # ftp://94.79.56.169/common/Client/MSXML%204.0%20Service%20Pack%202/msxml3.msi + w_download https://media.codeweavers.com/pub/other/msxml3.msi f9c678f8217e9d4f9647e8a1f6d89a7c26a57b9e9e00d39f7487493dd7b4e36c + + # It won't install on top of Wine's msxml3, which has a pretty high version number, so delete Wine's fake DLL + rm "${W_SYSTEM32_DLLS}"/msxml3.dll + w_override_dlls native msxml3 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # See https://github.com/Winetricks/winetricks/issues/1086 + # and https://bugs.winehq.org/show_bug.cgi?id=26925 + if w_workaround_wine_bug 26925 "Forcing quiet install"; then + w_try "${WINE}" msiexec /i msxml3.msi /q + else + w_try "${WINE}" msiexec /i msxml3.msi ${W_OPT_UNATTENDED:+/q} + fi +} + +#---------------------------------------------------------------- + +w_metadata msxml4 dlls \ + title="MS XML Core Services 4.0" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="msxml.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msxml4.dll" + +load_msxml4() +{ + # MS06-071: https://www.microsoft.com/en-us/download/details.aspx?id=11125 + # w_download https://download.microsoft.com/download/e/2/e/e2e92e52-210b-4774-8cd9-3a7a0130141d/msxml4-KB927978-enu.exe 7602c2a6d2a46ef2b4028438d2cce67fe437a9bfb569249ea38141b4756b4e03 + # MS07-042: https://www.microsoft.com/en-us/download/details.aspx?id=2386 + # w_download https://download.microsoft.com/download/9/4/2/9422e6b6-08ee-49cb-9f05-6c6ee755389e/msxml4-KB936181-enu.exe 1ce9ff868816cfc9bf33e93fdf1552afce5b491443892babb521e74c05e45242 + # SP3 (2009): https://www.microsoft.com/en-us/download/details.aspx?id=15697 + w_download https://web.archive.org/web/20210506101448/http://download.microsoft.com/download/A/2/D/A2D8587D-0027-4217-9DAD-38AFDB0A177E/msxml.msi 47c2ae679c37815da9267c81fc3777de900ad2551c11c19c2840938b346d70bb + w_override_dlls native,builtin msxml4 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec /i msxml.msi ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata msxml6 dlls \ + title="MS XML Core Services 6.0 sp2" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="msxml6-KB973686-enu-amd64.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msxml6.dll" + +load_msxml6() +{ + # Service Pack 2 + # https://www.microsoft.com/en-us/download/details.aspx?id=9774 + + # 64bit exe also includes 32bit dlls + # Originally here: https://download.microsoft.com/download/1/5/8/158F681A-E595-472B-B15E-62B649B1B6FF/msxml6-KB973686-enu-amd64.exe + w_download https://web.archive.org/web/20190122095451/https://download.microsoft.com/download/1/5/8/158F681A-E595-472B-B15E-62B649B1B6FF/msxml6-KB973686-enu-amd64.exe 0e5c4af488e88e8defb59de80271671d8283d5744b2eebdb351bbd4950fb0883 + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}"/msxml6/msxml6-KB973686-enu-amd64.exe + w_try_cabextract --directory="${W_TMP}" "${W_TMP}"/msxml6.msi + w_try_cp_dll "${W_TMP}"/msxml6.dll.86F857F6_A743_463D_B2FE_98CB5F727E09 "${W_SYSTEM32_DLLS}"/msxml6.dll + w_try_cp_dll "${W_TMP}"/msxml6r.dll.86F857F6_A743_463D_B2FE_98CB5F727E09 "${W_SYSTEM32_DLLS}"/msxml6r.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_try_cp_dll "${W_TMP}"/msxml6.dll.1ECC0691_D2EB_4A33_9CBF_5487E5CB17DB "${W_SYSTEM64_DLLS}"/msxml6.dll + w_try_cp_dll "${W_TMP}"/msxml6r.dll.1ECC0691_D2EB_4A33_9CBF_5487E5CB17DB "${W_SYSTEM64_DLLS}"/msxml6r.dll + fi + + w_override_dlls native,builtin msxml6 +} + +#---------------------------------------------------------------- + +w_metadata nuget dlls \ + title="NuGet Package manager" \ + publisher="Outercurve Foundation" \ + year="2013" \ + media="download" \ + file1="nuget.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/nuget.exe" \ + homepage="https://nuget.org" + +load_nuget() +{ + w_call dotnet40 + # Changes too rapidly to check shasum + w_download https://nuget.org/nuget.exe + w_try_cp_dll "${W_CACHE}/${W_PACKAGE}"/nuget.exe "${W_SYSTEM32_DLLS}" + w_warn "To run NuGet, use the command line \"${WINE} nuget\"." +} + +#---------------------------------------------------------------- + +w_metadata ogg dlls \ + title="OpenCodecs 0.85: FLAC, Speex, Theora, Vorbis, WebM" \ + publisher="Xiph.Org Foundation" \ + year="2011" \ + media="download" \ + file1="opencodecs_0.85.17777.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Xiph.Org/Open Codecs/AxPlayer.dll" \ + homepage="https://xiph.org/dshow" + +load_ogg() +{ + w_download https://downloads.xiph.org/releases/oggdsf/opencodecs_0.85.17777.exe fcec3cea637e806501aff447d902de3b5bfef226b629e43ab67e46dbb23f13e7 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + + +#---------------------------------------------------------------- + +w_metadata ole32 dlls \ + title="MS ole32 Module (ole32.dll)" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/ole32.dll" + +load_ole32() +{ + # Some applications need this, for example Wechat. + helper_winxpsp3 i386/ole32.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/ole32.dl_ + w_override_dlls native,builtin ole32 +} + +#---------------------------------------------------------------- + +w_metadata oleaut32 dlls \ + title="MS oleaut32.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/oleaut32.dll" + +load_oleaut32() +{ + helper_win7sp1 x86_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_bf07947959bc4c33/oleaut32.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_bf07947959bc4c33/oleaut32.dll" "${W_SYSTEM32_DLLS}/oleaut32.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_1b262ffd1219bd69/oleaut32.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_1b262ffd1219bd69/oleaut32.dll" "${W_SYSTEM64_DLLS}/oleaut32.dll" + fi + + w_override_dlls native,builtin oleaut32 +} + +#---------------------------------------------------------------- + +w_metadata pdh dlls \ + title="MS pdh.dll (Performance Data Helper)" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + conflicts="pdh_nt4" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/pdh.dll" + +load_pdh() +{ + helper_win7sp1 x86_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_b5e3f88a8eb425e8/pdh.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_b5e3f88a8eb425e8/pdh.dll" "${W_SYSTEM32_DLLS}/pdh.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_1202940e4711971e/pdh.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_1202940e4711971e/pdh.dll" "${W_SYSTEM64_DLLS}/pdh.dll" + fi + + w_override_dlls native,builtin pdh +} + +#---------------------------------------------------------------- + +w_metadata pdh_nt4 dlls \ + title="MS pdh.dll (Performance Data Helper); WinNT 4.0 Version" \ + publisher="Microsoft" \ + year="1997" \ + media="download" \ + conflicts="pdh" \ + file1="nt4pdhdll.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/pdh.dll" + +load_pdh_nt4() +{ + if [ "${W_ARCH}" = "win64" ]; then + w_warn "There is no 64-bit version of the WinNT 4.0 pdh.dll. If your program doesn't work then try a 32-bit wineprefix or use 'winetricks pdh' instead." + fi + + w_download http://download.microsoft.com/download/winntsrv40/update/5.0.2195.2668/nt4/en-us/nt4pdhdll.exe a0a45ea8f4b82daaebcff7ad5bd1b7f5546e527e04790ca8c4c9b71b18c73e32 + + w_try_unzip "${W_TMP}/${W_PACKAGE}" "${W_CACHE}/${W_PACKAGE}"/nt4pdhdll.exe + w_try_cp_dll "${W_TMP}/${W_PACKAGE}/pdh.dll" "${W_SYSTEM32_DLLS}/pdh.dll" + + w_override_dlls native,builtin pdh +} + +#---------------------------------------------------------------- + +w_metadata peverify dlls \ + title="MS peverify (from .NET 2.0 SDK)" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="../dotnet20sdk/setup.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/peverify.exe" + +load_peverify() +{ + w_download_to dotnet20sdk https://download.microsoft.com/download/c/4/b/c4b15d7d-6f37-4d5a-b9c6-8f07e7d46635/setup.exe 1d7337bfbb2c65f43c82d188688ce152af403bcb67a2cc2a3cc68a580ecd8200 + + # Seems to require dotnet20; at least doesn't work if dotnet40 is installed instead + w_call dotnet20 + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/dotnet20sdk/setup.exe" -F netfxsd1.cab + w_try_cabextract --directory="${W_TMP}" "${W_TMP}/netfxsd1.cab" -F FL_PEVerify_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8 + w_try mv "${W_TMP}/FL_PEVerify_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8" "${W_SYSTEM32_DLLS}/peverify.exe" +} + +#---------------------------------------------------------------- + +w_metadata physx dlls \ + title="PhysX" \ + publisher="Nvidia" \ + year="2021" \ + media="download" \ + file1="PhysX_9.21.0713_SystemSoftware.exe" \ + +load_physx() +{ + w_get_sha256sum "${W_PROGRAMS_X86_UNIX}/NVIDIA Corporation/PhysX/Engine/86C5F4F22ECD/APEX_Particles_x64.dll" + if [ "${_W_gotsha256sum}"x = "b3991e0165a9802b60e2f7d14c1be5f879071999ae74a38263cec9bf043a9eaa"x ] ; then + w_warn "${W_PACKAGE} is already installed - not updating" + unset _W_gotsha256sum + return + else + unset _W_gotsha256sum + w_download https://us.download.nvidia.com/Windows/9.21.0713/PhysX_9.21.0713_SystemSoftware.exe 26d62c5c347c15cb27c3be92bf10706113511b48b28aecc09f61ee58b3b62778 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" PhysX_9.21.0713_SystemSoftware.exe ${W_OPT_UNATTENDED:+/s} + fi +} + +#---------------------------------------------------------------- + +w_metadata pngfilt dlls \ + title="pngfilt.dll (from winxp)" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/pngfilt.dll" + +load_pngfilt() +{ + # Previously used https://www.microsoft.com/en-us/download/details.aspx?id=3907 + # Now using winxp's dll + + helper_winxpsp3 i386/pngfilt.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/pngfilt.dl_ + w_try_regsvr pngfilt.dll +} + +#---------------------------------------------------------------- + +w_metadata prntvpt dlls \ + title="prntvpt.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/prntvpt.dll" + +load_prntvpt() +{ + + helper_win7sp1 x86_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_1562129afd710f2c/prntvpt.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_1562129afd710f2c/prntvpt.dll" "${W_SYSTEM32_DLLS}/prntvpt.dll" + + w_override_dlls native,builtin prntvpt + w_try_regsvr prntvpt.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_7180ae1eb5ce8062/prntvpt.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_7180ae1eb5ce8062/prntvpt.dll" "${W_SYSTEM64_DLLS}/prntvpt.dll" + w_try_regsvr64 prntvpt.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata python26 dlls \ + title="Python interpreter 2.6.2" \ + publisher="Python Software Foundaton" \ + year="2009" \ + media="download" \ + file1="python-2.6.2.msi" \ + installed_exe1="c:/Python26/python.exe" + +load_python26() +{ + w_download https://www.python.org/ftp/python/2.6.2/python-2.6.2.msi c2276b398864b822c25a7c240cb12ddb178962afd2e12d602f1a961e31ad52ff + w_download https://downloads.sourceforge.net/project/pywin32/pywin32/Build%20214/pywin32-214.win32-py2.6.exe dc311bbdc5868e3dd139dfc46136221b7f55c5613a98a5a48fa725a6c681cd40 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec /i python-2.6.2.msi ALLUSERS=1 ${W_OPT_UNATTENDED:+/q} + + w_ahk_do " + SetTitleMatchMode, 2 + run pywin32-214.win32-py2.6.exe + WinWait, Setup, Wizard will install pywin32 + if ( w_opt_unattended > 0 ) { + ControlClick Button2 ; next + WinWait, Setup, Python 2.6 is required + ControlClick Button3 ; next + WinWait, Setup, Click Next to begin + ControlClick Button3 ; next + WinWait, Setup, finished + ControlClick Button4 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata python27 dlls \ + title="Python interpreter 2.7.16" \ + publisher="Python Software Foundaton" \ + year="2019" \ + media="download" \ + file1="python-2.7.16.msi" \ + installed_exe1="c:/Python27/python.exe" + +load_python27() +{ + w_download https://www.python.org/ftp/python/2.7.16/python-2.7.16.msi d57dc3e1ba490aee856c28b4915d09e3f49442461e46e481bc6b2d18207831d7 + w_download https://github.com/mhammond/pywin32/releases/download/b224/pywin32-224.win32-py2.7.exe 03bb02aff0ec604d1d5fefc699581ab599fff618eaddc8a721f2fa22e5572dd4 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec /i python-2.7.16.msi ALLUSERS=1 ${W_OPT_UNATTENDED:+/q} + + w_ahk_do " + SetTitleMatchMode, 2 + run pywin32-224.win32-py2.7.exe + WinWait, Setup, Wizard will install pywin32 + if ( w_opt_unattended > 0 ) { + ControlClick Button2 ; next + WinWait, Setup, Python 2.7 is required + ControlClick Button3 ; next + WinWait, Setup, Click Next to begin + ControlClick Button3 ; next + WinWait, Setup, finished + ControlClick Button4 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata qasf dlls \ + title="qasf.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/qasf.dll" + +load_qasf() +{ + helper_win7sp1 x86_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_1cc4e9c15ccc8ae8/qasf.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_1cc4e9c15ccc8ae8/qasf.dll" "${W_SYSTEM32_DLLS}/qasf.dll" + + w_override_dlls native,builtin qasf + w_try_regsvr qasf.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_78e385451529fc1e/qasf.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_78e385451529fc1e/qasf.dll" "${W_SYSTEM64_DLLS}/qasf.dll" + w_try_regsvr64 qasf.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata qcap dlls \ + title="qcap.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/qcap.dll" + +load_qcap() +{ + helper_win7sp1 x86_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_bae08d1e7dcccf2a/qcap.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_bae08d1e7dcccf2a/qcap.dll" "${W_SYSTEM32_DLLS}/qcap.dll" + w_override_dlls native,builtin qcap + w_try_regsvr qcap.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_16ff28a2362a4060/qcap.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_16ff28a2362a4060/qcap.dll" "${W_SYSTEM64_DLLS}/qcap.dll" + w_try_regsvr64 qcap.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata qdvd dlls \ + title="qdvd.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/qdvd.dll" + +load_qdvd() +{ + helper_win7sp1 x86_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_562994bd321aac67/qdvd.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_562994bd321aac67/qdvd.dll" "${W_SYSTEM32_DLLS}/qdvd.dll" + w_override_dlls native,builtin qdvd + w_try_regsvr qdvd.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_b2483040ea781d9d/qdvd.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_b2483040ea781d9d/qdvd.dll" "${W_SYSTEM64_DLLS}/qdvd.dll" + w_try_regsvr64 qdvd.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata qedit dlls \ + title="qedit.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/qedit.dll" + +load_qedit() +{ + helper_win7sp1 x86_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_5ca34698a5a970d2/qedit.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_5ca34698a5a970d2/qedit.dll" "${W_SYSTEM32_DLLS}/qedit.dll" + w_override_dlls native,builtin qedit + w_try_regsvr qedit.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_b8c1e21c5e06e208/qedit.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_b8c1e21c5e06e208/qedit.dll" "${W_SYSTEM64_DLLS}/qedit.dll" + w_try_regsvr64 qedit.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata quartz dlls \ + title="quartz.dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/quartz.dll" + +load_quartz() +{ + helper_win7sp1 x86_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_a877a1cc4c284497/quartz.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_a877a1cc4c284497/quartz.dll" "${W_SYSTEM32_DLLS}/quartz.dll" + w_override_dlls native,builtin quartz + w_try_regsvr quartz.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_04963d500485b5cd/quartz.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_04963d500485b5cd/quartz.dll" "${W_SYSTEM64_DLLS}/quartz.dll" + w_try_regsvr64 quartz.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata quartz_feb2010 dlls \ + title="quartz.dll (February 2010)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + conflicts="quartz" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/quartz.dll" + +load_quartz_feb2010() +{ + helper_directx_dl + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F quartz.dll "${W_TMP}/dxnt.cab" + + w_override_dlls native,builtin quartz + w_try_regsvr quartz.dll +} + +#---------------------------------------------------------------- + +w_metadata quicktime72 dlls \ + title="Apple QuickTime 7.2" \ + publisher="Apple" \ + year="2010" \ + media="download" \ + file1="QuickTimeInstaller.exe" \ + installed_file1="c:/windows/Installer/{95A890AA-B3B1-44B6-9C18-A8F7AB3EE7FC}/QTPlayer.ico" + +load_quicktime72() +{ + # https://support.apple.com/kb/DL837 + w_download http://appldnld.apple.com.edgesuite.net/content.info.apple.com/QuickTime/061-2915.20070710.pO94c/QuickTimeInstaller.exe a42b93531910bdf1539cc5ae3199ade5a1ca63fd4ac971df74c345d8e1ee6593 + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" "${file1}" ALLUSERS=1 DESKTOP_SHORTCUTS=0 QTTaskRunFlags=0 QTINFO.BISQTPRO=1 SCHEDULE_ASUW=0 REBOOT_REQUIRED=No ${W_OPT_UNATTENDED:+/qn} > /dev/null 2>&1 + + if w_workaround_wine_bug 11681; then + # Following advice verified with test movies from + # https://support.apple.com/kb/HT1425 + # in QuickTimePlayer. + + case ${LANG} in + ru*) w_warn "В настройках Quicktime включите Дополнительно / Безопасный режим (только gdi), иначе видеофайлы не будут воспроизводиться." ;; + pt*) w_warn "Nas preferências do Quicktime, marque Advanced / Safe Mode (gdi), ou os vídeos não irão reproduzir." ;; + *) w_warn "In Quicktime preferences, check Advanced / Safe Mode (gdi), or movies won't play." ;; + esac + if [ -z "${W_OPT_UNATTENDED}" ]; then + w_try "${WINE}" control "${W_PROGRAMS_WIN}\\QuickTime\\QTSystem\\QuickTime.cpl" + else + # FIXME: script the control panel with AutoHotKey? + # We could probably also overwrite QuickTime.qtp but + # the format isn't known, so we'd have to override all other settings, too. + : + fi + fi +} + +#---------------------------------------------------------------- + +w_metadata quicktime76 dlls \ + title="Apple QuickTime 7.6" \ + publisher="Apple" \ + year="2010" \ + media="download" \ + file1="QuickTimeInstaller.exe" \ + installed_file1="c:/windows/Installer/{57752979-A1C9-4C02-856B-FBB27AC4E02C}/QTPlayer.ico" + +load_quicktime76() +{ + # https://support.apple.com/kb/DL837 + w_download http://appldnld.apple.com/QuickTime/041-0025.20101207.Ptrqt/QuickTimeInstaller.exe c2dcda76ed55428e406ad7e6acdc84e804d30752a1380c313394c09bb3e27f56 + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" QuickTimeInstaller.exe ALLUSERS=1 DESKTOP_SHORTCUTS=0 QTTaskRunFlags=0 QTINFO.BISQTPRO=1 SCHEDULE_ASUW=0 REBOOT_REQUIRED=No ${W_OPT_UNATTENDED:+/qn} > /dev/null 2>&1 + + if w_workaround_wine_bug 11681; then + # Following advice verified with test movies from + # https://support.apple.com/kb/HT1425 + # in QuickTimePlayer. + + case ${LANG} in + ru*) w_warn "В настройках Quicktime включите Дополнительно / Безопасный режим (только gdi), иначе видеофайлы не будут воспроизводиться." ;; + pt*) w_warn "Nas preferências do Quicktime, marque Advanced / Safe Mode (gdi), ou os vídeos não irão reproduzir." ;; + *) w_warn "In Quicktime preferences, check Advanced / Safe Mode (gdi), or movies won't play." ;; + esac + if [ -z "${W_OPT_UNATTENDED}" ]; then + w_try "${WINE}" control "${W_PROGRAMS_WIN}\\QuickTime\\QTSystem\\QuickTime.cpl" + else + # FIXME: script the control panel with AutoHotKey? + # We could probably also overwrite QuickTime.qtp but + # the format isn't known, so we'd have to override all other settings, too. + : + fi + fi +} + +#---------------------------------------------------------------- + +w_metadata riched20 dlls \ + title="MS RichEdit Control 2.0 (riched20.dll)" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/riched20.dll" + +load_riched20() +{ + # FIXME: this verb used to also install riched32. Does anyone need that? + helper_win2ksp4 i386/riched20.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/riched20.dl_ + w_override_dlls native,builtin riched20 + + # https://github.com/Winetricks/winetricks/issues/292 + w_call msls31 +} + +#---------------------------------------------------------------- + +# Problem - riched20 and riched30 both install riched20.dll! +# We may need a better way to distinguish between installed files. + +w_metadata riched30 dlls \ + title="MS RichEdit Control 3.0 (riched20.dll, msls31.dll)" \ + publisher="Microsoft" \ + year="2001" \ + media="download" \ + file1="InstMsiA.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/riched20.dll" \ + installed_file2="${W_SYSTEM32_DLLS_WIN}/msls31.dll" + +load_riched30() +{ + # http://www.novell.com/documentation/nm1/readmeen_web/readmeen_web.html#Akx3j64 + # claims that Groupwise Messenger's View / Text Size command + # only works with riched30, and recommends getting it by installing + # msi 2, which just happens to come with riched30 version of riched20 + # (though not with a corresponding riched32, which might be a problem) + + # https://www.microsoft.com/en-us/download/details.aspx?id=21990 + # Originally at https://download.microsoft.com/download/WindowsInstaller/Install/2.0/W9XMe/EN-US/InstMsiA.exe + # with sha256sum 536e4c8385d7d250fd5702a6868d1ed004692136eefad22252d0dac15f02563a + # Mirror list at http://www.filewatcher.com/m/InstMsiA.Exe.1707856-0.html + # But they all have a different sha256sum, 5ab8b82f578f09dbccf797754155e531b5996b532c1f19c531596ec07cc4b46d + # Since mirrors are dead, going back to the microsoft.com version, via archive.org + w_download https://web.archive.org/web/20060720160141/https://download.microsoft.com/download/WindowsInstaller/Install/2.0/W9XMe/EN-US/InstMsiA.exe 536e4c8385d7d250fd5702a6868d1ed004692136eefad22252d0dac15f02563a + + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}"/riched30/InstMsiA.exe + w_try_cp_dll "${W_TMP}"/riched20.dll "${W_SYSTEM32_DLLS}" + w_try_cp_dll "${W_TMP}"/msls31.dll "${W_SYSTEM32_DLLS}" + w_override_dlls native,builtin riched20 +} + +#---------------------------------------------------------------- + +w_metadata richtx32 dlls \ + title="MS Rich TextBox Control 6.0" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/richtx32.ocx" + +load_richtx32() +{ + helper_vb6sp6 "${W_SYSTEM32_DLLS}" richtx32.ocx + w_try_regsvr richtx32.ocx +} + +#---------------------------------------------------------------- + +w_metadata sapi dlls \ + title="MS Speech API" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + conflicts="speechsdk" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/sapi.dll" + +load_sapi() +{ + # This version of native SAPI needs to be directly in system32/syswow64 + for stub in "${W_SYSTEM32_DLLS}/Speech" "${W_SYSTEM64_DLLS}/Speech"; do + if [ -d "${stub}" ]; then + w_try rm -rf "${stub}" + fi + done + + helper_win7sp1 x86_microsoft-windows-speechcommon_31bf3856ad364e35_6.1.7601.17514_none_d809b28230ecfe46/sapi.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-speechcommon_31bf3856ad364e35_6.1.7601.17514_none_d809b28230ecfe46/sapi.dll" "${W_SYSTEM32_DLLS}/sapi.dll" + w_override_dlls native sapi + w_try_regsvr sapi.dll + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-speechcommon_31bf3856ad364e35_6.1.7601.17514_none_34284e05e94a6f7c/sapi.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-speechcommon_31bf3856ad364e35_6.1.7601.17514_none_34284e05e94a6f7c/sapi.dll" "${W_SYSTEM64_DLLS}/sapi.dll" + w_try_regsvr64 sapi.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata sdl dlls \ + title="Simple DirectMedia Layer" \ + publisher="Sam Lantinga" \ + year="2012" \ + media="download" \ + file1="SDL-1.2.15-win32.zip" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/SDL.dll" + +load_sdl() +{ + # https://www.libsdl.org/download-1.2.php + w_download https://www.libsdl.org/release/SDL-1.2.15-win32.zip a28bbe38714ef7817b1c1e8082a48f391f15e4043402444b783952fca939edc1 + w_try_unzip "${W_SYSTEM32_DLLS}" "${W_CACHE}"/sdl/SDL-1.2.15-win32.zip SDL.dll +} + +#---------------------------------------------------------------- + +w_metadata secur32 dlls \ + title="MS Security Support Provider Interface" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/secur32.dll" + +load_secur32() +{ + w_warn "Installing native secur32 may lead to stack overflow crashes, see https://bugs.winehq.org/show_bug.cgi?id=45344" + + helper_win7sp1 x86_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_a851f4adbb0d5141/secur32.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_a851f4adbb0d5141/secur32.dll" "${W_SYSTEM32_DLLS}/secur32.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_04709031736ac277/secur32.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_04709031736ac277/secur32.dll" "${W_SYSTEM64_DLLS}/secur32.dll" + fi + + w_override_dlls native,builtin secur32 +} + +#---------------------------------------------------------------- + +w_metadata setupapi dlls \ + title="MS Setup API" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/setupapi.dll" + +load_setupapi() +{ + helper_winxpsp3 i386/setupapi.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/setupapi.dl_ + + w_override_dlls native,builtin setupapi +} + +#---------------------------------------------------------------- + +w_metadata shockwave dlls \ + title="Shockwave" \ + publisher="Adobe" \ + year="2018" \ + media="download" \ + file1="sw_lic_full_installer.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/Adobe/Shockwave 12/shockwave_Projector_Loader.dcr" + +load_shockwave() { + # 2017/03/12: 39715a84b1d85347066fbf89a3af9f5e612b59402093b055cd423bd30a7f637d + # 2017/03/15: 58f2152bf726d52f08fb41f904c62ff00fdf748c8ce413e8c8547da3a21922ba + # 2017/08/03: bebebaef1644a994179a2e491ce3f55599d768f7c6019729f21e7029b1845b9c + # 2017/12/12: 0a9813ac55a8718440518dc2f5f410a3a065b422fe0618c073bfc631b9abf12c + # 2018/03/16: 4d7b408cf5b65a522b071d7d9ddbc5f6964911a7d55c418e31f393e6055cf796 + # 2018/05/24: 2b03fa11ff6f31b3fef9313264f0ef356ee11d5bc3642c30a2482b4ac5dd0084 + # 2018/06/14: a37f6c47b74fa3c96906e01b9b41d63c08d212fa3e357e354db1b5a93eb92c2f + # 2019/04/02: 8e414c1a218157d2b83877fb0b6a5002c2e9bff4dc2a3095bae774a13e3e9dbf + w_download https://fpdownload.macromedia.com/get/shockwave/default/english/win95nt/latest/sw_lic_full_installer.msi 8e414c1a218157d2b83877fb0b6a5002c2e9bff4dc2a3095bae774a13e3e9dbf + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec /i sw_lic_full_installer.msi ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +# While this is an sdk, some apps require it (those needing sapi.dll), +# so keeping in the dll category +w_metadata speechsdk dlls \ + title="MS Speech SDK 5.1" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + conflicts="sapi" \ + file1="SpeechSDK51.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft Speech SDK 5.1/Bin/SAPI51SampleApp.exe" + +load_speechsdk() +{ + w_package_unsupported_win64 + + # https://www.microsoft.com/en-us/download/details.aspx?id=10121 + w_download https://web.archive.org/web/20110805062427/https://download.microsoft.com/download/B/4/3/B4314928-7B71-4336-9DE7-6FA4CF00B7B3/SpeechSDK51.exe 520aa5d1a72dc6f41dc9b8b88603228ffd5d5d6f696224fc237ec4828fe7f6e0 + + w_try_unzip "${W_TMP}" "${W_CACHE}"/speechsdk/SpeechSDK51.exe + + # Otherwise it only installs the SDK and not the redistributable: + w_set_winver win2k + + # Only added in wine-2.18 + for stub in "${W_SYSTEM32_DLLS}/Speech/Common/sapi.dll" "${W_SYSTEM64_DLLS}/Speech/Common/sapi.dll"; do + if [ -f "${stub}" ]; then + w_try rm "${stub}" + fi + done + + w_try_cd "${W_TMP}" + w_try "${WINE}" msiexec /i "Microsoft Speech SDK 5.1.msi" ${W_OPT_UNATTENDED:+/q} + + # If sapi.dll isn't in original location, applications won't start, see + # e.g., https://bugs.winehq.org/show_bug.cgi?id=43841 + mkdir -p "${W_SYSTEM32_DLLS}/Speech/Common/" + w_try ln -s "${W_COMMONFILES_X86}/Microsoft Shared/Speech/sapi.dll" "${W_SYSTEM32_DLLS}/Speech/Common" + + w_override_dlls native sapi + + # SAPI 5.1 doesn't work on vista and newer + w_set_winver winxp +} + +#---------------------------------------------------------------- + +w_metadata tabctl32 dlls \ + title="Microsoft Tabbed Dialog Control 6.0 (tabctl32.ocx)" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/tabctl32.ocx" + +load_tabctl32() +{ + helper_vb6sp6 "${W_TMP}" TabCtl32.ocx + w_try mv "${W_TMP}/TabCtl32.ocx" "${W_SYSTEM32_DLLS}/tabctl32.ocx" + w_try_regsvr tabctl32.ocx +} + +#---------------------------------------------------------------- + +w_metadata updspapi dlls \ + title="Windows Update Service API" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/updspapi.dll" + +load_updspapi() +{ + helper_winxpsp3 i386/update/updspapi.dll + w_try_cp_dll "${W_TMP}"/i386/update/updspapi.dll "${W_SYSTEM32_DLLS}" + + w_override_dlls native,builtin updspapi +} + +#---------------------------------------------------------------- + +w_metadata urlmon dlls \ + title="MS urlmon" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/urlmon.dll" + +load_urlmon() +{ + helper_win7sp1 x86_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_d1a4c8feac0dfcdb/urlmon.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_d1a4c8feac0dfcdb/urlmon.dll" "${W_SYSTEM32_DLLS}/urlmon.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_2dc36482646b6e11/urlmon.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_2dc36482646b6e11/urlmon.dll" "${W_SYSTEM64_DLLS}/urlmon.dll" + fi + + w_override_dlls native,builtin urlmon + + w_call iertutil +} + +#---------------------------------------------------------------- + +w_metadata usp10 dlls \ + title="Uniscribe" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/usp10.dll" + +load_usp10() +{ + helper_win7sp1 x86_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_af01e2f9b6be7939/usp10.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_af01e2f9b6be7939/usp10.dll" "${W_SYSTEM32_DLLS}/usp10.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_0b207e7d6f1bea6f/usp10.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_0b207e7d6f1bea6f/usp10.dll" "${W_SYSTEM64_DLLS}/usp10.dll" + fi + + w_override_dlls native,builtin usp10 +} + +#---------------------------------------------------------------- + +w_metadata vb2run dlls \ + title="MS Visual Basic 2 runtime" \ + publisher="Microsoft" \ + year="1993" \ + media="download" \ + file1="VBRUN200.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/VBRUN200.DLL" + +load_vb2run() +{ + # Not referenced on MS web anymore, but the old Microsoft Software Library FTP still has it. + # See ftp://ftp.microsoft.com/Softlib/index.txt + # 2014/05/31: Microsoft FTP is down ftp://$ftp_microsoft_com/Softlib/MSLFILES/VBRUN200.EXE + # 2015/08/10: chatnfiles is down, conradshome.com is up (and has a LOT of old MS installers archived!) + # 2018/11/15: now conradshome is down ,but quaddicted.com also has it (and a lot more) + w_download https://www.quaddicted.com/files/mirrors/ftp.planetquake.com/aoe/downloads/VBRUN200.EXE 4b0811d8fdcac1fd9411786c9119dc8d98d0540948211bdbc1ac682fbe5c0228 + w_try_unzip "${W_TMP}" "${W_CACHE}"/vb2run/VBRUN200.EXE + w_try_cp_dll "${W_TMP}/VBRUN200.DLL" "${W_SYSTEM32_DLLS}" +} + +#---------------------------------------------------------------- + +w_metadata vb3run dlls \ + title="MS Visual Basic 3 runtime" \ + publisher="Microsoft" \ + year="1998" \ + media="download" \ + file1="vb3run.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/Vbrun300.dll" + +load_vb3run() +{ + # See https://support.microsoft.com/kb/196285 + w_download https://download.microsoft.com/download/vb30/utility/1/w9xnt4/en-us/vb3run.exe 3ca3ad6332f83b5c2b86e4758afa400150f07ae66ce8b850d8f9d6bcd47ad4cd + w_try_unzip "${W_TMP}" "${W_CACHE}"/vb3run/vb3run.exe + w_try_cp_dll "${W_TMP}/Vbrun300.dll" "${W_SYSTEM32_DLLS}" +} + +#---------------------------------------------------------------- + +w_metadata vb4run dlls \ + title="MS Visual Basic 4 runtime" \ + publisher="Microsoft" \ + year="1998" \ + media="download" \ + file1="vb4run.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/Vb40032.dll" + +load_vb4run() +{ + # See https://support.microsoft.com/kb/196286 + w_download https://download.microsoft.com/download/vb40ent/sample27/1/w9xnt4/en-us/vb4run.exe 40931308b5a137f9ce3e9da9b43f4ca6688e18b523687cfea8be6cdffa3153fb + w_try_unzip "${W_TMP}" "${W_CACHE}"/vb4run/vb4run.exe + w_try_cp_dll "${W_TMP}/Vb40032.dll" "${W_SYSTEM32_DLLS}" + w_try_cp_dll "${W_TMP}/Vb40016.dll" "${W_SYSTEM32_DLLS}" +} + +#---------------------------------------------------------------- + +w_metadata vb5run dlls \ + title="MS Visual Basic 5 runtime" \ + publisher="Microsoft" \ + year="2001" \ + media="download" \ + file1="msvbvm50.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msvbvm50.dll" + +load_vb5run() +{ + w_download https://download.microsoft.com/download/vb50pro/utility/1/win98/en-us/msvbvm50.exe b5f8ea5b9d8b30822a2be2cdcb89cda99ec0149832659ad81f45360daa6e6965 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msvbvm50.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata vb6run dlls \ + title="MS Visual Basic 6 runtime sp6" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="vbrun60sp6.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msvbvm60.dll" + +load_vb6run() +{ + # https://support.microsoft.com/kb/290887 + if test ! -f "${W_CACHE}"/vb6run/vbrun60sp6.exe; then + w_download https://lon-01.lo4d.com/files/visual-basic-runtime-files/VB6.0-KB290887-X86.exe 467b5a10c369865f2021d379fc0933cb382146b702bbca4bcb703fc86f4322bb + + w_try "${WINE}" "${W_CACHE}"/vb6run/VB6.0-KB290887-X86.exe "/T:${W_TMP_WIN}" /c ${W_OPT_UNATTENDED:+/q} + if test ! -f "${W_TMP}"/vbrun60sp6.exe; then + w_die vbrun60sp6.exe not found + fi + w_try mv "${W_TMP}"/vbrun60sp6.exe "${W_CACHE}"/vb6run + fi + + # extract the files instead of using installer to avoid https://github.com/Winetricks/winetricks/issues/1806 + w_try_cabextract -L "${W_CACHE}/${W_PACKAGE}/${file1}" -d "${W_TMP}" + + for dll in asycfilt.dll comcat.dll msvbvm60.dll oleaut32.dll olepro32.dll stdole2.tlb; do + w_try mv "${W_TMP}/${dll}" "${W_SYSTEM32_DLLS}" + done +} + +#---------------------------------------------------------------- + +winetricks_vcrun6_helper() { + if test ! -f "${W_CACHE}"/vcrun6/vcredist.exe; then + w_download_to vcrun6 https://download.microsoft.com/download/vc60pro/Update/2/W9XNT4/EN-US/VC6RedistSetup_deu.exe c2eb91d9c4448d50e46a32fecbcc3b418706d002beab9b5f4981de552098cee7 + + w_try "${WINE}" "${W_CACHE}"/vcrun6/VC6RedistSetup_deu.exe "/T:${W_TMP_WIN}" /c ${W_OPT_UNATTENDED:+/q} + if test ! -f "${W_TMP}"/vcredist.exe; then + w_die vcredist.exe not found + fi + mv "${W_TMP}"/vcredist.exe "${W_CACHE}"/vcrun6 + fi +} + +w_metadata vcrun6 dlls \ + title="Visual C++ 6 SP4 libraries (mfc42, msvcp60, msvcirt)" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="VC6RedistSetup_deu.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc42.dll" + +load_vcrun6() +{ + # Load the Visual C++ 6 runtime libraries, including the elusive mfc42u.dll + winetricks_vcrun6_helper + + # extract the files instead of using installer to avoid https://github.com/Winetricks/winetricks/issues/1806 + w_try_cabextract "${W_CACHE}/${W_PACKAGE}/${file1}" -d "${W_TMP}" -F vcredist.exe + w_try_cabextract "${W_TMP}/vcredist.exe" -d "${W_TMP}" + + for dll in asycfilt.dll comcat.dll mfc42.dll mfc42u.dll msvcirt.dll msvcp60.dll msvcrt.dll oleaut32.dll olepro32.dll stdole2.tlb; do + w_try mv "${W_TMP}/${dll}" "${W_SYSTEM32_DLLS}" + done + + # atla.dll lbecomes atl.dll (note: atlu.dll is unused) + w_try mv "${W_TMP}/atla.dll" "${W_SYSTEM32_DLLS}/atl.dll" +} + +w_metadata mfc42 dlls \ + title="Visual C++ 6 SP4 mfc42 library; part of vcrun6" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="../vcrun6/VC6RedistSetup_deu.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc42u.dll" + +load_mfc42() +{ + winetricks_vcrun6_helper + + w_try_cabextract "${W_CACHE}"/vcrun6/vcredist.exe -d "${W_SYSTEM32_DLLS}" -F "mfc42*.dll" +} + +w_metadata msvcirt dlls \ + title="Visual C++ 6 SP4 msvcirt library; part of vcrun6" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="../vcrun6/VC6RedistSetup_deu.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msvcirt.dll" + +load_msvcirt() +{ + winetricks_vcrun6_helper + + w_try_cabextract "${W_CACHE}"/vcrun6/vcredist.exe -d "${W_SYSTEM32_DLLS}" -F msvcirt.dll +} + +#---------------------------------------------------------------- + +# FIXME: we don't currently have an install check that can distinguish +# between SP4 and SP6, it would have to check size or version of a file, +# or maybe a registry key. + +w_metadata vcrun6sp6 dlls \ + title="Visual C++ 6 SP6 libraries (with fixes in ATL and MFC)" \ + publisher="Microsoft" \ + year="2004" \ + media="download" \ + file1="VS6SP6.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc42.dll" + +load_vcrun6sp6() +{ + w_download https://www.ddsystem.com.br/update/setup/vb6+sp6/VS6SP6.EXE 7fa1d1778824b55a5fceb02f45c399b5d4e4dce7403661e67e587b5f455edbf3 + + # extract the files instead of using installer to avoid https://github.com/Winetricks/winetricks/issues/1806 + w_try_cabextract "${W_CACHE}/${W_PACKAGE}/${file1}" -d "${W_TMP}" -F vcredist.exe + w_try_cabextract "${W_TMP}/vcredist.exe" -d "${W_TMP}" + + for dll in asycfilt.dll comcat.dll mfc42.dll mfc42u.dll msvcirt.dll msvcp60.dll msvcrt.dll oleaut32.dll olepro32.dll stdole2.tlb; do + w_try mv "${W_TMP}/${dll}" "${W_SYSTEM32_DLLS}" + done + + # atla.dll lbecomes atl.dll (note: atlu.dll is unused) + w_try mv "${W_TMP}/atla.dll" "${W_SYSTEM32_DLLS}/atl.dll" +} + +#---------------------------------------------------------------- + +w_metadata vcrun2003 dlls \ + title="Visual C++ 2003 libraries (mfc71,msvcp71,msvcr71)" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="BZEditW32_1.6.5.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/msvcp71.dll" + +load_vcrun2003() +{ + # Sadly, I know of no Microsoft URL for these + # winetricks-test can't handle ${file1} in url since it does a raw parsing :/ + w_download https://sourceforge.net/projects/bzflag/files/bzedit%20win32/1.6.5/BZEditW32_1.6.5.exe 84d1bda5dbf814742898a2e1c0e4bc793e9bc1fba4b7a93d59a7ef12bd0fd802 + + w_try_7z "${W_SYSTEM32_DLLS}" "${W_CACHE}/vcrun2003/BZEditW32_1.6.5.exe" "mfc71.dll" "msvcp71.dll" "msvcr71.dll" -y +} + +w_metadata mfc71 dlls \ + title="Visual C++ 2003 mfc71 library; part of vcrun2003" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="BZEditW32_1.6.5.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc71.dll" + +load_mfc71() +{ + w_download_to vcrun2003 https://sourceforge.net/projects/bzflag/files/bzedit%20win32/1.6.5/BZEditW32_1.6.5.exe 84d1bda5dbf814742898a2e1c0e4bc793e9bc1fba4b7a93d59a7ef12bd0fd802 + + w_try_7z "${W_SYSTEM32_DLLS}" "${W_CACHE}/vcrun2003/BZEditW32_1.6.5.exe" "mfc71.dll" -y +} + +#---------------------------------------------------------------- + +# Temporary fix for bug 169 +# The | symbol in installed_file1 means "or". +# (Adding an installed_file2 would mean 'and'.) +# Perhaps we should test for one if winxp mode, and the other if win7 mode; +# if that becomes important to get right, we'll do something like +# "if installed_file1 is just the single char @, call test_installed_$verb" +# and then define that function here. +w_metadata vcrun2005 dlls \ + title="Visual C++ 2005 libraries (mfc80,msvcp80,msvcr80)" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="vcredist_x86.EXE" \ + installed_file1="c:/windows/winsxs/x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b/mfc80.dll|c:/windows/winsxs/x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef/mfc80.dll" + +load_vcrun2005() +{ + # 2011/06: Security update, see + # https://technet.microsoft.com/library/security/ms11-025 or + # https://support.microsoft.com/kb/2538242 + # Originally: 4ee4da0fe62d5fa1b5e80c6e6d88a4a2f8b3b140c35da51053d0d7b72a381d29 + # 2021/05/25: 8648c5fc29c44b9112fe52f9a33f80e7fc42d10f3b5b42b2121542a13e44adfd + w_download https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE 8648c5fc29c44b9112fe52f9a33f80e7fc42d10f3b5b42b2121542a13e44adfd + + # For native to be used, msvc* dlls must either be set to native only, OR + # set to native, builtin and remove wine's builtin manifest. Setting to native only breaks several apps, + # e.g., Dirac Codec and Ragnarok Online. + # For more info, see: + # https://bugs.winehq.org/show_bug.cgi?id=28225 + # https://bugs.winehq.org/show_bug.cgi?id=33604 + # https://bugs.winehq.org/show_bug.cgi?id=42859 + w_override_dlls native,builtin atl80 msvcm80 msvcp80 msvcr80 vcomp + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/q} + + if [ "${W_ARCH}" = "win64" ] ;then + # Originally: 0551a61c85b718e1fa015b0c3e3f4c4eea0637055536c00e7969286b4fa663e0 + # 2021/05/25: 4487570bd86e2e1aac29db2a1d0a91eb63361fcaac570808eb327cd4e0e2240d + w_download https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE 4487570bd86e2e1aac29db2a1d0a91eb63361fcaac570808eb327cd4e0e2240d + w_try "${WINE}" vcredist_x64.exe ${W_OPT_UNATTENDED:+/q} + fi +} + +w_metadata mfc80 dlls \ + title="Visual C++ 2005 mfc80 library; part of vcrun2005" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../vcrun2005/vcredist_x86.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc80.dll" + +load_mfc80() +{ + w_download_to vcrun2005 https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE 8648c5fc29c44b9112fe52f9a33f80e7fc42d10f3b5b42b2121542a13e44adfd + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2005/vcredist_x86.EXE -F 'vcredist.msi' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/vcredist.msi" + + w_try_cp_dll "${W_TMP}/win32"/mfc80.dll.8.0.50727.6195.9BAE13A2_E7AF_D6C3_FF1F_C8B3B9A1E18E "${W_SYSTEM32_DLLS}"/mfc80.dll + w_try_cp_dll "${W_TMP}/win32"/mfc80u.dll.8.0.50727.6195.9BAE13A2_E7AF_D6C3_FF1F_C8B3B9A1E18E "${W_SYSTEM32_DLLS}"/mfc80u.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm80.dll.8.0.50727.6195.9BAE13A2_E7AF_D6C3_FF1F_C8B3B9A1E18E "${W_SYSTEM32_DLLS}"/mfcm80.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm80u.dll.8.0.50727.6195.9BAE13A2_E7AF_D6C3_FF1F_C8B3B9A1E18E "${W_SYSTEM32_DLLS}"/mfcm80u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2005 https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE 4487570bd86e2e1aac29db2a1d0a91eb63361fcaac570808eb327cd4e0e2240d + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2005/vcredist_x64.EXE -F 'vcredist.msi' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/vcredist.msi" + + w_try_cp_dll "${W_TMP}/win64"/mfc80.dll.8.0.50727.6195.8731EA9C_B0D8_8F16_FF1F_C8B3B9A1E18E "${W_SYSTEM64_DLLS}"/mfc80.dll + w_try_cp_dll "${W_TMP}/win64"/mfc80u.dll.8.0.50727.6195.8731EA9C_B0D8_8F16_FF1F_C8B3B9A1E18E "${W_SYSTEM64_DLLS}"/mfc80u.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm80.dll.8.0.50727.6195.8731EA9C_B0D8_8F16_FF1F_C8B3B9A1E18E "${W_SYSTEM64_DLLS}"/mfcm80.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm80u.dll.8.0.50727.6195.8731EA9C_B0D8_8F16_FF1F_C8B3B9A1E18E "${W_SYSTEM64_DLLS}"/mfcm80u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2008 dlls \ + title="Visual C++ 2008 libraries (mfc90,msvcp90,msvcr90)" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="vcredist_x86.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Common Files/Microsoft Shared/VC/msdia90.dll" + +load_vcrun2008() +{ + # June 2011 security update, see + # https://technet.microsoft.com/library/security/ms11-025 or + # https://support.microsoft.com/kb/2538242 + # Originally: 6b3e4c51c6c0e5f68c8a72b497445af3dbf976394cbb62aa23569065c28deeb6 + # 2021/05/23: 8742bcbf24ef328a72d2a27b693cc7071e38d3bb4b9b44dec42aa3d2c8d61d92 + w_download https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe 8742bcbf24ef328a72d2a27b693cc7071e38d3bb4b9b44dec42aa3d2c8d61d92 + + # For native to be used, msvc* dlls must either be set to native only, OR + # set to native, builtin and remove wine's builtin manifest. Setting to native only breaks several apps, + # e.g., Dirac Codec and Ragnarok Online. + # For more info, see: + # https://bugs.winehq.org/show_bug.cgi?id=28225 + # https://bugs.winehq.org/show_bug.cgi?id=33604 + # https://bugs.winehq.org/show_bug.cgi?id=42859 + w_override_dlls native,builtin atl90 msvcm90 msvcp90 msvcr90 vcomp90 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # 2016/11/15: b811f2c047a3e828517c234bd4aa4883e1ec591d88fad21289ae68a6915a6665 + # 2021/05/23: c5e273a4a16ab4d5471e91c7477719a2f45ddadb76c7f98a38fa5074a6838654 + w_download https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe c5e273a4a16ab4d5471e91c7477719a2f45ddadb76c7f98a38fa5074a6838654 + w_try "${WINE}" vcredist_x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac +} + +w_metadata mfc90 dlls \ + title="Visual C++ 2008 mfc90 library; part of vcrun2008" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../vcrun2008/vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc90.dll" + +load_mfc90() +{ + w_download_to vcrun2008 https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe 8742bcbf24ef328a72d2a27b693cc7071e38d3bb4b9b44dec42aa3d2c8d61d92 + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2008/vcredist_x86.exe -F 'vc_red.cab' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/vc_red.cab" + + w_try_cp_dll "${W_TMP}/win32"/mfc90.dll.30729.6161.Microsoft_VC90_MFC_x86.QFE "${W_SYSTEM32_DLLS}"/mfc90.dll + w_try_cp_dll "${W_TMP}/win32"/mfc90u.dll.30729.6161.Microsoft_VC90_MFC_x86.QFE "${W_SYSTEM32_DLLS}"/mfc90u.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm90.dll.30729.6161.Microsoft_VC90_MFC_x86.QFE "${W_SYSTEM32_DLLS}"/mfcm90.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm90u.dll.30729.6161.Microsoft_VC90_MFC_x86.QFE "${W_SYSTEM32_DLLS}"/mfcm90u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2008 https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe c5e273a4a16ab4d5471e91c7477719a2f45ddadb76c7f98a38fa5074a6838654 + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2008/vcredist_x64.exe -F 'vc_red.cab' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/vc_red.cab" + + w_try_cp_dll "${W_TMP}/win64"/mfc90.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "${W_SYSTEM64_DLLS}"/mfc90.dll + w_try_cp_dll "${W_TMP}/win64"/mfc90u.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "${W_SYSTEM64_DLLS}"/mfc90u.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm90.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "${W_SYSTEM64_DLLS}"/mfcm90.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm90u.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "${W_SYSTEM64_DLLS}"/mfcm90u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2010 dlls \ + title="Visual C++ 2010 libraries (mfc100,msvcp100,msvcr100)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc100.dll" + +load_vcrun2010() +{ + # See https://www.microsoft.com/en-us/download/details.aspx?id=5555 + # Originally: 8162b2d665ca52884507ede19549e99939ce4ea4a638c537fa653539819138c8 + # 2021/04/24: 31d32fa39d52cac9a765a43660431f7a127eee784b54b2f5e2af3e2b763a1af8 + w_download https://download.microsoft.com/download/5/B/C/5BC5DBB3-652D-4DCE-B14A-475AB85EEF6E/vcredist_x86.exe 31d32fa39d52cac9a765a43660431f7a127eee784b54b2f5e2af3e2b763a1af8 + + w_override_dlls native,builtin msvcp100 msvcr100 vcomp100 atl100 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" vcredist_x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # https://www.microsoft.com/en-us/download/details.aspx?id=13523 + # Originally: c6cd2d3f0b11dc2a604ffdc4dd97861a83b77e21709ba71b962a47759c93f4c8 + # 2021/04/24: 2fddbc3aaaab784c16bc673c3bae5f80929d5b372810dbc28649283566d33255 + w_download https://download.microsoft.com/download/A/8/0/A80747C3-41BD-45DF-B505-E9710D2744E0/vcredist_x64.exe 2fddbc3aaaab784c16bc673c3bae5f80929d5b372810dbc28649283566d33255 + w_try "${WINE}" vcredist_x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac +} + +w_metadata mfc100 dlls \ + title="Visual C++ 2010 mfc100 library; part of vcrun2010" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../vcrun2010/vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc100u.dll" + +load_mfc100() +{ + w_download_to vcrun2010 https://download.microsoft.com/download/5/B/C/5BC5DBB3-652D-4DCE-B14A-475AB85EEF6E/vcredist_x86.exe 31d32fa39d52cac9a765a43660431f7a127eee784b54b2f5e2af3e2b763a1af8 + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2010/vcredist_x86.exe -F '*.cab' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/vc_red.cab" + + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc100_x86 "${W_SYSTEM32_DLLS}"/mfc100.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc100u_x86 "${W_SYSTEM32_DLLS}"/mfc100u.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm100_x86 "${W_SYSTEM32_DLLS}"/mfcm100.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm100u_x86 "${W_SYSTEM32_DLLS}"/mfcm100u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2010 https://download.microsoft.com/download/A/8/0/A80747C3-41BD-45DF-B505-E9710D2744E0/vcredist_x64.exe 2fddbc3aaaab784c16bc673c3bae5f80929d5b372810dbc28649283566d33255 + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2010/vcredist_x64.exe -F '*.cab' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/vc_red.cab" + + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc100_x64 "${W_SYSTEM64_DLLS}"/mfc100.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc100u_x64 "${W_SYSTEM64_DLLS}"/mfc100u.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm100_x64 "${W_SYSTEM64_DLLS}"/mfcm100.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm100u_x64 "${W_SYSTEM64_DLLS}"/mfcm100u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2012 dlls \ + title="Visual C++ 2012 libraries (atl110,mfc110,mfc110u,msvcp110,msvcr110,vcomp110)" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc110.dll" + +load_vcrun2012() +{ + # https://www.microsoft.com/en-us/download/details.aspx?id=30679 + w_download https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe b924ad8062eaf4e70437c8be50fa612162795ff0839479546ce907ffa8d6e386 + + w_override_dlls native,builtin atl110 msvcp110 msvcr110 vcomp110 + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" vcredist_x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # 2015/10/19: 681be3e5ba9fd3da02c09d7e565adfa078640ed66a0d58583efad2c1e3cc4064 + w_download https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe 681be3e5ba9fd3da02c09d7e565adfa078640ed66a0d58583efad2c1e3cc4064 + w_try "${WINE}" vcredist_x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac +} + +w_metadata mfc110 dlls \ + title="Visual C++ 2012 mfc110 library; part of vcrun2012" \ + publisher="Microsoft" \ + year="2012" \ + media="download" \ + file1="../vcrun2012/vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc110u.dll" + +load_mfc110() +{ + w_download_to vcrun2012 https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe b924ad8062eaf4e70437c8be50fa612162795ff0839479546ce907ffa8d6e386 + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2012/vcredist_x86.exe -F 'a3' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/a3" + + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc110_x86 "${W_SYSTEM32_DLLS}"/mfc110.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc110u_x86 "${W_SYSTEM32_DLLS}"/mfc110u.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm110_x86 "${W_SYSTEM32_DLLS}"/mfcm110.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm110u_x86 "${W_SYSTEM32_DLLS}"/mfcm110u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2012 https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe 681be3e5ba9fd3da02c09d7e565adfa078640ed66a0d58583efad2c1e3cc4064 + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2012/vcredist_x64.exe -F 'a3' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/a3" + + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc110_x64 "${W_SYSTEM64_DLLS}"/mfc110.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc110u_x64 "${W_SYSTEM64_DLLS}"/mfc110u.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm110_x64 "${W_SYSTEM64_DLLS}"/mfcm110.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm110u_x64 "${W_SYSTEM64_DLLS}"/mfcm110u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2013 dlls \ + title="Visual C++ 2013 libraries (mfc120,mfc120u,msvcp120,msvcr120,vcomp120)" \ + publisher="Microsoft" \ + year="2013" \ + media="download" \ + file1="vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc120.dll" + +load_vcrun2013() +{ + # https://support.microsoft.com/en-gb/help/3179560/update-for-visual-c-2013-and-visual-c-redistributable-package + # 2015/01/14: a22895e55b26202eae166838edbe2ea6aad00d7ea600c11f8a31ede5cbce2048 + # 2019/03/24: 89f4e593ea5541d1c53f983923124f9fd061a1c0c967339109e375c661573c17 + w_download https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe 89f4e593ea5541d1c53f983923124f9fd061a1c0c967339109e375c661573c17 + + w_override_dlls native,builtin atl120 msvcp120 msvcr120 vcomp120 + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" vcredist_x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # 2015/10/19: e554425243e3e8ca1cd5fe550db41e6fa58a007c74fad400274b128452f38fb8 + # 2019/03/24: 20e2645b7cd5873b1fa3462b99a665ac8d6e14aae83ded9d875fea35ffdd7d7e + w_download https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe 20e2645b7cd5873b1fa3462b99a665ac8d6e14aae83ded9d875fea35ffdd7d7e + w_try "${WINE}" vcredist_x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac +} + +w_metadata mfc120 dlls \ + title="Visual C++ 2013 mfc120 library; part of vcrun2013" \ + publisher="Microsoft" \ + year="2013" \ + media="download" \ + file1="../vcrun2013/vcredist_x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc120u.dll" + +load_mfc120() +{ + w_download_to vcrun2013 https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe 89f4e593ea5541d1c53f983923124f9fd061a1c0c967339109e375c661573c17 + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2013/vcredist_x86.exe -F 'a3' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/a3" + + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc120_x86 "${W_SYSTEM32_DLLS}"/mfc120.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfc120u_x86 "${W_SYSTEM32_DLLS}"/mfc120u.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm120_x86 "${W_SYSTEM32_DLLS}"/mfcm120.dll + w_try_cp_dll "${W_TMP}/win32"/F_CENTRAL_mfcm120u_x86 "${W_SYSTEM32_DLLS}"/mfcm120u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2013 https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe 20e2645b7cd5873b1fa3462b99a665ac8d6e14aae83ded9d875fea35ffdd7d7e + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2013/vcredist_x64.exe -F 'a3' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/a3" + + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc120_x64 "${W_SYSTEM64_DLLS}"/mfc120.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfc120u_x64 "${W_SYSTEM64_DLLS}"/mfc120u.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm120_x64 "${W_SYSTEM64_DLLS}"/mfcm120.dll + w_try_cp_dll "${W_TMP}/win64"/F_CENTRAL_mfcm120u_x64 "${W_SYSTEM64_DLLS}"/mfcm120u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2015 dlls \ + title="Visual C++ 2015 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll)" \ + publisher="Microsoft" \ + year="2015" \ + media="download" \ + conflicts="vcrun2017 vcrun2019" \ + file1="vc_redist.x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc140.dll" + +load_vcrun2015() +{ + # https://www.microsoft.com/en-us/download/details.aspx?id=48145 + # 2015/10/12: fdd1e1f0dcae2d0aa0720895eff33b927d13076e64464bb7c7e5843b7667cd14 + w_download https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe fdd1e1f0dcae2d0aa0720895eff33b927d13076e64464bb7c7e5843b7667cd14 + + w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-convert-l1-1-0 api-ms-win-crt-environment-l1-1-0 api-ms-win-crt-filesystem-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-multibyte-l1-1-0 api-ms-win-crt-process-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-string-l1-1-0 api-ms-win-crt-utility-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcr140 ucrtbase vcomp140 vcruntime140 + + if w_workaround_wine_bug 50894 "Working around failing wusa.exe lookup via C:\windows\SysNative"; then + w_set_winver winxp + fi + + # Setup will refuse to install ucrtbase because builtin's version number is higher, so manually replace it + # See https://bugs.winehq.org/show_bug.cgi?id=46317 + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2015/vc_redist.x86.exe -F 'a10' + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}/win32/a10" -F 'ucrtbase.dll' + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" vc_redist.x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # 2015/10/12: 5eea714e1f22f1875c1cb7b1738b0c0b1f02aec5ecb95f0fdb1c5171c6cd93a3 + w_download https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe 5eea714e1f22f1875c1cb7b1738b0c0b1f02aec5ecb95f0fdb1c5171c6cd93a3 + # Also replace 64-bit ucrtbase.dll + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2015/vc_redist.x64.exe -F 'a10' + w_try_cabextract --directory="${W_SYSTEM64_DLLS}" "${W_TMP}/win64/a10" -F 'ucrtbase.dll' + w_try "${WINE}" vc_redist.x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac + + w_set_winver 'default' +} + +w_metadata mfc140 dlls \ + title="Visual C++ 2015 mfc140 library; part of vcrun2015" \ + publisher="Microsoft" \ + year="2015" \ + media="download" \ + file1="../vcrun2015/vc_redist.x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc140u.dll" + +load_mfc140() +{ + w_download_to vcrun2015 https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe fdd1e1f0dcae2d0aa0720895eff33b927d13076e64464bb7c7e5843b7667cd14 + + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2015/vc_redist.x86.exe -F 'a11' + w_try_cabextract --directory="${W_TMP}/win32" "${W_TMP}/win32/a11" + + w_try_cp_dll "${W_TMP}/win32"/mfc140.dll "${W_SYSTEM32_DLLS}"/mfc140.dll + w_try_cp_dll "${W_TMP}/win32"/mfc140u.dll "${W_SYSTEM32_DLLS}"/mfc140u.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm140.dll "${W_SYSTEM32_DLLS}"/mfcm140.dll + w_try_cp_dll "${W_TMP}/win32"/mfcm140u.dll "${W_SYSTEM32_DLLS}"/mfcm140u.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_download_to vcrun2015 https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe 5eea714e1f22f1875c1cb7b1738b0c0b1f02aec5ecb95f0fdb1c5171c6cd93a3 + + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2015/vc_redist.x64.exe -F 'a11' + w_try_cabextract --directory="${W_TMP}/win64" "${W_TMP}/win64/a11" + + w_try_cp_dll "${W_TMP}/win64"/mfc140.dll "${W_SYSTEM64_DLLS}"/mfc140.dll + w_try_cp_dll "${W_TMP}/win64"/mfc140u.dll "${W_SYSTEM64_DLLS}"/mfc140u.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm140.dll "${W_SYSTEM64_DLLS}"/mfcm140.dll + w_try_cp_dll "${W_TMP}/win64"/mfcm140u.dll "${W_SYSTEM64_DLLS}"/mfcm140u.dll + fi +} + +#---------------------------------------------------------------- + +w_metadata vcrun2017 dlls \ + title="Visual C++ 2017 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,msvcp140_1.dll,msvcp140_2.dll,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll)" \ + publisher="Microsoft" \ + year="2017" \ + media="download" \ + conflicts="vcrun2015 vcrun2019" \ + file1="vc_redist.x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc140.dll" + +load_vcrun2017() +{ + # https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads + # 2017/10/02: 2da11e22a276be85970eaed255daf3d92af84e94142ec04252326a882e57303e + # 2019/03/17: 7355962b95d6a5441c304cd2b86baf37bc206f63349f4a02289bcfb69ef142d3 + # 2019/08/14: 54ad46ae80984aa48cae6361213692c96b3639e322730d28c7fb93b183c761da + w_download https://aka.ms/vs/15/release/vc_redist.x86.exe 54ad46ae80984aa48cae6361213692c96b3639e322730d28c7fb93b183c761da + + w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcp140_1 msvcp140_2 msvcr140 ucrtbase vcomp140 vcruntime140 + + if w_workaround_wine_bug 50894 "Working around failing wusa.exe lookup via C:\windows\SysNative"; then + w_set_winver winxp + fi + + # Setup will refuse to install ucrtbase because builtin's version number is higher, so manually replace it + # See https://bugs.winehq.org/show_bug.cgi?id=46317 + w_try_cabextract --directory="${W_TMP}/win32" "${W_CACHE}"/vcrun2017/vc_redist.x86.exe -F 'a10' + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}/win32/a10" -F 'ucrtbase.dll' + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" vc_redist.x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads + # 2017/10/02: 7434bf559290cccc3dd3624f10c9e6422cce9927d2231d294114b2f929f0e465 + # 2019/03/17: b192e143d55257a0a2f76be42e44ff8ee14014f3b1b196c6e59829b6b3ec453c + # 2019/08/14: 5b0cbb977f2f5253b1ebe5c9d30edbda35dbd68fb70de7af5faac6423db575b5 + w_download https://aka.ms/vs/15/release/vc_redist.x64.exe 5b0cbb977f2f5253b1ebe5c9d30edbda35dbd68fb70de7af5faac6423db575b5 + # Also replace 64-bit ucrtbase.dll + w_try_cabextract --directory="${W_TMP}/win64" "${W_CACHE}"/vcrun2017/vc_redist.x64.exe -F 'a10' + w_try_cabextract --directory="${W_SYSTEM64_DLLS}" "${W_TMP}/win64/a10" -F 'ucrtbase.dll' + w_try "${WINE}" vc_redist.x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata vcrun2019 dlls \ + title="Visual C++ 2015-2019 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,msvcp140_1,msvcp140_2,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll) (and vcruntime140_1.dll on win64)" \ + publisher="Microsoft" \ + year="2019" \ + media="download" \ + conflicts="vcrun2015 vcrun2017" \ + file1="vc_redist.x86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/mfc140.dll" + +load_vcrun2019() +{ + # https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads + # 2019/12/26: e59ae3e886bd4571a811fe31a47959ae5c40d87c583f786816c60440252cd7ec + # 2020/03/23: ac96016f1511ae3eb5ec9de04551146fe351b7f97858dcd67163912e2302f5d6 + # 2020/05/20: a06aac66734a618ab33c1522920654ddfc44fc13cafaa0f0ab85b199c3d51dc0 + # 2020/08/05: b4d433e2f66b30b478c0d080ccd5217ca2a963c16e90caf10b1e0592b7d8d519 + # 2020/10/03: caa38fd474164a38ab47ac1755c8ccca5ccfacfa9a874f62609e6439924e87ec + # 2020/11/13: 50a3e92ade4c2d8f310a2812d46322459104039b9deadbd7fdd483b5c697c0c8 + # 2021/03/09: 4521ed84b9b1679a706e719423d54ef5e413dc50dde1cf362232d7359d7e89c4 + # 2021/03/28: e830c313aa99656748f9d2ed582c28101eaaf75f5377e3fb104c761bf3f808b2 + # 2021/04/05: e830c313aa99656748f9d2ed582c28101eaaf75f5377e3fb104c761bf3f808b2 + # 2021/04/13: 14563755ac24a874241935ef2c22c5fce973acb001f99e524145113b2dc638c1 + # 2021/06/06: 91c21c93a88dd82e8ae429534dacbc7a4885198361eae18d82920c714e328cf9 + # 2021/08/26: 1acd8d5ea1cdc3eb2eb4c87be3ab28722d0825c15449e5c9ceef95d897de52fa + # 2021/10/23: 80c7969f4e05002a0cd820b746e0acb7406d4b85e52ef096707315b390927824 + # 2022/01/18: 4c6c420cf4cbf2c9c9ed476e96580ae92a97b2822c21329a2e49e8439ac5ad30 + + w_warn "ucrtbase.dll is no longer included in vcrun2019. For details see: https://github.com/Winetricks/winetricks/issues/1770" + + w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcp140_1 msvcp140_2 msvcr140 vcomp140 vcruntime140 + + w_download https://aka.ms/vs/16/release/vc_redist.x86.exe 4c6c420cf4cbf2c9c9ed476e96580ae92a97b2822c21329a2e49e8439ac5ad30 + + if w_workaround_wine_bug 50894 "Working around failing wusa.exe lookup via C:\windows\SysNative"; then + w_set_winver winxp + fi + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" vc_redist.x86.exe ${W_OPT_UNATTENDED:+/q} + + case "${W_ARCH}" in + win64) + # Also install the 64-bit version + # 2019/12/26: 40ea2955391c9eae3e35619c4c24b5aaf3d17aeaa6d09424ee9672aa9372aeed + # 2020/03/23: b6c82087a2c443db859fdbeaae7f46244d06c3f2a7f71c35e50358066253de52 + # 2020/05/20: 7d7105c52fcd6766beee1ae162aa81e278686122c1e44890712326634d0b055e + # 2020/08/05: 952a0c6cb4a3dd14c3666ef05bb1982c5ff7f87b7103c2ba896354f00651e358 + # 2020/10/03: 4b5890eb1aefdf8dfa3234b5032147eb90f050c5758a80901b201ae969780107 + # 2020/11/13: b1a32c71a6b7d5978904fb223763263ea5a7eb23b2c44a0d60e90d234ad99178 + # 2021/03/09: f299953673de262fefad9dd19bfbe6a5725a03ae733bebfec856f1306f79c9f7 + # 2021/03/28: b6c82087a2c443db859fdbeaae7f46244d06c3f2a7f71c35e50358066253de52 + # 2021/04/05: 015edd4e5d36e053b23a01adb77a2b12444d3fb6eccefe23e3a8cd6388616a16 + # 2021/04/13: 52b196bbe9016488c735e7b41805b651261ffa5d7aa86eb6a1d0095be83687b2 + # 2021/06/06: a1592d3da2b27230c087a3b069409c1e82c2664b0d4c3b511701624702b2e2a3 + # 2021/08/26: 003063723b2131da23f40e2063fb79867bae275f7b5c099dbd1792e25845872b + # 2021/10/23: 9b9dd72c27ab1db081de56bb7b73bee9a00f60d14ed8e6fde45dab3e619b5f04 + # 2022/01/18: 296f96cd102250636bcd23ab6e6cf70935337b1bbb3507fe8521d8d9cfaa932f + + # vcruntime140_1 is only shipped on x64: + w_override_dlls native,builtin vcruntime140_1 + + w_download https://aka.ms/vs/16/release/vc_redist.x64.exe 296f96cd102250636bcd23ab6e6cf70935337b1bbb3507fe8521d8d9cfaa932f + w_try "${WINE}" vc_redist.x64.exe ${W_OPT_UNATTENDED:+/q} + ;; + esac + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata vjrun20 dlls \ + title="MS Visual J# 2.0 SE libraries (requires dotnet20)" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="vjredist.exe" \ + installed_file1="c:/windows/Microsoft.NET/Framework/VJSharp/VJSharpSxS10.dll" + +load_vjrun20() +{ + w_package_unsupported_win64 + + w_call dotnet20 + + # See https://www.microsoft.com/en-us/download/details.aspx?id=18084 + w_download https://web.archive.org/web/20200803205240/https://download.microsoft.com/download/9/2/3/92338cd0-759f-4815-8981-24b437be74ef/vjredist.exe cf8f3dd4ad41453a302870b74de1c6489e7ed255ad3f652ce4af0b424a933b41 + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" vjredist.exe ${W_OPT_UNATTENDED:+/q /C:"install /qnt"} +} + +#---------------------------------------------------------------- + +w_metadata vstools2019 apps \ + title="MS Visual Studio Build Tools 2019" \ + publisher="Microsoft" \ + year="2019" \ + media="download" + +load_vstools2019() +{ + w_call dotnet472 + w_download https://aka.ms/vs/16/release/installer e653e715ddb8a08873e50a2fe091fca2ce77726b8b6ed2b99ed916d0e03c1fbe vstools2019.zip + w_try_unzip "${W_TMP}/vs_installer_16" "${W_CACHE}/${W_PACKAGE}/vstools2019.zip" + w_try "${WINE}" "${W_TMP}"/vs_installer_16/Contents/vs_installer.exe install \ + --channelId VisualStudio.16.Release \ + --channelUri "https://aka.ms/vs/16/release/channel" \ + --productId "Microsoft.VisualStudio.Product.BuildTools" \ + --add "Microsoft.VisualStudio.Workload.VCTools" \ + --includeRecommended \ + ${W_OPT_UNATTENDED:+--quiet} +} + +#---------------------------------------------------------------- + +w_metadata vulkanrt121412 dlls \ + title="Vulkan Runtime 1.2.141.2" \ + publisher="LunarG" \ + year="2020" \ + media="download" \ + file1="VulkanRT-1.2.141.2-Installer.exe" \ + installed_exe1="${W_SYSTEM32_DLLS_WIN}/vulkaninfo.exe" + +load_vulkanrt121412() +{ + # https://vulkan.lunarg.com/sdk/home + w_download "https://sdk.lunarg.com/sdk/download/1.2.141.2/windows/VulkanRT-1.2.141.2-Installer.exe?Human=true;u=" bf5050ead980e66fdd7b8eb5664d2b92e037ec5c400f75c2dc209a595828aaf7 "${file1}" + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata vulkansdk121412 apps \ + title="Vulkan SDK 1.2.141.2 (developers only)" \ + publisher="LunarG" \ + year="2020" \ + media="download" \ + file1="VulkanSDK-1.2.141.2-Installer.exe" \ + installed_file1="C:/VulkanSDK/1.2.141.2/vulkan.ico" \ + installed_file2="C:/windows/winevulkan.json" + +load_vulkansdk121412() +{ + _W_vulkan_version="${file1%-*.exe}" + _W_vulkan_version="${_W_vulkan_version#*-}" + # https://vulkan.lunarg.com/sdk/home + w_download "https://sdk.lunarg.com/sdk/download/1.2.141.2/windows/VulkanSDK-1.2.141.2-Installer.exe?Human=true;u=" d732eaee50c5f924ee64c9408bec7073b7a230464f1636f346833727c9bbddd0 "${file1}" + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} + echo "Creating C:\\windows\\winevulkan.json winevulkan json file" + cat > "${W_WINDIR_UNIX}"/winevulkan.json <<_EOF_ +{ + "file_format_version": "1.0.0", + "ICD": { + "library_path": "c:\\\\windows\\\\system32\\\\winevulkan.dll", + "api_version": "${_W_vulkan_version}" + } +} +_EOF_ + echo "Creating winevulkan registry settings" + cat > "${W_TMP}"/winevulkan.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers\\] +"C:\\\\Windows\\\\winevulkan.json"=dword:00000000 + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\winevulkan.reg +} + +#---------------------------------------------------------------- + +w_metadata webio dlls \ + title="MS Windows Web I/O" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/webio.dll" + +load_webio() +{ + helper_win7sp1 x86_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_5ef1a4093cf55387/webio.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_5ef1a4093cf55387/webio.dll" "${W_SYSTEM32_DLLS}/webio.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_bb103f8cf552c4bd/webio.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_bb103f8cf552c4bd/webio.dll" "${W_SYSTEM64_DLLS}/webio.dll" + fi + + w_override_dlls native,builtin webio +} + + +#---------------------------------------------------------------- + +w_metadata windowscodecs dlls \ + title="MS Windows Imaging Component" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="wic_x86_enu.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/WindowsCodecs.dll" + +load_windowscodecs() +{ + # Separate 32/64-bit installers: + if [ "${W_ARCH}" = "win32" ] ; then + # https://www.microsoft.com/en-us/download/details.aspx?id=32 + w_download https://web.archive.org/web/20200810071051if_/https://download.microsoft.com/download/f/f/1/ff178bb1-da91-48ed-89e5-478a99387d4f/wic_x86_enu.exe 196868b09d87ae04e4ab42b4a3e0abbb160500e8ff13deb38e2956ee854868b1 + EXE="wic_x86_enu.exe" + elif [ "${W_ARCH}" = "win64" ] ; then + # https://www.microsoft.com/en-us/download/details.aspx?id=1385 + w_download https://web.archive.org/web/20191125095535if_/http://download.microsoft.com/download/6/4/5/645fed5f-a6e7-44d9-9d10-fe83348796b0/wic_x64_enu.exe 5822fecd69a90c2833965a25e8779000825d69cc8c9250933f0ab70df52171e1 + EXE="wic_x64_enu.exe" + else + w_die "Invalid W_ARCH value, ${W_ARCH}" + fi + + # Avoid a file existence check. + w_try rm -f "${W_SYSTEM32_DLLS}"/windowscodecs.dll "${W_SYSTEM32_DLLS}"/windowscodecsext.dll "${W_SYSTEM32_DLLS}"/wmphoto.dll "${W_SYSTEM32_DLLS}"/photometadatahandler.dll + + if [ "${W_ARCH}" = "win64" ]; then + w_try rm -f "${W_SYSTEM64_DLLS}"/windowscodecs.dll "${W_SYSTEM64_DLLS}"/windowscodecsext.dll "${W_SYSTEM64_DLLS}"/wmphoto.dll "${W_SYSTEM64_DLLS}"/photometadatahandler.dll + fi + + # AF says in AppDB entry for .NET 3.0 that windowscodecs has to be native only + w_override_dlls native windowscodecs windowscodecsext + + # Previously this was winxp, but that didn't work for 64-bit, see https://github.com/Winetricks/winetricks/issues/970 + w_set_winver win2k3 + + # Always run the WIC installer in passive mode. + # See https://bugs.winehq.org/show_bug.cgi?id=16876 and + # https://bugs.winehq.org/show_bug.cgi?id=23232 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + if w_workaround_wine_bug 32859 "Working around possibly broken libX11"; then + # shellcheck disable=SC2086 + w_try ${W_TASKSET} "${WINE}" "${EXE}" /passive + else + w_try "${WINE}" "${EXE}" /passive + fi + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata winhttp dlls \ + title="MS Windows HTTP Services" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/winhttp.dll" + +load_winhttp() +{ + # 2017/10/12: Can't use win7's version, as that need webio.dll, which wants ntdll.EtwEventActivityIdControl. + # Should get that into wine{,-stable} so we can use win7 version in the long run + # See https://github.com/Winetricks/winetricks/issues/831 + + helper_win2ksp4 i386/new/winhttp.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/new/winhttp.dl_ + w_override_dlls native,builtin winhttp +} + +#---------------------------------------------------------------- + +w_metadata wininet dlls \ + title="MS Windows Internet API" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/wininet.dll" + +load_wininet() +{ + helper_win7sp1 x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_1eaaa4a07717236e/wininet.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_1eaaa4a07717236e/wininet.dll" "${W_SYSTEM32_DLLS}/wininet.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_7ac940242f7494a4/wininet.dll + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_7ac940242f7494a4/wininet.dll" "${W_SYSTEM64_DLLS}/wininet.dll" + fi + + w_override_dlls native,builtin wininet + + w_call iertutil +} + +#---------------------------------------------------------------- + +w_metadata wininet_win2k dlls \ + title="MS Windows Internet API" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="../win2ksp4/W2KSP4_EN.EXE" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/wininet.dll" + +load_wininet_win2k() +{ + helper_win2ksp4 i386/wininet.dl_ + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_TMP}"/i386/wininet.dl_ + + w_override_dlls native,builtin wininet +} + +#---------------------------------------------------------------- + +w_metadata wmi dlls \ + title="Windows Management Instrumentation (aka WBEM) Core 1.5" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="wmi9x.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/wbem/wbemcore.dll" + +load_wmi() +{ + w_package_unsupported_win64 + + # WMI for NT4.0 need validation: https://www.microsoft.com/en-us/download/details.aspx?id=7665 + # See also https://www.microsoft.com/en-us/download/details.aspx?id=16510 + # Originally at: https://download.microsoft.com/download/platformsdk/wmi9x/1.5/W9X/EN-US/wmi9x.exe + # Mirror list: https://filemare.com/en-us/search/wmi9x.exe/761569271 + # 2017/10/14: ftp://59.124.141.94 is dead, using ftp://82.162.138.211 + # 2018/06/03: ftp://82.162.138.211 is dead, moved to ftp://ftp.espe.edu.ec + # 2019/12/22: all ftp mirrors I found are dead, so use wayback machine for original MS url + w_download https://web.archive.org/web/20051221074940/https://download.microsoft.com/download/platformsdk/wmi9x/1.5/W9X/EN-US/wmi9x.exe 1d5d94050354b164c6a19531df151e0703d5eb39cebf4357ee2cfc340c2509d0 + + w_set_winver win98 + w_override_dlls native,builtin wbemprox wmiutils + + # Note: there is a crash in the background towards the end, doesn't seem to hurt; see https://bugs.winehq.org/show_bug.cgi?id=7920 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" wmi9x.exe ${W_OPT_UNATTENDED:+/S} + w_killall "WinMgmt.exe" + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata wmv9vcm dlls \ + title="MS Windows Media Video 9 Video Compression Manager" \ + publisher="Microsoft" \ + year="2013" \ + media="download" \ + file1="WindowsServer2003-WindowsMedia-KB2845142-x86-ENU.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/wmv9vcm.dll" + +load_wmv9vcm() +{ + # https://www.microsoft.com/en-us/download/details.aspx?id=39486 + # See also https://www.microsoft.com/en-us/download/details.aspx?id=6191 + w_download https://download.microsoft.com/download/2/8/D/28DA9C3E-6DA2-456F-BD33-1F937EB6E0FF/WindowsServer2003-WindowsMedia-KB2845142-x86-ENU.exe 51e11691339c1c817b12f92e613145ffcd7b6f7e869d994cc8dbc4591b24f155 + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_dll "${W_TMP}"/wm64/wmv9vcm.dll "${W_SYSTEM32_DLLS}" + + # Register codec: + cat > "${W_TMP}"/tmp.reg <<_EOF_ +REGEDIT4 +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32] +"vidc.WMV3"="wmv9vcm.dll" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\tmp.reg +} + +#---------------------------------------------------------------- + +w_metadata wsh57 dlls \ + title="MS Windows Script Host 5.7" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="scripten.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/scrrun.dll" + +load_wsh57() +{ + # See also https://www.microsoft.com/en-us/download/details.aspx?id=8247 + w_download https://download.microsoft.com/download/4/4/d/44de8a9e-630d-4c10-9f17-b9b34d3f6417/scripten.exe 63c781b9e50bfd55f10700eb70b5c571a9bedfd8d35af29f6a22a77550df5e7b + + w_try_cabextract -d "${W_SYSTEM32_DLLS}" "${W_CACHE}"/wsh57/scripten.exe + + # Wine doesn't provide the other dll's (yet?) + w_override_dlls native,builtin jscript scrrun vbscript cscript.exe wscript.exe + w_try_regsvr dispex.dll jscript.dll scrobj.dll scrrun.dll vbscript.dll wshcon.dll wshext.dll +} + +#---------------------------------------------------------------- + +w_metadata xact dlls \ + title="MS XACT Engine (32-bit only)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/xactengine2_0.dll" + +load_xact() +{ + helper_directx_Jun2010 + + # Extract xactengine?_?.dll, X3DAudio?_?.dll, xaudio?_?.dll, xapofx?_?.dll + w_try_cabextract -d "${W_TMP}" -L -F '*_xact_*x86*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + w_try_cabextract -d "${W_TMP}" -L -F '*_x3daudio_*x86*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + w_try_cabextract -d "${W_TMP}" -L -F '*_xaudio_*x86*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + + for x in "${W_TMP}"/*.cab ; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'xactengine*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'xaudio*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'x3daudio*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'xapofx*.dll' "${x}" + done + + # Don't install 64-bit xact DLLs by default. They are broken in Wine, see: + # https://bugs.winehq.org/show_bug.cgi?id=41618#c5 + + w_override_dlls native,builtin xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7 + w_override_dlls native,builtin x3daudio1_0 x3daudio1_1 x3daudio1_2 x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 x3daudio1_7 + w_override_dlls native,builtin xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 xapofx1_5 + + # Register xactengine?_?.dll + for x in "${W_SYSTEM32_DLLS}"/xactengine* ; do + w_try_regsvr "$(basename "${x}")" + done + + # and xaudio?_?.dll, but not xaudio2_8 (unsupported) + for x in 0 1 2 3 4 5 6 7 ; do + w_try_regsvr "$(basename "${W_SYSTEM32_DLLS}/xaudio2_${x}")" + done +} + +#---------------------------------------------------------------- + +w_metadata xact_x64 dlls \ + title="MS XACT Engine (64-bit only)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_Jun2010_redist.exe" \ + installed_file1="${W_SYSTEM64_DLLS_WIN64:-does_not_exist}/xactengine2_0.dll" + +load_xact_x64() +{ + w_package_unsupported_win32 + if w_workaround_wine_bug 41618; then + w_warn "While this helps some games, it completely breaks others. You've been warned." + fi + + helper_directx_Jun2010 + + # Extract xactengine?_?.dll, X3DAudio?_?.dll, xaudio?_?.dll, xapofx?_?.dll + w_try_cabextract -d "${W_TMP}" -L -F '*_xact_*x64*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + w_try_cabextract -d "${W_TMP}" -L -F '*_x3daudio_*x64*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + w_try_cabextract -d "${W_TMP}" -L -F '*_xaudio_*x64*' "${W_CACHE}/directx9/${DIRECTX_NAME}" + + for x in "${W_TMP}"/*.cab ; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'xactengine*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'xaudio*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'x3daudio*.dll' "${x}" + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'xapofx*.dll' "${x}" + done + + w_override_dlls native,builtin xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7 + w_override_dlls native,builtin x3daudio1_0 x3daudio1_1 x3daudio1_2 x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 x3daudio1_7 + w_override_dlls native,builtin xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 xapofx1_5 + + # Register xactengine?_?.dll + for x in "${W_SYSTEM64_DLLS}"/xactengine* ; do + w_try_regsvr64 "$(basename "${x}")" + done + + # and xaudio?_?.dll, but not xaudio2_8 (unsupported) + for x in 0 1 2 3 4 5 6 7 ; do + w_try_regsvr64 "$(basename "${W_SYSTEM64_DLLS}/xaudio2_${x}")" + done +} + +#---------------------------------------------------------------- + +w_metadata xinput dlls \ + title="Microsoft XInput (Xbox controller support)" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/xinput1_1.dll" + +load_xinput() +{ + helper_directx_Jun2010 + + w_try_cabextract -d "${W_TMP}" -L -F '*_xinput_*x86*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*.cab; do + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F 'xinput*.dll' "${x}" + done + if test "${W_ARCH}" = "win64"; then + w_try_cabextract -d "${W_TMP}" -L -F '*_xinput_*x64*' "${W_CACHE}"/directx9/${DIRECTX_NAME} + for x in "${W_TMP}"/*x64.cab; do + w_try_cabextract -d "${W_SYSTEM64_DLLS}" -L -F 'xinput*.dll' "${x}" + done + fi + w_override_dlls native xinput1_1 + w_override_dlls native xinput1_2 + w_override_dlls native xinput1_3 + w_override_dlls native xinput9_1_0 +} + +#---------------------------------------------------------------- + +w_metadata xmllite dlls \ + title="MS xmllite dll" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="../win7sp1/windows6.1-KB976932-X86.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/xmllite.dll" + +load_xmllite() +{ + helper_win7sp1 x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/xmllite.dll + w_try_cp_dll "${W_TMP}/x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/xmllite.dll" "${W_SYSTEM32_DLLS}/xmllite.dll" + + if [ "${W_ARCH}" = "win64" ]; then + helper_win7sp1_x64 amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/xmllite.dll "${W_SYSTEM64_DLLS}/xmllite.dll" + w_try_cp_dll "${W_TMP}/amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/xmllite.dll" "${W_SYSTEM64_DLLS}/xmllite.dll" + fi + + w_override_dlls native,builtin xmllite +} + +#---------------------------------------------------------------- + +w_metadata xna31 dlls \ + title="MS XNA Framework Redistributable 3.1" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="xnafx31_redist.msi" \ + installed_file1="C:/windows/assembly/GAC_32/Microsoft.Xna.Framework.Game/3.1.0.0__6d5c3888ef60e27d/Microsoft.Xna.Framework.Game.dll" + +load_xna31() +{ + w_call dotnet20sp2 + w_download https://web.archive.org/web/20120325004645/https://download.microsoft.com/download/5/9/1/5912526C-B950-4662-99B6-119A83E60E5C/xnafx31_redist.msi 187e7e6b08fe35428d945612a7d258bfed25fad53cc54882983abdc73fe60f91 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec ${W_OPT_UNATTENDED:+/quiet} /i "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata xna40 dlls \ + title="MS XNA Framework Redistributable 4.0" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="xnafx40_redist.msi" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Common Files/Microsoft Shared/XNA/Framework/v4.0/XnaNative.dll" + +load_xna40() +{ + if w_workaround_wine_bug 30718; then + export COMPlus_OnlyUseLatestCLR=1 + w_call dotnet40 + fi + + # https://www.microsoft.com/en-us/download/details.aspx?id=20914 + w_download https://web.archive.org/web/20120325002813/https://download.microsoft.com/download/A/C/2/AC2C903B-E6E8-42C2-9FD7-BEBAC362A930/xnafx40_redist.msi e6c41d692ebcba854dad4b1c52bb7ddd05926bad3105595d6596b8bab01c25e7 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" msiexec ${W_OPT_UNATTENDED:+/quiet} /i "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata xvid dlls \ + title="Xvid Video Codec" \ + publisher="xvid.org" \ + year="2009" \ + media="download" \ + file1="Xvid-1.3.2-20110601.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Xvid/xvid.ico" + +load_xvid() +{ + w_call vcrun6 + w_download http://www.koepi.info/Xvid-1.3.2-20110601.exe 74b23965cebe59e388eab6dba224b6b751ef4519454cc12086ade51c81f0a33c + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ --mode unattended --decode_divx 1 --decode_3ivx 1 --decode_other 1} +} + +####################### +# fonts +####################### + +w_metadata baekmuk fonts \ + title="Baekmuk Korean fonts" \ + publisher="Wooderart Inc. / kldp.net" \ + year="1999" \ + media="download" \ + file1="fonts-baekmuk_2.2.orig.tar.gz" \ + installed_file1="${W_FONTSDIR_WIN}/batang.ttf" + +load_baekmuk() +{ + # See http://kldp.net/projects/baekmuk for project page + # Need to download from Debian as the project page has unique captcha tokens per visitor + w_download "https://deb.debian.org/debian/pool/main/f/fonts-baekmuk/fonts-baekmuk_2.2.orig.tar.gz" 08ab7dffb55d5887cc942ce370f5e33b756a55fbb4eaf0b90f244070e8d51882 + + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${file1}" baekmuk-ttf-2.2/ttf + w_try_cp_font_files baekmuk-ttf-2.2/ttf/ "${W_FONTSDIR_UNIX}" + w_register_font batang.ttf "Baekmuk Batang" + w_register_font gulim.ttf "Baekmuk Gulim" + w_register_font dotum.ttf "Baekmuk Dotum" + w_register_font hline.ttf "Baekmuk Headline" +} + +#---------------------------------------------------------------- + +w_metadata cjkfonts fonts \ + title="All Chinese, Japanese, Korean fonts and aliases" \ + publisher="Various" \ + date="1999-2019" \ + media="download" + +load_cjkfonts() +{ + w_call fakechinese + w_call fakejapanese + w_call fakekorean + w_call unifont +} + +#---------------------------------------------------------------- + +w_metadata calibri fonts \ + title="MS Calibri font" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/calibri.ttf" + +load_calibri() +{ + helper_pptfonts "CALIBRI*.TTF" + w_register_font calibri.ttf "Calibri" + w_register_font calibrib.ttf "Calibri Bold" + w_register_font calibrii.ttf "Calibri Italic" + w_register_font calibriz.ttf "Calibri Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata cambria fonts \ + title="MS Cambria font" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/cambria.ttc" + +load_cambria() +{ + helper_pptfonts "CAMBRIA*.TT*" + w_register_font cambria.ttc "Cambria & Cambria Math" + w_register_font cambriab.ttf "Cambria Bold" + w_register_font cambriai.ttf "Cambria Italic" + w_register_font cambriaz.ttf "Cambria Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata candara fonts \ + title="MS Candara font" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/candara.ttf" + +load_candara() +{ + helper_pptfonts "CANDARA*.TTF" + w_register_font candara.ttf "Candara" + w_register_font candarab.ttf "Candara Bold" + w_register_font candarai.ttf "Candara Italic" + w_register_font candaraz.ttf "Candara Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata consolas fonts \ + title="MS Consolas console font" \ + publisher="Microsoft" \ + year="2011" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/consola.ttf" + +load_consolas() +{ + helper_pptfonts "CONSOLA*.TTF" + w_register_font consola.ttf "Consolas" + w_register_font consolab.ttf "Consolas Bold" + w_register_font consolai.ttf "Consolas Italic" + w_register_font consolaz.ttf "Consolas Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata constantia fonts \ + title="MS Constantia font" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/constan.ttf" + +load_constantia() +{ + helper_pptfonts "CONSTAN*.TTF" + w_register_font constan.ttf "Constantia" + w_register_font constanb.ttf "Constantia Bold" + w_register_font constani.ttf "Constantia Italic" + w_register_font constanz.ttf "Constantia Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata corbel fonts \ + title="MS Corbel font" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/corbel.ttf" + +load_corbel() +{ + helper_pptfonts "CORBEL*.TTF" + w_register_font corbel.ttf "Corbel" + w_register_font corbelb.ttf "Corbel Bold" + w_register_font corbeli.ttf "Corbel Italic" + w_register_font corbelz.ttf "Corbel Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata meiryo fonts \ + title="MS Meiryo font" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + conflicts="fakejapanese_vlgothic" \ + file1="PowerPointViewer.exe" \ + installed_file1="${W_FONTSDIR_WIN}/meiryo.ttc" + +load_meiryo() +{ + helper_pptfonts "MEIRYO*.TTC" + w_register_font meiryo.ttc "Meiryo & Meiryo Italic & Meiryo UI & Meiryo UI Italic" + w_register_font meiryob.ttc "Meiryo Bold & Meiryo Bold Italic & Meiryo UI Bold & Meiryo UI Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata pptfonts fonts \ + title="All MS PowerPoint Viewer fonts" \ + publisher="various" \ + date="2007-2009" \ + media="download" + +load_pptfonts() +{ + w_call calibri + w_call cambria + w_call candara + w_call consolas + w_call constantia + w_call corbel + w_call meiryo +} + +helper_pptfonts() +{ + # download PowerPointViewer, extract the given files, and copy them to $W_FONTSDIR_UNIX + # Font registration should still be done by the respective verbs + # $1 - font pattern to extract + + pptfont="$1" + w_download_to PowerPointViewer "https://web.archive.org/web/20171225132744if_/https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423 + w_try_cabextract -d "${W_TMP}" -F "ppviewer.cab" "${W_CACHE}/PowerPointViewer/PowerPointViewer.exe" + w_try_cabextract -d "${W_TMP}" -F "${pptfont}" "${W_TMP}/ppviewer.cab" + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "${pptfont}" +} + +#---------------------------------------------------------------- + +w_metadata andale fonts \ + title="MS Andale Mono font" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="andale32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/andalemo.ttf" + +load_andale() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/andale32.exe" 0524fe42951adc3a7eb870e32f0920313c71f170c859b5f770d82b4ee111e970 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/andale32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "AndaleMo.TTF" + w_register_font andalemo.ttf "Andale Mono" +} + +#---------------------------------------------------------------- + +w_metadata arial fonts \ + title="MS Arial / Arial Black fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="arial32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/arial.ttf" + +load_arial() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/arial32.exe" 85297a4d146e9c87ac6f74822734bdee5f4b2a722d7eaa584b7f2cbf76f478f6 + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/arialb32.exe" a425f0ffb6a1a5ede5b979ed6177f4f4f4fdef6ae7c302a7b7720ef332fec0a8 + + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/arial32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Arial*.TTF" + w_register_font arialbd.ttf "Arial Bold" + w_register_font arialbi.ttf "Arial Bold Italic" + w_register_font ariali.ttf "Arial Italic" + w_register_font arial.ttf "Arial" + + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/arialb32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "AriBlk.TTF" + w_register_font ariblk.ttf "Arial Black" +} + +#---------------------------------------------------------------- + +w_metadata comicsans fonts \ + title="MS Comic Sans fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="comic32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/comic.ttf" + +load_comicsans() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/comic32.exe" 9c6df3feefde26d4e41d4a4fe5db2a89f9123a772594d7f59afd062625cd204e + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/comic32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Comic*.TTF" + w_register_font comicbd.ttf "Comic Sans MS Bold" + w_register_font comic.ttf "Comic Sans MS" +} + +#---------------------------------------------------------------- + +w_metadata courier fonts \ + title="MS Courier fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="courie32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/cour.ttf" +load_courier() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/courie32.exe" bb511d861655dde879ae552eb86b134d6fae67cb58502e6ff73ec5d9151f3384 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/courie32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "cour*.ttf" + w_register_font courbd.ttf "Courier New Bold" + w_register_font courbi.ttf "Courier New Bold Italic" + w_register_font couri.ttf "Courier New Italic" + w_register_font cour.ttf "Courier New" +} + +#---------------------------------------------------------------- + +w_metadata georgia fonts \ + title="MS Georgia fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="georgi32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/georgia.ttf" +load_georgia() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/georgi32.exe" 2c2c7dcda6606ea5cf08918fb7cd3f3359e9e84338dc690013f20cd42e930301 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/georgi32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Georgia*.TTF" + w_register_font georgiab.ttf "Georgia Bold" + w_register_font georgiai.ttf "Georgia Italic" + w_register_font georgia.ttf "Georgia" + w_register_font georgiaz.ttf "Georgia Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata impact fonts \ + title="MS Impact fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="impact32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/impact.ttf" + +load_impact() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/impact32.exe" 6061ef3b7401d9642f5dfdb5f2b376aa14663f6275e60a51207ad4facf2fccfb + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/impact32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Impact.TTF" + w_register_font impact.ttf "Impact" +} + +#---------------------------------------------------------------- + +w_metadata times fonts \ + title="MS Times fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="times32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/times.ttf" + +load_times() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/times32.exe" db56595ec6ef5d3de5c24994f001f03b2a13e37cee27bc25c58f6f43e8f807ab + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/times32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Times*.TTF" + w_register_font timesbd.ttf "Times New Roman Bold" + w_register_font timesbi.ttf "Times New Roman Bold Italic" + w_register_font timesi.ttf "Times New Roman Italic" + w_register_font times.ttf "Times New Roman" +} + +#---------------------------------------------------------------- + +w_metadata trebuchet fonts \ + title="MS Trebuchet fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="trebuchet32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/trebuc.ttf" + +load_trebuchet() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/trebuc32.exe" 5a690d9bb8510be1b8b4fe49f1f2319651fe51bbe54775ddddd8ef0bd07fdac9 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/trebuc32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "[tT]rebuc*.ttf" + w_register_font trebucbd.ttf "Trebuchet MS Bold" + w_register_font trebucbi.ttf "Trebuchet MS Bold Italic" + w_register_font trebucit.ttf "Trebuchet MS Italic" + w_register_font trebuc.ttf "Trebuchet MS" +} + +#---------------------------------------------------------------- + +w_metadata verdana fonts \ + title="MS Verdana fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="verdan32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/verdana.ttf" + +load_verdana() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/verdan32.exe" c1cb61255e363166794e47664e2f21af8e3a26cb6346eb8d2ae2fa85dd5aad96 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/verdan32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Verdana*.TTF" + w_register_font verdanab.ttf "Verdana Bold" + w_register_font verdanai.ttf "Verdana Italic" + w_register_font verdana.ttf "Verdana" + w_register_font verdanaz.ttf "Verdana Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata webdings fonts \ + title="MS Webdings fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="webdin32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/webdings.ttf" + +load_webdings() +{ + w_download_to corefonts "https://mirrors.kernel.org/gentoo/distfiles/webdin32.exe" 64595b5abc1080fba8610c5c34fab5863408e806aafe84653ca8575bed17d75a + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/corefonts/webdin32.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "Webdings.TTF" + w_register_font webdings.ttf "Webdings" +} + +#---------------------------------------------------------------- + +w_metadata corefonts fonts \ + title="MS Arial, Courier, Times fonts" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="arial32.exe" \ + installed_file1="${W_FONTSDIR_WIN}/corefonts.installed" + +load_corefonts() +{ + # Natively installed versions of these fonts will cause the installers + # to exit silently. Because there are apps out there that depend on the + # files being present in the Windows font directory we use cabextract + # to obtain the files and register the fonts by hand. + + w_call andale + w_call arial + w_call comicsans + w_call courier + w_call georgia + w_call impact + w_call times + w_call trebuchet + w_call verdana + w_call webdings + + touch "${W_FONTSDIR_UNIX}/corefonts.installed" +} + +#---------------------------------------------------------------- + +w_metadata droid fonts \ + title="Droid fonts" \ + publisher="Ascender Corporation" \ + year="2009" \ + media="download" \ + file1="DroidSans-Bold.ttf" \ + installed_file1="${W_FONTSDIR_WIN}/droidsans-bold.ttf" + +do_droid() { + w_download "${_W_droid_url}${1}?raw=true" "$3" "$1" + w_try_cp_font_files "${W_CACHE}/droid" "${W_FONTSDIR_UNIX}" "$1" + w_register_font "$(echo "$1" | tr "[:upper:]" "[:lower:]")" "$2" +} + +load_droid() +{ + # See https://en.wikipedia.org/wiki/Droid_(font) + # Old URL was http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=data/fonts/' + # Then it was https://github.com/android/platform_frameworks_base/blob/master/data/fonts/ + # but the fonts are no longer in master. Using an older commit instead: + _W_droid_url="https://github.com/android/platform_frameworks_base/blob/feef9887e8f8eb6f64fc1b4552c02efb5755cdc1/data/fonts/" + + do_droid DroidSans-Bold.ttf "Droid Sans Bold" 2f529a3e60c007979d95d29794c3660694217fb882429fb33919d2245fe969e9 + do_droid DroidSansFallback.ttf "Droid Sans Fallback" 05d71b179ef97b82cf1bb91cef290c600a510f77f39b4964359e3ef88378c79d + do_droid DroidSansJapanese.ttf "Droid Sans Japanese" 935867c21b8484c959170e62879460ae9363eae91f9b35e4519d24080e2eac30 + do_droid DroidSansMono.ttf "Droid Sans Mono" 12b552de765dc1265d64f9f5566649930dde4dba07da0251d9f92801e70a1047 + do_droid DroidSans.ttf "Droid Sans" f51b88945f4c1b236f44b8d55a2d304316869127e95248c435c23f1e4142a7db + do_droid DroidSerif-BoldItalic.ttf "Droid Serif Bold Italic" 3fdf15b911c04317e5881ae1e4b9faefcdc4bf4cfb60223597d5c9455c3e4156 + do_droid DroidSerif-Bold.ttf "Droid Serif Bold" d28533eed8368f047eb5f57a88a91ba2ffc8b69a2dec5e50fe3f0c11ae3f4d8e + do_droid DroidSerif-Italic.ttf "Droid Serif Italic" 8a55a4823886234792991dd304dfa1fa120ae99483ec6c2255597d7d913b9a55 + do_droid DroidSerif-Regular.ttf "Droid Serif" 22aea9471bea5bce1ec3bf7136c84f075b3d11cf09dffdc3dba05e570094cbde + + unset _W_droid_url +} + +#---------------------------------------------------------------- + +w_metadata eufonts fonts \ + title="Updated fonts for Romanian and Bulgarian" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="EUupdate.EXE" \ + installed_file1="${W_FONTSDIR_WIN}/trebucbd.ttf" + +load_eufonts() +{ + # https://www.microsoft.com/en-us/download/details.aspx?id=16083 + # Previously at https://download.microsoft.com/download/a/1/8/a180e21e-9c2b-4b54-9c32-bf7fd7429970/EUupdate.EXE + # 2020/09/11: https://sourceforge.net/projects/mscorefonts2/files/cabs/EUupdate.EXE + w_download "https://sourceforge.net/projects/mscorefonts2/files/cabs/EUupdate.EXE" 464dd2cd5f09f489f9ac86ea7790b7b8548fc4e46d9f889b68d2cdce47e09ea8 + w_try_cabextract -d "${W_TMP}" "${W_CACHE}"/eufonts/EUupdate.EXE + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" + + w_register_font arialbd.ttf "Arial Bold" + w_register_font arialbi.ttf "Arial Bold Italic" + w_register_font ariali.ttf "Arial Italic" + w_register_font arial.ttf "Arial" + w_register_font timesbd.ttf "Times New Roman Bold" + w_register_font timesbi.ttf "Times New Roman Bold Italic" + w_register_font timesi.ttf "Times New Roman Italic" + w_register_font times.ttf "Times New Roman" + w_register_font trebucbd.ttf "Trebuchet MS Bold" + w_register_font trebucbi.ttf "Trebuchet MS Bold Italic" + w_register_font trebucit.ttf "Trebuchet MS Italic" + w_register_font trebuc.ttf "Trebuchet MS" + w_register_font verdanab.ttf "Verdana Bold" + w_register_font verdanai.ttf "Verdana Italian" + w_register_font verdana.ttf "Verdana" + w_register_font verdanaz.ttf "Verdana Bold Italic" +} + +#---------------------------------------------------------------- + +w_metadata fakechinese fonts \ + title="Creates aliases for Chinese fonts using Source Han Sans fonts" \ + publisher="Adobe" \ + year="2019" + +load_fakechinese() +{ + # Loads Source Han Sans fonts and sets aliases for Microsoft Chinese fonts + # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts + w_call sourcehansans + + # Simplified Chinese + w_register_font_replacement "Dengxian" "Source Han Sans SC" + w_register_font_replacement "FangSong" "Source Han Sans SC" + w_register_font_replacement "KaiTi" "Source Han Sans SC" + w_register_font_replacement "Microsoft YaHei" "Source Han Sans SC" + w_register_font_replacement "Microsoft YaHei UI" "Source Han Sans SC" + w_register_font_replacement "NSimSun" "Source Han Sans SC" + w_register_font_replacement "SimHei" "Source Han Sans SC" + w_register_font_replacement "SimKai" "Source Han Sans SC" + w_register_font_replacement "SimSun" "Source Han Sans SC" + w_register_font_replacement "SimSun-ExtB" "Source Han Sans SC" + + # Traditional Chinese + w_register_font_replacement "DFKai-SB" "Source Han Sans TC" + w_register_font_replacement "Microsoft JhengHei" "Source Han Sans TC" + w_register_font_replacement "Microsoft JhengHei UI" "Source Han Sans TC" + w_register_font_replacement "MingLiU" "Source Han Sans TC" + w_register_font_replacement "PMingLiU" "Source Han Sans TC" + w_register_font_replacement "MingLiU-ExtB" "Source Han Sans TC" + w_register_font_replacement "PMingLiU-ExtB" "Source Han Sans TC" +} + +#---------------------------------------------------------------- + +w_metadata fakejapanese fonts \ + title="Creates aliases for Japanese fonts using Source Han Sans fonts" \ + publisher="Adobe" \ + year="2019" + +load_fakejapanese() +{ + # Loads Source Han Sans fonts and sets aliases for Microsoft Japanese fonts + # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts + w_call sourcehansans + + w_register_font_replacement "Meiryo" "Source Han Sans" + w_register_font_replacement "Meiryo UI" "Source Han Sans" + w_register_font_replacement "MS Gothic" "Source Han Sans" + w_register_font_replacement "MS PGothic" "Source Han Sans" + w_register_font_replacement "MS Mincho" "Source Han Sans" + w_register_font_replacement "MS PMincho" "Source Han Sans" + w_register_font_replacement "MS UI Gothic" "Source Han Sans" + w_register_font_replacement "UD Digi KyoKasho N-R" "Source Han Sans" + w_register_font_replacement "UD Digi KyoKasho NK-R" "Source Han Sans" + w_register_font_replacement "UD Digi KyoKasho NP-R" "Source Han Sans" + w_register_font_replacement "Yu Gothic" "Source Han Sans" + w_register_font_replacement "Yu Gothic UI" "Source Han Sans" + w_register_font_replacement "Yu Mincho" "Source Han Sans" + w_register_font_replacement "メイリオ" "Source Han Sans" + w_register_font_replacement "MS ゴシック" "Source Han Sans" + w_register_font_replacement "MS Pゴシック" "Source Han Sans" + w_register_font_replacement "MS 明朝" "Source Han Sans" + w_register_font_replacement "MS P明朝" "Source Han Sans" +} + +#---------------------------------------------------------------- + +w_metadata fakejapanese_ipamona fonts \ + title="Creates aliases for Japanese fonts using IPAMona fonts" \ + publisher="Jun Kobayashi" \ + year="2008" + +load_fakejapanese_ipamona() +{ + w_call ipamona + + # Aliases to set: + # MS UI Gothic --> IPAMonaUIGothic + # MS Gothic (MS ゴシック) --> IPAMonaGothic + # MS PGothic (MS Pゴシック) --> IPAMonaPGothic + # MS Mincho (MS 明朝) --> IPAMonaMincho + # MS PMincho (MS P明朝) --> IPAMonaPMincho + + w_register_font_replacement "MS UI Gothic" "IPAMonaUIGothic" + w_register_font_replacement "MS Gothic" "IPAMonaGothic" + w_register_font_replacement "MS PGothic" "IPAMonaPGothic" + w_register_font_replacement "MS Mincho" "IPAMonaMincho" + w_register_font_replacement "MS PMincho" "IPAMonaPMincho" + w_register_font_replacement "MS ゴシック" "IPAMonaGothic" + w_register_font_replacement "MS Pゴシック" "IPAMonaPGothic" + w_register_font_replacement "MS 明朝" "IPAMonaMincho" + w_register_font_replacement "MS P明朝" "IPAMonaPMincho" +} + +#---------------------------------------------------------------- + +w_metadata fakejapanese_vlgothic fonts \ + title="Creates aliases for Japanese Meiryo fonts using VLGothic fonts" \ + publisher="Project Vine / Daisuke Suzuki" \ + conflicts="meiryo" \ + year="2014" + +load_fakejapanese_vlgothic() +{ + w_call vlgothic + + # Aliases to set: + # Meiryo UI --> VL Gothic + # Meiryo (メイリオ) --> VL Gothic + + w_register_font_replacement "Meiryo UI" "VL Gothic" + w_register_font_replacement "Meiryo" "VL Gothic" + w_register_font_replacement "メイリオ" "VL Gothic" +} + +#---------------------------------------------------------------- + +w_metadata fakekorean fonts \ + title="Creates aliases for Korean fonts using Source Han Sans fonts" \ + publisher="Adobe" \ + year="2019" + +load_fakekorean() +{ + # Loads Source Han Sans fonts and sets aliases for Microsoft Korean fonts + # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts + w_call sourcehansans + + w_register_font_replacement "Batang" "Source Han Sans K" + w_register_font_replacement "BatangChe" "Source Han Sans K" + w_register_font_replacement "Dotum" "Source Han Sans K" + w_register_font_replacement "DotumChe" "Source Han Sans K" + w_register_font_replacement "Gulim" "Source Han Sans K" + w_register_font_replacement "GulimChe" "Source Han Sans K" + w_register_font_replacement "Gungsuh" "Source Han Sans K" + w_register_font_replacement "GungsuhChe" "Source Han Sans K" + w_register_font_replacement "Malgun Gothic" "Source Han Sans K" + w_register_font_replacement "바탕" "Source Han Sans K" + w_register_font_replacement "바탕체" "Source Han Sans K" + w_register_font_replacement "돋움" "Source Han Sans K" + w_register_font_replacement "돋움체" "Source Han Sans K" + w_register_font_replacement "굴림" "Source Han Sans K" + w_register_font_replacement "굴림체" "Source Han Sans K" + w_register_font_replacement "맑은 고딕" "Source Han Sans K" +} + +#---------------------------------------------------------------- + +w_metadata ipamona fonts \ + title="IPAMona Japanese fonts" \ + publisher="Jun Kobayashi" \ + year="2008" \ + media="download" \ + file1="opfc-ModuleHP-1.1.1_withIPAMonaFonts-1.0.8.tar.gz" \ + installed_file1="${W_FONTSDIR_WIN}/ipag-mona.ttf" \ + homepage="http://www.geocities.jp/ipa_mona/" + +load_ipamona() +{ + w_download "https://web.archive.org/web/20190309175311/http://www.geocities.jp/ipa_mona/opfc-ModuleHP-1.1.1_withIPAMonaFonts-1.0.8.tar.gz" ab77beea3b051abf606cd8cd3badf6cb24141ef145c60f508fcfef1e3852bb9d + + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${file1}" "${file1%.tar.gz}/fonts" + w_try_cp_font_files "${file1%.tar.gz}/fonts" "${W_FONTSDIR_UNIX}" + + w_register_font ipagui-mona.ttf "IPAMonaUIGothic" + w_register_font ipag-mona.ttf "IPAMonaGothic" + w_register_font ipagp-mona.ttf "IPAMonaPGothic" + w_register_font ipam-mona.ttf "IPAMonaMincho" + w_register_font ipamp-mona.ttf "IPAMonaPMincho" +} + +#---------------------------------------------------------------- + +w_metadata liberation fonts \ + title="Red Hat Liberation fonts (Mono, Sans, SansNarrow, Serif)" \ + publisher="Red Hat" \ + year="2008" \ + media="download" \ + file1="liberation-fonts-ttf-1.07.4.tar.gz" \ + installed_file1="${W_FONTSDIR_WIN}/liberationmono-bolditalic.ttf" + +load_liberation() +{ + # https://pagure.io/liberation-fonts + w_download "https://releases.pagure.org/liberation-fonts/liberation-fonts-ttf-1.07.4.tar.gz" 61a7e2b6742a43c73e8762cdfeaf6dfcf9abdd2cfa0b099a9854d69bc4cfee5c + + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_font_files "${file1%.tar.gz}" "${W_FONTSDIR_UNIX}" + + w_register_font liberationmono-bolditalic.ttf "Liberation Mono Bold Italic" + w_register_font liberationmono-bold.ttf "Liberation Mono Bold" + w_register_font liberationmono-italic.ttf "Liberation Mono Italic" + w_register_font liberationmono-regular.ttf "Liberation Mono" + + w_register_font liberationsans-bolditalic.ttf "Liberation Sans Bold Italic" + w_register_font liberationsans-bold.ttf "Liberation Sans Bold" + w_register_font liberationsans-italic.ttf "Liberation Sans Italic" + w_register_font liberationsans-regular.ttf "Liberation Sans" + + w_register_font liberationsansnarrow-bolditalic.ttf "Liberation Sans Narrow Bold Italic" + w_register_font liberationsansnarrow-bold.ttf "Liberation Sans Narrow Bold" + w_register_font liberationsansnarrow-italic.ttf "Liberation Sans Narrow Italic" + w_register_font liberationsansnarrow-regular.ttf "Liberation Sans Narrow" + + w_register_font liberationserif-bolditalic.ttf "Liberation Serif Bold Italic" + w_register_font liberationserif-bold.ttf "Liberation Serif Bold" + w_register_font liberationserif-italic.ttf "Liberation Serif Italic" + w_register_font liberationserif-regular.ttf "Liberation Serif" +} + +#---------------------------------------------------------------- + +w_metadata lucida fonts \ + title="MS Lucida Console font" \ + publisher="Microsoft" \ + year="1998" \ + media="download" \ + file1="eurofixi.exe" \ + installed_file1="${W_FONTSDIR_WIN}/lucon.ttf" + +load_lucida() +{ + # The site supports https with Let's Encrypt, but that cert fails with curl (which breaks src/linkcheck.sh) + w_download "http://ftpmirror.your.org/pub/misc/ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40TSE/hotfixes-postSP3/Euro-fix/eurofixi.exe" 41f272a33521f6e15f2cce9ff1e049f2badd5ff0dc327fc81b60825766d5b6c7 + w_try_cabextract -d "${W_TMP}" -F "lucon.ttf" "${W_CACHE}"/lucida/eurofixi.exe + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" + w_register_font lucon.ttf "Lucida Console" +} + +#---------------------------------------------------------------- + +w_metadata opensymbol fonts \ + title="OpenSymbol fonts (replacement for Wingdings)" \ + publisher="OpenOffice.org" \ + year="2017" \ + media="download" \ + file1="fonts-opensymbol_102.10+LibO6.1.5-3+deb10u4_all.deb" \ + installed_file1="${W_FONTSDIR_WIN}/opens___.ttf" + +load_opensymbol() +{ + # The OpenSymbol fonts are a replacement for the Windows Wingdings font from OpenOffice.org. + # Need to w_download Debian since I can't find a standalone download from OpenOffice + # Note: The source download package on debian is for _all_ of OpenOffice, which is 266 MB. + w_download "https://cdn-aws.deb.debian.org/debian-security/pool/updates/main/libr/libreoffice/fonts-opensymbol_102.10+LibO6.1.5-3+deb10u4_all.deb" 1b2ab1e8eeb9a3a4a07e4a1c9bf539bb721734bf8b9881f4d0b8e71e822cecde + w_try_cd "${W_TMP}" + w_try_ar "${W_CACHE}/${W_PACKAGE}/${file1}" data.tar.xz + w_try tar -Jxf "${W_TMP}/data.tar.xz" ./usr/share/fonts/truetype/openoffice/opens___.ttf + w_try_cp_font_files "usr/share/fonts/truetype/openoffice" "${W_FONTSDIR_UNIX}" + w_register_font opens___.ttf "OpenSymbol" +} + +#---------------------------------------------------------------- + +w_metadata sourcehansans fonts \ + title="Source Han Sans fonts" \ + publisher="Adobe" \ + year="2021" \ + media="download" \ + file1="SourceHanSans.ttc.zip" \ + installed_file1="${W_FONTSDIR_WIN}/sourcehansans.ttc" + +load_sourcehansans() +{ + w_download "https://github.com/adobe-fonts/source-han-sans/releases/download/2.004R/SourceHanSans.ttc.zip" 6f59118a9adda5a7fe4e9e6bb538309f7e1d3c5411f9a9d32af32a79501b7e4f + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try mv "${W_TMP}/SourceHanSans.ttc" "${W_TMP}/sourcehansans_.ttc" + w_try mv "${W_TMP}/sourcehansans_.ttc" "${W_TMP}/sourcehansans.ttc" + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "*.ttc" + + # Simplified Chinese + w_register_font sourcehansans.ttc "Source Han Sans SC ExtraLight" + w_register_font sourcehansans.ttc "Source Han Sans SC Light" + w_register_font sourcehansans.ttc "Source Han Sans SC Normal" + w_register_font sourcehansans.ttc "Source Han Sans SC" + w_register_font sourcehansans.ttc "Source Han Sans SC Medium" + w_register_font sourcehansans.ttc "Source Han Sans SC Bold" + w_register_font sourcehansans.ttc "Source Han Sans SC Heavy" + + # Traditional Chinese (Taiwan) + w_register_font sourcehansans.ttc "Source Han Sans TC ExtraLight" + w_register_font sourcehansans.ttc "Source Han Sans TC Light" + w_register_font sourcehansans.ttc "Source Han Sans TC Normal" + w_register_font sourcehansans.ttc "Source Han Sans TC" + w_register_font sourcehansans.ttc "Source Han Sans TC Medium" + w_register_font sourcehansans.ttc "Source Han Sans TC Bold" + w_register_font sourcehansans.ttc "Source Han Sans TC Heavy" + + # Japanese + w_register_font sourcehansans.ttc "Source Han Sans ExtraLight" + w_register_font sourcehansans.ttc "Source Han Sans Light" + w_register_font sourcehansans.ttc "Source Han Sans Normal" + w_register_font sourcehansans.ttc "Source Han Sans" + w_register_font sourcehansans.ttc "Source Han Sans Medium" + w_register_font sourcehansans.ttc "Source Han Sans Bold" + w_register_font sourcehansans.ttc "Source Han Sans Heavy" + + # Korean + w_register_font sourcehansans.ttc "Source Han Sans K ExtraLight" + w_register_font sourcehansans.ttc "Source Han Sans K Light" + w_register_font sourcehansans.ttc "Source Han Sans K Normal" + w_register_font sourcehansans.ttc "Source Han Sans K" + w_register_font sourcehansans.ttc "Source Han Sans K Medium" + w_register_font sourcehansans.ttc "Source Han Sans K Bold" + w_register_font sourcehansans.ttc "Source Han Sans K Heavy" +} + +#---------------------------------------------------------------- + +w_metadata tahoma fonts \ + title="MS Tahoma font (not part of corefonts)" \ + publisher="Microsoft" \ + year="1999" \ + media="download" \ + file1="IELPKTH.CAB" \ + installed_file1="${W_FONTSDIR_WIN}/tahoma.ttf" + +load_tahoma() +{ + # Formerly at https://download.microsoft.com/download/ie55sp2/Install/5.5_SP2/WIN98Me/EN-US/IELPKTH.CAB + w_download https://downloads.sourceforge.net/corefonts/OldFiles/IELPKTH.CAB c1be3fb8f0042570be76ec6daa03a99142c88367c1bc810240b85827c715961a + + w_try_cabextract -d "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" "*.TTF" + + w_register_font tahoma.ttf "Tahoma" + w_register_font tahomabd.ttf "Tahoma Bold" +} + +#---------------------------------------------------------------- + +w_metadata takao fonts \ + title="Takao Japanese fonts" \ + publisher="Jun Kobayashi" \ + year="2010" \ + media="download" \ + file1="takao-fonts-ttf-003.02.01.zip" \ + installed_file1="${W_FONTSDIR_WIN}/takaogothic.ttf" + +load_takao() +{ + # The Takao font provides Japanese glyphs. May also be needed with fakejapanese function above. + # See https://launchpad.net/takao-fonts for project page + w_download "https://launchpad.net/takao-fonts/trunk/003.02.01/+download/takao-fonts-ttf-003.02.01.zip" 2f526a16c7931958f560697d494d8304949b3ce0aef246fb0c727fbbcc39089e + w_try_unzip "${W_TMP}" "${W_CACHE}"/takao/takao-fonts-ttf-003.02.01.zip + w_try_cp_font_files "${W_TMP}/takao-fonts-ttf-003.02.01" "${W_FONTSDIR_UNIX}" + + w_register_font takaogothic.ttf "TakaoGothic" + w_register_font takaopgothic.ttf "TakaoPGothic" + w_register_font takaomincho.ttf "TakaoMincho" + w_register_font takaopmincho.ttf "TakaoPMincho" + w_register_font takaoexgothic.ttf "TakaoExGothic" + w_register_font takaoexmincho.ttf "TakaoExMincho" +} + +#---------------------------------------------------------------- + +w_metadata uff fonts \ + title="Ubuntu Font Family" \ + publisher="Ubuntu" \ + year="2010" \ + media="download" \ + file1="ubuntu-font-family-0.83.zip" \ + installed_file1="${W_FONTSDIR_WIN}/ubuntu-r.ttf" \ + homepage="https://launchpad.net/ubuntu-font-family" + +load_uff() +{ + w_download "https://assets.ubuntu.com/v1/fad7939b-ubuntu-font-family-0.83.zip" 456d7d42797febd0d7d4cf1b782a2e03680bb4a5ee43cc9d06bda172bac05b42 ubuntu-font-family-0.83.zip + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + + w_try_cp_font_files "${W_TMP}/$(basename "${file1}" .zip)" "${W_FONTSDIR_UNIX}" + + w_register_font ubuntu-bi.ttf "Ubuntu Bold Italic" + w_register_font ubuntu-b.ttf "Ubuntu Bold" + w_register_font ubuntu-c.ttf "Ubuntu Condensed" + w_register_font ubuntu-i.ttf "Ubuntu Italic" + w_register_font ubuntu-li.ttf "Ubuntu Light Italic" + w_register_font ubuntu-l.ttf "Ubuntu Light" + w_register_font ubuntu-mi.ttf "Ubuntu Medium Italic" + w_register_font ubuntumono-bi.ttf "Ubuntu Mono Bold Italic" + w_register_font ubuntumono-b.ttf "Ubuntu Mono Bold" + w_register_font ubuntumono-ri.ttf "Ubuntu Mono Italic" + w_register_font ubuntumono-r.ttf "Ubuntu Mono" + w_register_font ubuntu-m.ttf "Ubuntu Medium" + w_register_font ubuntu-ri.ttf "Ubuntu Italic" + w_register_font ubuntu-r.ttf "Ubuntu" + +} + +#---------------------------------------------------------------- + +w_metadata vlgothic fonts \ + title="VLGothic Japanese fonts" \ + publisher="Project Vine / Daisuke Suzuki" \ + year="2014" \ + media="download" \ + file1="VLGothic-20141206.tar.xz" \ + installed_file1="${W_FONTSDIR_WIN}/vl-gothic-regular.ttf" \ + homepage="https://ja.osdn.net/projects/vlgothic" + +load_vlgothic() +{ + w_download "https://ja.osdn.net/projects/vlgothic/downloads/62375/VLGothic-20141206.tar.xz" 982040db2f9cb73d7c6ab7d9d163f2ed46d1180f330c9ba2fae303649bf8102d + + w_try_cd "${W_TMP}" + w_try tar -Jxf "${W_CACHE}/vlgothic/VLGothic-20141206.tar.xz" + w_try_cp_font_files "${W_TMP}/VLGothic" "${W_FONTSDIR_UNIX}" + + w_register_font vl-gothic-regular.ttf "VL Gothic" + w_register_font vl-pgothic-regular.ttf "VL PGothic" +} + +#---------------------------------------------------------------- + +w_metadata wenquanyi fonts \ + title="WenQuanYi CJK font" \ + publisher="wenq.org" \ + year="2009" \ + media="download" \ + file1="wqy-microhei-0.2.0-beta.tar.gz" \ + installed_file1="${W_FONTSDIR_WIN}/wqy-microhei.ttc" + +load_wenquanyi() +{ + # See http://wenq.org/enindex.cgi + # Donate at http://wenq.org/enindex.cgi?Download(en)#MicroHei_Beta if you want to help support free CJK font development + w_download "https://downloads.sourceforge.net/wqy/wqy-microhei-0.2.0-beta.tar.gz" 2802ac8023aa36a66ea6e7445854e3a078d377ffff42169341bd237871f7213e + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_font_files "${W_TMP}/wqy-microhei" "${W_FONTSDIR_UNIX}" "*.ttc" + + w_register_font wqy-microhei.ttc "WenQuanYi Micro Hei" +} + +#---------------------------------------------------------------- + +w_metadata wenquanyizenhei fonts \ + title="WenQuanYi ZenHei font" \ + publisher="wenq.org" \ + year="2009" \ + media="download" \ + file1="wqy-zenhei-0.8.38-1.tar.gz" \ + installed_file1="${W_FONTSDIR_WIN}/wqy-zenhei.ttc" + +load_wenquanyizenhei() +{ + # See http://wenq.org/wqy2/index.cgi?ZenHei + # Donate at http://wenq.org/wqy2/index.cgi?Donation if you want to help support free font development + w_download "http://downloads.sourceforge.net/wqy/wqy-zenhei-0.8.38-1.tar.gz" 6018eb54243eddc41e9cbe0b71feefa5cb2570ecbaccd39daa025961235dea22 + w_try_cd "${W_TMP}" + w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try_cp_font_files "${W_TMP}/wqy-zenhei" "${W_FONTSDIR_UNIX}" "*.ttc" + + w_register_font wqy-zenhei.ttc "WenQuanYi Zen Hei" +} + +#---------------------------------------------------------------- + +w_metadata unifont fonts \ + title="Unifont alternative to Arial Unicode MS" \ + publisher="Roman Czyborra / GNU" \ + year="2021" \ + media="download" \ + file1="unifont-13.0.06.ttf" \ + installed_file1="${W_FONTSDIR_WIN}/unifont.ttf" + +load_unifont() +{ + # The GNU Unifont provides glyphs for just about everything in common language. It is intended for multilingual usage. + # See https://unifoundry.com/unifont/index.html for project page. + w_download "https://unifoundry.com/pub/unifont/unifont-13.0.06/font-builds/unifont-13.0.06.ttf" d73c0425811ffd366b0d1973e9338bac26fe7cf085760a12e10c61241915e742 + w_try cp "${W_CACHE}/${W_PACKAGE}/${file1}" "${W_TMP}/unifont.ttf" + w_try_cp_font_files "${W_TMP}" "${W_FONTSDIR_UNIX}" + + w_register_font unifont.ttf "Unifont" + w_register_font_replacement "Arial Unicode MS" "Unifont" +} + +#---------------------------------------------------------------- + +w_metadata allfonts fonts \ + title="All fonts" \ + publisher="various" \ + year="1998-2010" \ + media="download" + +load_allfonts() +{ + # This verb uses reflection, should probably do it portably instead, but that would require keeping it up to date + for file in "${WINETRICKS_METADATA}"/fonts/*.vars; do + cmd=$(basename "${file}" .vars) + case ${cmd} in + # "fake*" verbs need to be skipped because + # this "allfonts" verb is intended to only install real fonts and + # adding font replacements at the same time may invalidate the replacements + # "pptfonts" can be skipped because it only calls other verbs for installing fonts + # See https://github.com/Winetricks/winetricks/issues/899 + allfonts|cjkfonts|fake*|pptfonts) ;; + *) w_call "${cmd}";; + esac + done +} + +####################### +# apps +####################### + +#---------------------------------------------------------------- + +w_metadata 3m_library apps \ + title="3M Cloud Library" \ + publisher="3M Company" \ + year="2015" \ + media="download" \ + file1="cloudLibrary-2.1.1702011951-Setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/cloudLibrary/cloudLibrary.exe" \ + homepage="https://www.yourcloudlibrary.com/" + +load_3m_library() +{ + w_download https://usestrwebaccess.blob.core.windows.net/apps/pc/cloudLibrary-2.1.1702011951-Setup.exe bb3d854cc525c065e7298423bf0019309f4b65497c1d8bc6af09460cd6fcb57f + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata 7zip apps \ + title="7-Zip 19.00" \ + publisher="Igor Pavlov" \ + year="2019" \ + media="download" \ + file1="7z1900.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/7-Zip/7zFM.exe" + +load_7zip() +{ + w_download https://www.7-zip.org/a/7z1900.exe 759aa04d5b03ebeee13ba01df554e8c962ca339c74f56627c8bed6984bb7ef80 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata adobe_diged apps \ + title="Adobe Digital Editions 1.7" \ + publisher="Adobe" \ + year="2011" \ + media="download" \ + file1="setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Adobe/Adobe Digital Editions/digitaleditions.exe" \ + homepage="https://www.adobe.com/solutions/ebook/digital-editions.html" + +load_adobe_diged() +{ + w_download https://kb2.adobe.com/cps/403/kb403051/attachments/setup.exe 4ebe0fcefbe68900ca6bf499432030c9f8eb8828f8cb5a7e1fd1a16c0eba918e + # NSIS installer + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}/setup.exe" ${W_OPT_UNATTENDED:+ /S} +} + +#---------------------------------------------------------------- + +w_metadata adobe_diged4 apps \ + title="Adobe Digital Editions 4.5" \ + publisher="Adobe" \ + year="2015" \ + media="download" \ + file1="ADE_4.5_Installer.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Adobe/Adobe Digital Editions 4.5/DigitalEditions.exe" \ + homepage="https://www.adobe.com/solutions/ebook/digital-editions.html" + +load_adobe_diged4() +{ + w_download https://download.adobe.com/pub/adobe/digitaleditions/ADE_4.5_Installer.exe a21a9d5389728fdac6a7288953dddeea774ef2bee07f1caf7ea20bbed8f5a2c6 + + if w_workaround_wine_bug 32323; then + w_call corefonts + fi + + if [ ! -x "$(command -v winbindd 2>/dev/null)" ]; then + w_warn "Adobe Digital Editions 4.5 requires winbind (part of Samba) to be installed, but winbind was not detected." + fi + + w_call dotnet40 + + #w_call win7 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if w_workaround_wine_bug 46019 "Installer fails under wine, manually unpacking it instead" ,4.6; then + w_try_7z "${W_PROGRAMS_X86_UNIX}/Adobe/Adobe Digital Editions 4.5" "${file1}" -y + else + w_ahk_do " + SetTitleMatchMode, 2 + run, ${file1} ${W_OPT_UNATTENDED:+ /S} + winwait, Installing Adobe Digital Editions + ControlClick, Button1 ; Don't install Norton Internet Security + ControlClick, Static19 ; Next + " + fi +} + +#---------------------------------------------------------------- + +w_metadata autohotkey apps \ + title="AutoHotKey" \ + publisher="autohotkey.org" \ + year="2010" \ + media="download" \ + file1="AutoHotkey104805_Install.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/AutoHotkey/AutoHotkey.exe" + +load_autohotkey() +{ + w_download https://github.com/AutoHotkey/AutoHotkey/releases/download/v1.0.48.05/AutoHotkey104805_Install.exe 4311c3e7c29ed2d67f415138360210bc2f55ff78758b20b003b91d775ee207b9 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" AutoHotkey104805_Install.exe ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata busybox apps \ + title="BusyBox FRP-4621-gf3c5e8bc3" \ + publisher="Ron Yorston / Busybox authors" \ + year="2021" \ + media="download" \ + file1="busybox-w32-FRP-4621-gf3c5e8bc3.exe" \ + installed_exe1="${W_SYSTEM32_DLLS_WIN}/busybox.exe" + +load_busybox() +{ + w_download https://frippery.org/files/busybox/busybox-w32-FRP-4621-gf3c5e8bc3.exe 58c9da9ba094eade662572f9a725a6af44350dc3ff5a7897696926c651fdb582 + + if test "${W_ARCH}" = "win64"; then + w_download https://frippery.org/files/busybox/busybox-w64-FRP-4621-gf3c5e8bc3.exe 7109bc6f129ab7ce466f7b3175ca830316184b431d16a965ade17b93c035ec7c + w_try_cp_dll "${W_CACHE}/${W_PACKAGE}/${file1}" "${W_SYSTEM32_DLLS}/busybox.exe" + w_try_cp_dll "${W_CACHE}/${W_PACKAGE}/busybox-w64-FRP-4621-gf3c5e8bc3.exe" "${W_SYSTEM64_DLLS}/busybox.exe" + else + w_try_cp_dll "${W_CACHE}/${W_PACKAGE}/${file1}" "${W_SYSTEM32_DLLS}/busybox.exe" + fi +} + +#---------------------------------------------------------------- + +w_metadata cmake apps \ + title="CMake 2.8" \ + publisher="Kitware" \ + year="2013" \ + media="download" \ + file1="cmake-2.8.11.2-win32-x86.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/CMake 2.8/bin/cmake-gui.exe" + +load_cmake() +{ + w_download https://www.cmake.org/files/v2.8/cmake-2.8.11.2-win32-x86.exe cb6a7df8fd6f2eca66512279991f3c2349e3f788477c3be8eaa362d46c21dbf0 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" cmake-2.8.11.2-win32-x86.exe ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata colorprofile apps \ + title="Standard RGB color profile" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="ColorProfile.exe" \ + installed_exe1="c:/windows/system32/spool/drivers/color/sRGB Color Space Profile.icm" + +load_colorprofile() +{ + w_download https://download.microsoft.com/download/whistler/hwdev1/1.0/wxp/en-us/ColorProfile.exe d04ac910acdd97abd663f559bebc6440d8d68664bf977ec586035247d7b0f728 + w_try_unzip "${W_TMP}" "${W_CACHE}"/colorprofile/ColorProfile.exe + + # It's in system32 for both win32/win64 + mkdir -p "${W_WINDIR_UNIX}"/system32/spool/drivers/color + w_try cp -f "${W_TMP}/sRGB Color Space Profile.icm" "${W_WINDIR_UNIX}"/system32/spool/drivers/color +} + +#---------------------------------------------------------------- + +w_metadata controlpad apps \ + title="MS ActiveX Control Pad" \ + publisher="Microsoft" \ + year="1997" \ + media="download" \ + file1="setuppad.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/ActiveX Control Pad/PED.EXE" + +load_controlpad() +{ + # https://msdn.microsoft.com/en-us/library/ms968493.aspx + w_call wsh57 + w_download https://download.microsoft.com/download/activexcontrolpad/install/4.0.0.950/win98mexp/en-us/setuppad.exe eab94091ac391f9bbc8e355a1d231e6a08b8dbbb0f6539245b7f0c58d94f420c + w_try_cabextract --directory="${W_TMP}" "${W_CACHE}"/controlpad/setuppad.exe + + echo "If setup says 'Unable to start DDE ...', press Ignore" + + w_try_cd "${W_TMP}" + w_try "${WINE}" setup ${W_OPT_UNATTENDED:+/qt} + + if ! test -f "${W_SYSTEM32_DLLS}"/FM20.DLL; then + w_die "Install failed. Please report, If you just wanted fm20.dll, try installing art2min instead." + fi +} + +#---------------------------------------------------------------- + +w_metadata controlspy apps \ + title="Control Spy 6 " \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="ControlSpyV6.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft/ControlSpy/ControlSpyV6.exe" + +load_controlspy() +{ + # Originally at https://download.microsoft.com/download/a/3/1/a315b133-03a8-4845-b428-ec585369b285/ControlSpy.msi + # 2019/04/11: changed to https://github.com/pywinauto/pywinauto/blob/master/apps/ControlSpy_20/ControlSpyV6.exe + # Unfortunately that means no V5 of ControlSpy :/ + w_download https://github.com/pywinauto/pywinauto/blob/master/apps/ControlSpy_20/ControlSpyV6.exe + w_try mkdir -p "${W_PROGRAMS_X86_UNIX}/Microsoft/ControlSpy" + w_try cp "${W_CACHE}/${W_PACKAGE}/${file1}" "${W_PROGRAMS_X86_UNIX}/Microsoft/ControlSpy" +} + +#---------------------------------------------------------------- + +# dxdiag is a system component that one usually adds to an existing wineprefix, +# so it belongs in 'dlls', not apps. +w_metadata dxdiag dlls \ + title="DirectX Diagnostic Tool" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="../directx9/directx_feb2010_redist.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/dxdiag.exe" + +load_dxdiag() +{ + helper_directx_dl + + w_call gmdls + + w_try_cabextract -d "${W_TMP}" -L -F dxnt.cab "${W_CACHE}"/directx9/${DIRECTX_NAME} + w_try_cabextract -d "${W_SYSTEM32_DLLS}" -L -F "dxdiag.exe" "${W_TMP}/dxnt.cab" + mkdir -p "${W_WINDIR_UNIX}/help" + w_try_cabextract -d "${W_WINDIR_UNIX}/help" -L -F "dxdiag.chm" "${W_TMP}/dxnt.cab" + w_override_dlls native dxdiag.exe + + if w_workaround_wine_bug 49996; then + w_call dxdiagn_feb2010 + fi + + if w_workaround_wine_bug 9027; then + w_call dmband + w_call dmime + w_call dmstyle + w_call dmsynth + w_call dmusic + fi +} + +#---------------------------------------------------------------- + +w_metadata emu8086 apps \ + title="emu8086" \ + publisher="emu8086.com" \ + year="2015" \ + media="download" \ + file1="emu8086v408r11.zip" \ + installed_exe1="c:/emu8086/emu8086.exe" + +load_emu8086() +{ + # 2018/11/15: emu8086.com is down + # w_download http://www.emu8086.com/files/emu8086v408r11.zip d56d6e42fe170c52df5abd6002b1e8fef0b840eb8d8807d77819fe1fc2e17afd + w_download https://web.archive.org/web/20160206003914if_/http://emu8086.com/files/emu8086v408r11.zip d56d6e42fe170c52df5abd6002b1e8fef0b840eb8d8807d77819fe1fc2e17afd + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}" + w_try "${WINE}" "${W_TMP}/Setup.exe" ${W_OPT_UNATTENDED:+/silent} +} + +#---------------------------------------------------------------- + +w_metadata ev3 apps \ + title="Lego Mindstorms EV3 Home Edition" \ + publisher="Lego" \ + year="2014" \ + media="download" \ + file1="LMS-EV3-WIN32-ENUS-01-02-01-full-setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/LEGO Software/LEGO MINDSTORMS EV3 Home Edition/MindstormsEV3.exe" + +load_ev3() +{ + if w_workaround_wine_bug 40192 "Installing vcrun2005 as Wine does not have MFC80.dll"; then + w_call vcrun2005 + fi + + if w_workaround_wine_bug 40193 "Installing IE8 as built-in Gecko is not sufficient"; then + w_call ie8 + fi + + w_call dotnet40 + + # 2016/03/22: LMS-EV3-WIN32-ENUS-01-02-01-full-setup.exe c47341f08242f0f6f01996530e7c93bda2d666747ada60ab93fa773a55d40a19 + + w_download http://esd.lego.com.edgesuite.net/digitaldelivery/mindstorms/6ecda7c2-1189-4816-b2dd-440e22d65814/public/LMS-EV3-WIN32-ENUS-01-02-01-full-setup.exe c47341f08242f0f6f01996530e7c93bda2d666747ada60ab93fa773a55d40a19 + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/qb /AcceptLicenses yes} + + if w_workaround_wine_bug 40729 "Setting override for urlmon.dll to native to avoid crash"; then + w_override_dlls native urlmon + fi +} + +#---------------------------------------------------------------- + +w_metadata firefox apps \ + title="Firefox 51.0" \ + publisher="Mozilla" \ + year="2017" \ + media="download" \ + file1="FirefoxSetup51.0.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Mozilla Firefox/firefox.exe" + +load_firefox() +{ + w_download "https://download.mozilla.org/?product=firefox-51.0-SSL&os=win&lang=en-US" 05fa9ae012eca560f42d593e75eb37045a54e4978b665b51f6a61e4a2d376eb8 "${file1}" + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ -ms} +} + +#---------------------------------------------------------------- + +w_metadata fontxplorer apps \ + title="Font Xplorer 1.2.2" \ + publisher="Moon Software" \ + year="2001" \ + media="download" \ + file1="Font_Xplorer_122_Free.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Font Xplorer/FXplorer.exe" \ + homepage="http://www.moonsoftware.com/fxplorer.asp" + +load_fontxplorer() +{ + # 2011/05/15: http://www.moonsoftware.com/files/legacy/Font_Xplorer_122_Free.exe e3a53841c133e2ecfeb75c7ea277e23011317bb031f8caf423b7e9b7f92d85e0 + # 2019/06/14: http://www.moonsoftware.com/files/legacy/Font_Xplorer_122_Free.exe is dead + w_download https://web.archive.org/web/20190217101943/http://www.moonsoftware.com/files/legacy/Font_Xplorer_122_Free.exe e3a53841c133e2ecfeb75c7ea277e23011317bb031f8caf423b7e9b7f92d85e0 + w_try_cd "${W_CACHE}/fontxplorer" + w_try "${WINE}" Font_Xplorer_122_Free.exe ${W_OPT_UNATTENDED:+/S} + w_killall "explorer.exe" +} + +#---------------------------------------------------------------- + +w_metadata foobar2000 apps \ + title="foobar2000 v1.4" \ + publisher="Peter Pawlowski" \ + year="2018" \ + media="manual_download" \ + file1="foobar2000_v1.4.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/foobar2000/foobar2000.exe" + +load_foobar2000() +{ + # 2016/12/21: 1.3.14 - 72d024d258c2f3b6cea62dc47fb613848202e7f33f2331f6b2e0a8e61daffcb6 + # 2018/07/25: 1.4 - 7c048faecfec79f9ec2b332b2c68b25e0d0219b47a7c679fe56f2ec05686a96a + + w_download_manual https://www.foobar2000.org/download foobar2000_v1.4.exe 7c048faecfec79f9ec2b332b2c68b25e0d0219b47a7c679fe56f2ec05686a96a + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata hhw apps \ + title="HTML Help Workshop" \ + publisher="Microsoft" \ + year="2000" \ + media="download" \ + file1="htmlhelp.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/HTML Help Workshop/hhw.exe" + +load_hhw() +{ + w_call mfc40 + + # https://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx + w_download https://web.archive.org/web/20160423015142if_/http://download.microsoft.com/download/0/a/9/0a939ef6-e31c-430f-a3df-dfae7960d564/htmlhelp.exe b2b3140d42a818870c1ab13c1c7b8d4536f22bd994fa90aade89729a6009a3ae + + # htmlhelp.exe automatically runs hhupd.exe. It shows a dialog that says + # "This computer already has a newer version of HTML Help." + # because of Wine's built-in hhctrl.ocx and it copys files only when + # Windows version is "Windows 98", "Windows 95", "Windows NT 4.0", + # or "Windows NT 3.51". 64-bit prefixes can't use any of them. + # + # So we need the following steps: + # 1. Run htmlhelp.exe to unpack its contents + # 2. Edit htmlhelp.inf not to run hhupd.exe + # 3. Run setup.exe + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}"/htmlhelp.exe /C "/T:${W_TMP_WIN}" ${W_OPT_UNATTENDED:+/q} + w_try_cd "${W_TMP}" + w_try sed -i "s/RunPostSetupCommands=HHUpdate//" htmlhelp.inf + w_try "${WINE}" setup.exe + + if w_workaround_wine_bug 7517; then + w_call itircl + w_call itss + fi +} + +#---------------------------------------------------------------- + +w_metadata iceweasel apps \ + title="GNU Icecat 31.7.0" \ + publisher="GNU Foundation" \ + year="2015" \ + media="download" \ + file1="icecat-31.7.0.en-US.win32.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/icecat/icecat.exe" + +load_iceweasel() +{ + w_download https://ftp.gnu.org/gnu/gnuzilla/31.7.0/icecat-31.7.0.en-US.win32.zip 27d10e63ab9ea4e6995c235b92258b379f79433a06a12e4ad16811801cf81e36 + w_try_unzip "${W_PROGRAMS_X86_UNIX}" "${W_CACHE}/${W_PACKAGE}/${file1}" +} + + +#---------------------------------------------------------------- + +w_metadata irfanview apps \ + title="Irfanview" \ + publisher="Irfan Skiljan" \ + year="2016" \ + media="download" \ + file1="iview444_setup.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/IrfanView/i_view32.exe" \ + homepage="https://www.irfanview.com/" + +load_irfanview() +{ + w_download http://download.betanews.com/download/967963863-1/iview444_setup.exe 71b44cd3d14376bbb619b2fe8a632d29200385738dd186680e988ce32662b3d6 + if w_workaround_wine_bug 657 "Installing mfc42"; then + w_call mfc42 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if test "${W_OPT_UNATTENDED}"; then + w_ahk_do " + SetWinDelay 200 + SetTitleMatchMode, 2 + run ${file1} + winwait, Setup, This program will install + winactivate, Setup, This program will install + Sleep 900 + ControlClick, Button7 ; Uncheck All + Sleep 900 + ControlClick, Button4 ; Create start menu icons + Sleep 900 + ControlClick, Button11 ; Next + Sleep 900 + winwait, Setup, version + Sleep 900 + ControlClick, Button11 ; Next + Sleep 900 + winwait, Setup, associate extensions + Sleep 900 + ControlClick, Button1 ; Images Only associations + Sleep 900 + ControlClick, Button16 ; Next + Sleep 1000 + winwait, Setup, INI + Sleep 1000 + ControlClick, Button21 ; Next + Sleep 1000 + winwait, Setup, You want to change + winactivate, Setup, really + Sleep 900 + ControlClick, Button1 ; Yes + Sleep 900 + winwait, Setup, successful + winactivate, Setup, successful + Sleep 900 + ControlClick, Button1 ; no load webpage + Sleep 900 + ControlClick, Button2 ; no start irfanview + Sleep 900 + ControlClick, Button25 ; done + Sleep 900 + winwaitclose + " + else + w_try "${WINE}" "${file1}" + fi +} + +#---------------------------------------------------------------- + +# FIXME: ie6 always installs to C:/Program Files even if LANG is de_DE.utf-8, +# so we have to hard code that, but that breaks on 64-bit Windows. +w_metadata ie6 dlls \ + title="Internet Explorer 6" \ + publisher="Microsoft" \ + year="2002" \ + media="download" \ + conflicts="ie7 ie8" \ + file1="ie60.exe" \ + installed_file1="c:/Program Files/Internet Explorer/iedetect.dll" + +load_ie6() +{ + w_package_unsupported_win64 + + w_download https://web.archive.org/web/20150411022055if_/http://download.oldapps.com/Internet_Explorer/ie60.exe e34e0557d939e7e83185f5354403df99c92a3f3ff80f5ee0c75f6843eaa6efb2 + + w_try_cd "${W_TMP}" + "${WINE}" "${W_CACHE}/${W_PACKAGE}/${file1}" + + # Unregister Wine IE + if [ ! -f "${W_SYSTEM32_DLLS}"/plugin.ocx ]; then + w_override_dlls builtin iexplore.exe + w_try "${WINE}" iexplore -unregserver + fi + + # Change the override to the native so we are sure we use and register them + w_override_dlls native,builtin iexplore.exe inetcpl.cpl itircl itss jscript mlang mshtml msimtf shdoclc shdocvw shlwapi + + # Remove the fake DLLs, if any + mv "${W_PROGRAMS_UNIX}/Internet Explorer/iexplore.exe" "${W_PROGRAMS_UNIX}/Internet Explorer/iexplore.exe.bak" + for dll in itircl itss jscript mlang mshtml msimtf shdoclc shdocvw; do + test -f "${W_SYSTEM32_DLLS}"/${dll}.dll && + mv "${W_SYSTEM32_DLLS}"/${dll}.dll "${W_SYSTEM32_DLLS}"/${dll}.dll.bak + done + + # The installer doesn't want to install iexplore.exe in XP mode. + w_set_winver win2k + + # Workaround https://bugs.winehq.org/show_bug.cgi?id=21009 + # FIXME: seems this didn't get migrated to Github? + # See also https://code.google.com/p/winezeug/issues/detail?id=78 + rm -f "${W_SYSTEM32_DLLS}"/browseui.dll "${W_SYSTEM32_DLLS}"/inseng.dll + + # Otherwise regsvr32 crashes later + rm -f "${W_SYSTEM32_DLLS}"/inetcpl.cpl + + # Work around https://bugs.winehq.org/show_bug.cgi?id=25432 + w_try_cabextract -F inseng.dll "${W_TMP}/IE 6.0 Full/ACTSETUP.CAB" + mv inseng.dll "${W_SYSTEM32_DLLS}" + w_override_dlls native inseng + + w_try_cd "${W_TMP}/IE 6.0 Full" + w_try_ms_installer "${WINE}" IE6SETUP.EXE ${W_OPT_UNATTENDED:+/q:a /r:n /c:"ie6wzd /S:""#e"" /q:a /r:n"} + + # Work around DLL registration bug until ierunonce/RunOnce/wineboot is fixed + # FIXME: whittle down this list + w_try_cd "${W_SYSTEM32_DLLS}" + for i in actxprxy.dll browseui.dll browsewm.dll cdfview.dll ddraw.dll \ + dispex.dll dsound.dll iedkcs32.dll iepeers.dll iesetup.dll imgutil.dll \ + inetcomm.dll inetcpl.cpl inseng.dll isetup.dll jscript.dll laprxy.dll \ + mlang.dll mshtml.dll mshtmled.dll msi.dll msident.dll \ + msoeacct.dll msrating.dll mstime.dll msxml3.dll occache.dll \ + ole32.dll oleaut32.dll olepro32.dll pngfilt.dll quartz.dll \ + rpcrt4.dll rsabase.dll rsaenh.dll scrobj.dll scrrun.dll \ + shdocvw.dll shell32.dll vbscript.dll webcheck.dll \ + wshcon.dll wshext.dll asctrls.ocx hhctrl.ocx mscomct2.ocx \ + plugin.ocx proctexe.ocx tdc.ocx webcheck.dll wshom.ocx; do + "${WINE}" regsvr32 /i ${i} > /dev/null 2>&1 + done + + # Set Windows version back to the default. Leave at win2k for better rendering (is there a bug for that?) + w_set_winver 'default' + + # the ie6 we use these days lacks pngfilt, so grab that + w_call pngfilt + + w_call msls31 +} + +#---------------------------------------------------------------- + +w_metadata ie7 dlls \ + title="Internet Explorer 7" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + conflicts="ie6 ie8" \ + file1="IE7-WindowsXP-x86-enu.exe" \ + installed_file1="c:/windows/ie7.log" + +load_ie7() +{ + w_package_unsupported_win64 + + # Unregister Wine IE + if grep -q -i "wine placeholder" "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe"; then + w_override_dlls builtin iexplore.exe + w_try "${WINE}" iexplore -unregserver + fi + + # Change the override to the native so we are sure we use and register them + w_override_dlls native,builtin ieproxy ieframe itircl itss jscript mshtml msimtf shdoclc shdocvw shlwapi urlmon wininet xmllite + + # IE7 installer will check the version number of iexplore.exe which causes IE7 installer to fail on wine-1.9.0+ + w_override_dlls native iexplore.exe + + # Bundled updspapi cannot work on Wine + w_override_dlls builtin updspapi + + # Remove the fake DLLs from the existing WINEPREFIX + if [ -f "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe" ]; then + mv "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe" "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe.bak" + fi + for dll in itircl itss jscript mshtml msimtf shdoclc shdocvw urlmon; do + test -f "${W_SYSTEM32_DLLS}"/${dll}.dll && + mv "${W_SYSTEM32_DLLS}"/${dll}.dll "${W_SYSTEM32_DLLS}"/${dll}.dll.bak + done + + # See https://bugs.winehq.org/show_bug.cgi?id=16013 + # Find instructions to create this file in dlls/wintrust/tests/crypt.c + w_download https://github.com/Winetricks/winetricks/raw/master/files/winetest.cat 5d18ab44fc289100ccf4b51cf614cc2d36f7ca053e557e2ba973811293c97d38 + + # Put a dummy catalog file in place + mkdir -p "${W_SYSTEM32_DLLS}"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\} + w_try cp -f "${W_CACHE}"/ie7/winetest.cat "${W_SYSTEM32_DLLS}"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\}/oem0.cat + + # KLUDGE: if / is writable (as on OS X?), having a Z: mapping to it + # causes ie7 to put temporary directories on Z:\. + # So hide it temporarily. This is not very robust! + if [ -w / ] && [ -h "${WINEPREFIX}/dosdevices/z:" ]; then + w_try rm -f "${WINEPREFIX}/dosdevices/z:.bak_wt" + w_try mv "${WINEPREFIX}/dosdevices/z:" "${WINEPREFIX}/dosdevices/z:.bak_wt" + _W_restore_z=1 + fi + + # Install + # Microsoft took this down (as of 2020/08/08), but the latest snapshot on archive.org (2020/06/20) gives a different binary. + # The snapshot just before that (2020/06/17) is fine, however: + w_download https://web.archive.org/web/20200617171343/https://download.microsoft.com/download/3/8/8/38889DC1-848C-4BF2-8335-86C573AD86D9/IE7-WindowsXP-x86-enu.exe bf5c325bbe3f4174869b2a8ff75f92833e7f7debe64777ed0faf293c7725cbef + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # IE7 requies winxp to install: + w_set_winver winxp + + w_try_ms_installer "${WINE}" IE7-WindowsXP-x86-enu.exe ${W_OPT_UNATTENDED:+/quiet} + + if [ "${_W_restore_z}" = 1 ]; then + # END KLUDGE: restore Z:, assuming that the user didn't kill us + w_try mv "${WINEPREFIX}/dosdevices/z:.bak_wt" "${WINEPREFIX}/dosdevices/z:" + fi + + # Work around DLL registration bug until ierunonce/RunOnce/wineboot is fixed + # FIXME: whittle down this list + w_try_cd "${W_SYSTEM32_DLLS}" + for i in actxprxy.dll browseui.dll browsewm.dll cdfview.dll ddraw.dll \ + dispex.dll dsound.dll iedkcs32.dll iepeers.dll iesetup.dll \ + imgutil.dll inetcomm.dll inseng.dll isetup.dll jscript.dll laprxy.dll \ + mlang.dll mshtml.dll mshtmled.dll msi.dll msident.dll \ + msoeacct.dll msrating.dll mstime.dll msxml3.dll occache.dll \ + ole32.dll oleaut32.dll olepro32.dll pngfilt.dll quartz.dll \ + rpcrt4.dll rsabase.dll rsaenh.dll scrobj.dll scrrun.dll \ + shdocvw.dll shell32.dll urlmon.dll vbscript.dll webcheck.dll \ + wshcon.dll wshext.dll asctrls.ocx hhctrl.ocx mscomct2.ocx \ + plugin.ocx proctexe.ocx tdc.ocx webcheck.dll wshom.ocx; do + "${WINE}" regsvr32 /i ${i} > /dev/null 2>&1 + done + + # Builtin ieproxy is in system32, but ie7's lives in Program Files. Native + # CLSID path will get overwritten on prefix update. Setting ieproxy to + # native doesn't help because setupapi ignores DLL overrides. To work + # around this problem, copy native ieproxy to system32. + w_try_cp_dll "${W_PROGRAMS_X86_UNIX}/Internet Explorer/ieproxy.dll" "${W_SYSTEM32_DLLS}" + + # Seeing is believing + case ${WINETRICKS_GUI} in + none) + w_warn "To start ie7, use the command \"${WINE}\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore.exe'" + ;; + *) + w_warn "Starting ie7. To start it later, use the command \"${WINE}\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore.exe'" + "${WINE}" "${W_PROGRAMS_WIN}\\Internet Explorer\\iexplore.exe" http://www.example.com/ > /dev/null 2>&1 & + ;; + esac + + unset _W_restore_z +} + +#---------------------------------------------------------------- + +w_metadata ie8 dlls \ + title="Internet Explorer 8" \ + publisher="Microsoft" \ + year="2009" \ + media="download" \ + conflicts="ie6 ie7" \ + file1="IE8-WindowsXP-x86-ENU.exe" \ + installed_file1="c:/windows/ie8_main.log" + +load_ie8() +{ + if [ "${W_ARCH}" = "win32" ]; then + # Bundled in Windows 7, so refuses to install. Works with XP: + w_set_winver winxp + else + # Bundled in Windows 7, so refuses to install. Works with Win2003: + w_set_winver win2k3 + fi + + # Unregister Wine IE + #if [ ! -f "$W_SYSTEM32_DLLS"/plugin.ocx ]; then + if grep -q -i "wine placeholder" "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe"; then + w_override_dlls builtin iexplore.exe + w_try "${WINE}" iexplore -unregserver + fi + + w_call msls31 + + # Change the override to the native so we are sure we use and register them + w_override_dlls native,builtin ieframe ieproxy itircl itss jscript msctf mshtml shdoclc shdocvw shlwapi urlmon wininet xmllite + + # IE8 installer will check the version number of iexplore.exe which causes IE8 installer to fail on wine-1.9.0+ + w_override_dlls native iexplore.exe + + # Bundled updspapi cannot work on Wine + w_override_dlls builtin updspapi + + # See https://bugs.winehq.org/show_bug.cgi?id=16013 + # Find instructions to create this file in dlls/wintrust/tests/crypt.c + w_download https://github.com/Winetricks/winetricks/raw/master/files/winetest.cat 5d18ab44fc289100ccf4b51cf614cc2d36f7ca053e557e2ba973811293c97d38 + + # Put a dummy catalog file in place + mkdir -p "${W_SYSTEM32_DLLS}"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\} + w_try cp -f "${W_CACHE}"/ie8/winetest.cat "${W_SYSTEM32_DLLS}"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\}/oem0.cat + + if [ "${W_ARCH}" = "win32" ]; then + w_download https://download.microsoft.com/download/C/C/0/CC0BD555-33DD-411E-936B-73AC6F95AE11/IE8-WindowsXP-x86-ENU.exe 5a2c6c82774bfe99b175f50a05b05bcd1fac7e9d0e54db2534049209f50cd6ef + else + w_download https://download.microsoft.com/download/7/5/4/754D6601-662D-4E39-9788-6F90D8E5C097/IE8-WindowsServer2003-x64-ENU.exe bcff753e92ceabf31cfefaa6def146335c7cb27a50b95cd4f4658a0c3326f499 + fi + + # Remove the fake DLLs from the existing WINEPREFIX + if [ -f "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe" ]; then + w_try mv "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe" "${W_PROGRAMS_X86_UNIX}/Internet Explorer/iexplore.exe.bak" + fi + + if [ "${W_ARCH}" = "win64" ]; then + if [ -f "${W_PROGRAMS_UNIX}/Internet Explorer/iexplore.exe" ]; then + w_try mv "${W_PROGRAMS_UNIX}/Internet Explorer/iexplore.exe" "${W_PROGRAMS_UNIX}/Internet Explorer/iexplore.exe.bak" + fi + fi + + # Replace the fake DLLs by copies from the bundle + for dll in browseui inseng itircl itss jscript mshtml shdoclc shdocvw shlwapi urlmon; do + test -f "${W_SYSTEM32_DLLS}"/${dll}.dll && + w_try mv "${W_SYSTEM32_DLLS}"/${dll}.dll "${W_SYSTEM32_DLLS}"/${dll}.dll.bak && + w_try_cabextract --directory="${W_SYSTEM32_DLLS}" "${W_CACHE}"/ie8/IE8-WindowsXP-x86-ENU.exe -F ${dll}.dll + if [ "${W_ARCH}" = "win64" ]; then + test -f "${W_SYSTEM64_DLLS}"/${dll}.dll && + w_try mv "${W_SYSTEM64_DLLS}"/${dll}.dll "${W_SYSTEM64_DLLS}"/${dll}.dll.bak + w_try_cabextract --directory="${W_SYSTEM64_DLLS}" "${W_CACHE}"/ie8/IE8-WindowsServer2003-x64-ENU.exe -F ${dll}.dll + fi + + done + + # KLUDGE: if / is writable (as on OS X?), having a Z: mapping to it + # causes ie7 to put temporary directories on Z:\. + # So hide it temporarily. This is not very robust! + if [ -w / ] && [ -h "${WINEPREFIX}/dosdevices/z:" ]; then + w_try rm -f "${WINEPREFIX}/dosdevices/z:.bak_wt" + w_try mv "${WINEPREFIX}/dosdevices/z:" "${WINEPREFIX}/dosdevices/z:.bak_wt" + _W_restore_z=1 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # FIXME: There's an option for /updates-noupdates to disable checking for updates, but that + # forces the install to fail on Wine. Not sure if it's an IE8 or Wine bug... + # FIXME: can't check status, as it always reports failure on wine? + if [ "${W_ARCH}" = "win32" ]; then + "${WINE}" IE8-WindowsXP-x86-ENU.exe ${W_OPT_UNATTENDED:+/quiet /forcerestart} + else + "${WINE}" IE8-WindowsServer2003-x64-ENU.exe ${W_OPT_UNATTENDED:+/quiet /forcerestart} + fi + + if [ "${_W_restore_z}" = 1 ]; then + # END KLUDGE: restore Z:, assuming that the user didn't kill us + w_try mv "${WINEPREFIX}/dosdevices/z:.bak_wt" "${WINEPREFIX}/dosdevices/z:" + fi + + # Work around DLL registration bug until ierunonce/RunOnce/wineboot is fixed + # FIXME: whittle down this list + for i in actxprxy.dll browseui.dll browsewm.dll cdfview.dll ddraw.dll \ + dispex.dll dsound.dll iedkcs32.dll iepeers.dll iesetup.dll \ + imgutil.dll inetcomm.dll isetup.dll jscript.dll laprxy.dll \ + mlang.dll msctf.dll mshtml.dll mshtmled.dll msi.dll msimtf.dll msident.dll \ + msoeacct.dll msrating.dll mstime.dll msxml3.dll occache.dll \ + ole32.dll oleaut32.dll olepro32.dll pngfilt.dll quartz.dll \ + rpcrt4.dll rsabase.dll rsaenh.dll scrobj.dll scrrun.dll \ + shdocvw.dll shell32.dll urlmon.dll vbscript.dll webcheck.dll \ + wshcon.dll wshext.dll asctrls.ocx hhctrl.ocx mscomct2.ocx \ + plugin.ocx proctexe.ocx tdc.ocx uxtheme.dll webcheck.dll wshom.ocx; do + "${WINE}" regsvr32 /i ${i} > /dev/null 2>&1 + if [ "${W_ARCH}" = "win64" ]; then + "${WINE64}" regsvr32 /i ${i} > /dev/null 2>&1 + fi + done + + if w_workaround_wine_bug 25648 "Setting TabProcGrowth=0 to avoid hang"; then + cat > "${W_TMP}"/set-tabprocgrowth.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main] +"TabProcGrowth"=dword:00000000 + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-tabprocgrowth.reg + fi + + # Builtin ieproxy is in system32, but ie8's lives in Program Files. Native + # CLSID path will get overwritten on prefix update. Setting ieproxy to + # native doesn't help because setupapi ignores DLL overrides. To work + # around this problem, copy native ieproxy to system32. + w_try_cp_dll "${W_PROGRAMS_X86_UNIX}/Internet Explorer/ieproxy.dll" "${W_SYSTEM32_DLLS}" + + if [ "${W_ARCH}" = "win64" ]; then + w_try_cp_dll "${W_PROGRAMS_UNIX}/Internet Explorer/ieproxy.dll" "${W_SYSTEM64_DLLS}" + fi + + # Seeing is believing + case ${WINETRICKS_GUI} in + none) + w_warn "To start ie8, use the command \"${WINE}\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore.exe'" + ;; + *) + w_warn "Starting ie8. To start it later, use the command \"${WINE}\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore.exe'" + "${WINE}" "${W_PROGRAMS_WIN}\\Internet Explorer\\iexplore.exe" http://www.example.com > /dev/null 2>&1 & + ;; + esac + + w_set_winver 'default' + + unset _W_restore_z +} + +#---------------------------------------------------------------- + +w_metadata kindle apps \ + title="Amazon Kindle" \ + publisher="Amazon" \ + year="2017" \ + media="download" \ + file1="KindleForPC-installer-1.16.44025.exe" \ + installed_exe1="${W_PROGRAMS_WIN}/Amazon/Kindle/Kindle.exe" \ + homepage="https://www.amazon.com/kindle-dbs/fd/kcp" + +load_kindle() +{ + if w_workaround_wine_bug 43508; then + w_warn "Using an older version of Kindle (1.16.44025) to work around https://bugs.winehq.org/show_bug.cgi?id=43508" + fi + + # Originally at: https://s3.amazonaws.com/kindleforpc/44025/KindleForPC-installer-1.16.44025.exe + w_download https://web.archive.org/web/20160817182927/https://s3.amazonaws.com/kindleforpc/44025/KindleForPC-installer-1.16.44025.exe 2655fa8be7b8f4659276c46ef9f3fede847135bf6e5c1de136c9de7af6cac1e2 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} + + if w_workaround_wine_bug 35041 && [ -n "${W_TASKSET}" ] ; then + w_warn "You may need to run with ${W_TASKSET} to avoid a libX11 crash." + fi + + if w_workaround_wine_bug 29045; then + w_call corefonts + fi + + w_warn "If kindle does not load for you, try increasing your open file limit" +} + +#---------------------------------------------------------------- + +w_metadata kobo apps \ + title="Kobo e-book reader" \ + publisher="Kobo" \ + year="2011" \ + media="download" \ + file1="KoboSetup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Kobo/Kobo.exe" \ + homepage="http://www.borders.com/online/store/MediaView_ereaderapps" + +load_kobo() +{ + w_download http://download.kobobooks.com/desktop/1/KoboSetup.exe 721e76c06820058422f06420400a0b1286662196d6178d70c4592fd8034704c4 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} +} + +#---------------------------------------------------------------- + +w_metadata mingw apps \ + title="Minimalist GNU for Windows, including GCC for Windows" \ + publisher="GNU" \ + year="2013" \ + media="download" \ + file1="mingw-get-setup.exe" \ + installed_exe1="c:/MinGW/bin/gcc.exe" \ + homepage="http://mingw.org/wiki/Getting_Started" + +load_mingw() +{ + w_download "https://downloads.sourceforge.net/mingw/files/mingw-get-setup.exe" aab27bd5547d35dc159288f3b5b8760f21b0cfec86e8f0032b49dd0410f232bc + + if test "${W_OPT_UNATTENDED}"; then + w_info "FYI: Quiet mode will install these mingw packages: 'gcc msys-base'" + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + run, ${file1} + WinWait, MinGW Installation Manager Setup Tool + if ( w_opt_unattended > 0 ) { + WinActivate + Sleep, 1000 + ControlClick, Button1 ; Install + ; Window title is blank + WinWait, , Step 1: Specify Installation Preferences + Sleep, 1000 + ControlClick, Button10 ; Continue + Sleep, 1000 + WinWait, , Step 2: Download and Set Up MinGW Installation Manager + ; This takes a while + WinWait, , Catalogue update completed + Sleep, 1000 + ControlClick, Button4 ; Continue + ; This window appears in background, but isn't active because of another popup + ; We may need to wait for that to disappear first + WinWait, MinGW Installation Manager + Sleep, 1000 + WinClose, MinGW Installation Manager + } + WinWaitClose, MinGW Installation Manager + " + + w_append_path 'C:\MinGW\bin' + w_try "${WINE}" mingw-get update + w_try "${WINE}" mingw-get install gcc msys-base +} + +#---------------------------------------------------------------- + +w_metadata mozillabuild apps \ + title="Mozilla build environment" \ + publisher="Mozilla Foundation" \ + year="2015" \ + media="download" \ + file1="MozillaBuildSetup-2.0.0.exe" \ + installed_file1="c:/mozilla-build/moztools/bin/nsinstall.exe" \ + homepage="https://wiki.mozilla.org/MozillaBuild" + +load_mozillabuild() +{ + w_download https://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-2.0.0.exe d5ffe52fe634fb7ed02e61041cc183c3af92039ee74e794f7ae83a408e4cf3f5 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" MozillaBuildSetup-2.0.0.exe ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata mpc apps \ + title="Media Player Classic - Home Cinema" \ + publisher="doom9 folks" \ + year="2014" \ + media="download" \ + file1="MPC-HC.1.7.5.x86.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/MPC-HC/mpc-hc.exe" \ + homepage="https://mpc-hc.sourceforge.io/" + +load_mpc() +{ + w_download https://downloads.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.7.5_x86/MPC-HC.1.7.5.x86.exe 1d690da5b330f723aea4a294d478828395d321b59fc680f2b971e8b16b8bd33d + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" MPC-HC.1.7.5.x86.exe ${W_OPT_UNATTENDED:+ /VERYSILENT} +} + +#---------------------------------------------------------------- + +w_metadata mspaint apps \ + title="MS Paint" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="windowsxp-kb978706-x86-enu_f4e076b3867c2f08b6d258316aa0e11d6822b8d7.exe" \ + installed_file1="c:/windows/mspaint.exe" + +load_mspaint() +{ + if w_workaround_wine_bug 657 "Native mspaint.exe from XP requires mfc42.dll"; then + w_call mfc42 + fi + + # Originally at: https://download.microsoft.com/download/0/A/4/0A40DF5C-2BAE-4C63-802A-84C33B34AC98/WindowsXP-KB978706-x86-ENU.exe + # Mirror list: http://www.filewatcher.com/_/?q=WindowsXP-KB978706-x86-ENU.exe + w_download http://download.windowsupdate.com/msdownload/update/software/secu/2010/01/windowsxp-kb978706-x86-enu_f4e076b3867c2f08b6d258316aa0e11d6822b8d7.exe 93ed34ab6c0d01a323ce10992d1c1ca27d1996fef82f0864d83e7f5ac6f9b24b + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}/${file1}" /q /x:"${W_TMP}/${file1}" + w_try cp -f "${W_TMP}/${file1}/SP3GDR/mspaint.exe" "${W_WINDIR_UNIX}"/mspaint.exe +} + +#---------------------------------------------------------------- + +w_metadata mt4 apps \ + title="Meta Trader 4" \ + year="2005" \ + media="download" \ + file1="mt4setup.exe" + +load_mt4() +{ + w_download https://web.archive.org/web/20160112133258/https://download.mql5.com/cdn/web/metaquotes.software.corp/mt4/mt4setup.exe?utm_campaign=www.metatrader4.com 96c82266e18cc4ada1bbc0cd0ada74c3a31d18914fb1a36626f4596c8bacb6f0 mt4setup.exe + + if w_workaround_wine_bug 7156 "${title} needs wingdings.ttf, installing opensymbol"; then + w_call opensymbol + fi + + # Opens a webpage + WINEDLLOVERRIDES="winebrowser.exe=" + export WINEDLLOVERRIDES + + # No documented silent install option, unfortunately. + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + Run, ${file1} + SetTitleMatchMode, RegEx + WinWaitActive, 4 Setup + Sleep, 200 + ControlClick, Button1 + Sleep, 200 + ControlClick, Button3 + WinWaitClose ; Wait for installer to finish + Process, Wait, Terminal.exe + WinWaitActive, ahk_class #32770 + Process, Close, Terminal.exe + " +} + +#---------------------------------------------------------------- + +w_metadata njcwp_trial apps \ + title="NJStar Chinese Word Processor trial" \ + publisher="NJStar" \ + year="2015" \ + media="download" \ + file1="njcwp610sw15918.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/NJStar Chinese WP6/NJStar.exe" \ + homepage="https://www.njstar.com/cms/njstar-chinese-word-processor" + +load_njcwp_trial() +{ + w_download http://ftp.njstar.com/sw/njcwp610sw15918.exe 7afa6dfc431f058d1397ac7100d5650b97347e1f37f81a2e2d2ee5dfdff4660b + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if test "${W_OPT_UNATTENDED}"; then + w_ahk_do " + SetTitleMatchMode, 2 + run ${file1} + WinWait, Setup, Welcome + ControlClick Button2 ; next + WinWait, Setup, License + ControlClick Button2 ; agree + WinWait, Setup, Install + ControlClick Button2 ; install + WinWait, Setup, Completing + ControlClick Button4 ; do not launch + ControlClick Button2 ; finish + WinWaitClose + " + else + w_try "${WINE}" "${file1}" + fi +} + +#---------------------------------------------------------------- + +w_metadata njjwp_trial apps \ + title="NJStar Japanese Word Processor trial" \ + publisher="NJStar" \ + year="2009" \ + media="download" \ + file1="njjwp610sw15918.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/NJStar Japanese WP6/NJStarJ.exe" \ + homepage="https://www.njstar.com/cms/njstar-japanese-word-processor" + +load_njjwp_trial() +{ + w_download http://ftp.njstar.com/sw/njjwp610sw15918.exe 7f36138c3d19539cb73d757cd42a6f7afebdaf9cfed0cf9bc483c33e519e2a26 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if test "${W_OPT_UNATTENDED}"; then + w_ahk_do " + SetTitleMatchMode, 2 + run ${file1} + WinWait, Setup, Welcome + ControlClick Button2 ; next + WinWait, Setup, License + ControlClick Button2 ; agree + WinWait, Setup, Install + ControlClick Button2 ; install + WinWait, Setup, Completing + ControlClick Button4 ; do not launch + ControlClick Button2 ; finish + WinWaitClose + " + else + w_try "${WINE}" "${file1}" + fi +} + +#---------------------------------------------------------------- + +w_metadata nook apps \ + title="Nook for PC (e-book reader)" \ + publisher="Barnes & Noble" \ + year="2011" \ + media="download" \ + file1="bndr2_setup_latest.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Barnes & Noble/BNDesktopReader/BNDReader.exe" \ + homepage="https://www.barnesandnoble.com/h/nook/apps" + +load_nook() +{ + # Dates from curl --head + # 2012/03/07: sha256sum 436616d99f0e2351909ab53d910b505c7a3fca248876ebb835fd7bce4aad9720 + w_download http://images.barnesandnoble.com/PResources/download/eReader2/bndr2_setup_latest.exe 436616d99f0e2351909ab53d910b505c7a3fca248876ebb835fd7bce4aad9720 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # Exits with 199 for some reason.. + "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} + + status=$? + case ${status} in + 0|199) echo "Successfully installed ${W_PACKAGE}" ;; + *) w_die "Failed to install ${W_PACKAGE}" ;; + esac +} + +#---------------------------------------------------------------- + +w_metadata npp apps \ + title="Notepad++" \ + publisher="Don Ho" \ + year="2019" \ + media="download" \ + file1="npp.7.7.1.Installer.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Notepad++/notepad++.exe" + +load_npp() +{ + w_download https://notepad-plus-plus.org/repository/7.x/7.7.1/npp.7.7.1.Installer.exe 6787c524b0ac30a698237ffb035f932d7132343671b8fe8f0388ed380d19a51c + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata office2003pro apps \ + title="Microsoft Office 2003 Professional" \ + publisher="Microsoft" \ + year="2002" \ + media="cd" \ + file1="setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Office/Office11/WINWORD.EXE" + +load_office2003pro() +{ + w_mount OFFICE11 + w_read_key + + w_ahk_do " + if ( w_opt_unattended > 0 ) { + run ${W_ISO_MOUNT_LETTER}:setup.exe /EULA_ACCEPT=YES /PIDKEY=${W_KEY} + } else { + run ${W_ISO_MOUNT_LETTER}:setup.exe + } + SetTitleMatchMode, 2 + WinWait,Microsoft Office 2003 Setup, Welcome + if ( w_opt_unattended > 0 ) { + Sleep 500 + WinWait,Microsoft Office 2003 Setup,Key + Sleep 500 + ControlClick Button1 ; Next + WinWait,Microsoft Office 2003 Setup,Initials + Sleep 500 + ControlClick Button1 ; Next + WinWait,Microsoft Office 2003 Setup,End-User + Sleep 500 + ControlClick Button1 ; I accept + ControlClick Button2 ; Next + WinWait,Microsoft Office 2003 Setup,Recommended + Sleep 500 + ControlClick Button7 ; Next + WinWait,Microsoft Office 2003 Setup,Summary + Sleep 500 + ControlClick Button1 ; Install + } + WinWait,Microsoft Office 2003 Setup,Completed + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button2 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata office2007pro apps \ + title="Microsoft Office 2007 Professional" \ + publisher="Microsoft" \ + year="2006" \ + media="cd" \ + file1="setup.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft Office/Office12/WINWORD.EXE" + +load_office2007pro() +{ + if w_workaround_wine_bug 14980 "Using native riched20"; then + w_override_app_dlls winword.exe n riched20 + w_override_app_dlls excel.exe n riched20 + w_override_app_dlls powerpnt.exe n riched20 + w_override_app_dlls msaccess.exe n riched20 + w_override_app_dlls outlook.exe n riched20 + w_override_app_dlls mspub.exe n riched20 + w_override_app_dlls infopath.exe n riched20 + fi + + w_mount OFFICE12 + w_read_key + + if [ -n "${W_OPT_UNATTENDED}" ]; then + # See + # https://blogs.technet.microsoft.com/office_resource_kit/2009/01/29/configure-a-silent-install-of-the-2007-office-system-with-config-xml/ + # https://www.symantec.com/connect/articles/office-2007-silent-installation-lessons-learned + cat > "${W_TMP}"/config.xml <<__EOF__ + + + + +__EOF__ + "${WINE}" ${W_ISO_MOUNT_LETTER}:setup.exe /config "${W_TMP_WIN}"\\config.xml + + status=$? + case ${status} in + 0|43) ;; + 78) + w_die "Installing ${W_PACKAGE} failed, product key ${W_KEY} \ + might be wrong. Try again without -q, or put correct key in \ + ${W_CACHE}/${W_PACKAGE}/key.txt and rerun." + ;; + *) + w_die "Installing ${W_PACKAGE} failed." + ;; + esac + + else + w_try "${WINE}" ${W_ISO_MOUNT_LETTER}:setup.exe + fi +} + +#---------------------------------------------------------------- + +w_metadata office2013pro apps \ + title="Microsoft Office 2013 Professional" \ + publisher="Microsoft" \ + year="2013" \ + media="download" \ + file1="setup.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft Office/Office15/WINWORD.EXE" + +load_office2013pro() +{ + w_package_unsupported_win64 + + if [ ! -x "$(command -v ntlm_auth 2>/dev/null)" ]; then + w_die "winbind (part of samba) is required for the installation" + fi + + # link from https://www.askvg.com/direct-download-link-microsoft-office-2013-professional-plus-free-trial/ + w_download https://web.archive.org/web/20130324022555/http://care.dlservice.microsoft.com/dl/download/2/9/C/29CC45EF-4CDA-4710-9FB3-1489786570A1/OfficeProfessionalPlus_x86_en-us.img 236f8faae3f979ec72592a63784bba2f0d614916350c44631221b88ae9dae206 "OFFICE15.iso" + + w_set_winver win7 + + w_call corefonts + w_call tahoma + + w_call riched20 + + + if w_workaround_wine_bug 43581 "Wine has problems parsing some regex strings during installation"; then + w_call msxml6 + fi + + case "${WINETRICKS_ISO_MOUNT}" in + # archivemount > 0.8.8: works + # archivemount <= 0.8.8: cannot finish installation due to path issue + archivemount) + _W_last_bad_ver=0.8.8 + _W_tool_ver="$(archivemount --version 2>&1 | head -n 1 | cut -d ' ' -f3)" + _W_pos_am_ver="$(printf "%s\\n%s" "${_W_tool_ver}" "${_W_last_bad_ver}" | sort -t. -k 1,1n -k 2,2n -k 3,3n | grep -n "^${_W_tool_ver}\$" | cut -d : -f1 | head -n 1)" + if test "${_W_pos_am_ver}" = "2"; then + W_USE_USERMOUNT=1 + else + w_warn "archivemount <= ${_W_last_bad_ver} has path issue and cannot be used." + fi + unset _W_last_bad_ver _W_tool_ver _W_pos_am_ver + ;; + # fuseiso: works + # hdiutil: partially tested (only mounting/unmounting and copying files) + *) W_USE_USERMOUNT=1 ;; + esac + w_mount OFFICE15 + + if [ -n "${W_OPT_UNATTENDED}" ]; then + cat > "${W_TMP}"/config.xml <<_EOF_ + + + +_EOF_ + w_try "${WINE}" "${W_ISO_MOUNT_LETTER}:${file1}" /config "${W_TMP_WIN}"\\config.xml + else + w_try "${WINE}" "${W_ISO_MOUNT_LETTER}:${file1}" + fi + + w_wineserver -w + w_umount + + w_warn "Microsoft Office 2013 is far away from running stable under wine 3.3. It should not be used in a productive environment." +} + +#---------------------------------------------------------------- + +w_metadata ollydbg110 apps \ + title="OllyDbg" \ + publisher="ollydbg.de" \ + year="2004" \ + media="download" \ + file1="odbg110.zip" \ + installed_file1="c:/ollydbg110/OLLYDBG.EXE" \ + homepage="http://ollydbg.de" + +load_ollydbg110() +{ + # The GUI is unreadable without having corefonts installed. + w_call corefonts + + w_download http://www.ollydbg.de/odbg110.zip 73b1770f28893dab22196eb58d45ede8ddf5444009960ccc0107d09881a7cd1e + w_try_unzip "${W_DRIVE_C}/ollydbg110" "${W_CACHE}/${W_PACKAGE}"/odbg110.zip +} + +#---------------------------------------------------------------- + +w_metadata ollydbg200 apps \ + title="OllyDbg" \ + publisher="ollydbg.de" \ + year="2010" \ + media="download" \ + file1="odbg200.zip" \ + installed_file1="c:/ollydbg200/ollydbg.exe" \ + homepage="http://ollydbg.de" + +load_ollydbg200() +{ + # The GUI is unreadable without having corefonts installed. + w_call corefonts + + w_download http://www.ollydbg.de/odbg200.zip 93dfd6348323db33f2005fc1fb8ff795256ae91d464dd186adc29c4314ed647c + w_try_unzip "${W_DRIVE_C}/ollydbg200" "${W_CACHE}/${W_PACKAGE}"/odbg200.zip +} + +#---------------------------------------------------------------- + +w_metadata ollydbg201 apps \ + title="OllyDbg" \ + publisher="ollydbg.de" \ + year="2013" \ + media="download" \ + file1="odbg201.zip" \ + installed_file1="c:/ollydbg201/ollydbg.exe" \ + homepage="http://ollydbg.de" + +load_ollydbg201() +{ + # The GUI is unreadable without having corefonts installed. + w_call corefonts + + w_download http://www.ollydbg.de/odbg201.zip 29244e551be31f347db00503c512058086f55b43c93c1ae93729b15ce6e087a5 + w_try_unzip "${W_DRIVE_C}/ollydbg201" "${W_CACHE}/${W_PACKAGE}"/odbg201.zip + + # ollydbg201 is affected by Wine bug 36012 if debug symbols are available. + # As a workaround native 'dbghelp' can be installed. We don't do this automatically + # because for some people it might work even without additional workarounds. + # Older versions of OllyDbg were not affected by this bug. +} + +#---------------------------------------------------------------- + +w_metadata openwatcom apps \ + title="Open Watcom C/C++ compiler (can compile win16 code!)" \ + publisher="Watcom" \ + year="2010" \ + media="download" \ + file1="open-watcom-c-win32-1.9.exe" \ + installed_file1="c:/WATCOM/owsetenv.bat" \ + homepage="http://www.openwatcom.org" + +load_openwatcom() +{ + # 2016/03/11: upstream http://www.openwatcom.org appears to be dead (404) + # 2019/06/14: now at https://sourceforge.net/projects/openwatcom/files/open-watcom-1.9/open-watcom-c-win32-1.9.exe/download + w_download https://sourceforge.net/projects/openwatcom/files/open-watcom-1.9/open-watcom-c-win32-1.9.exe 040c910aba304fdb5f39b8fe508cd3c772b1da1f91a58179fa0895e0b2bf190b + + if [ -n "${W_OPT_UNATTENDED}" ]; then + # Options documented at http://bugzilla.openwatcom.org/show_bug.cgi?id=898 + # But they don't seem to work on Wine, so jam them into setup.inf + # Pick smallest installation that supports 16-bit C and C++ + w_try_cd "${W_TMP}" + cp "${W_CACHE}/${W_PACKAGE}/${file1}" . + w_try_unzip . "${file1}" setup.inf + sed -i 's/tools16=.*/tools16=true/' setup.inf + w_try zip -f "${file1}" + w_try "${WINE}" "${file1}" -s + else + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" + fi + + if test ! -f "${W_DRIVE_C}"/WATCOM/binnt/wcc.exe; then + w_warn "c:/watcom/binnt/wcc.exe not found; you probably didn't select 16-bit tools, and won't be able to build win16test." + fi +} + +#---------------------------------------------------------------- + +w_metadata protectionid apps \ + title="Protection ID" \ + publisher="CDKiLLER & TippeX" \ + year="2016" \ + media="manual_download" \ + file1="ProtectionId.685.December.2016.rar" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/protection_id.exe" + +load_protectionid() +{ + w_download "https://web.archive.org/web/20181209123344/https://pid.wiretarget.com/?f=ProtectionId.685.December.2016.rar" 27a84d740c9fb96cc866438a2b5cd4afc350affc8b7a0122c28c651af3559aea ProtectionId.685.December.2016.rar + w_try_cd "${W_SYSTEM32_DLLS}" + w_try_unrar "${W_CACHE}/${W_PACKAGE}/${file1}" + + # ProtectionId.685.December.2016 has a different executable name than usual, this may need to be disabled on next update: + w_try mv Protection_ID.eXe protection_id_.exe + w_try mv protection_id_.exe protection_id.exe +} + +#---------------------------------------------------------------- + +w_metadata psdk2003 apps \ + title="MS Platform SDK 2003" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="5.2.3790.1830.15.PlatformSDK_Svr2003SP1_rtm.img" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Microsoft Platform SDK/SetEnv.Cmd" + +load_psdk2003() +{ + w_package_unsupported_win64 + + w_call mfc42 + + # https://www.microsoft.com/en-us/download/details.aspx?id=15656 + w_download https://download.microsoft.com/download/7/5/e/75ec7f04-4c8c-4f38-b582-966e76602643/5.2.3790.1830.15.PlatformSDK_Svr2003SP1_rtm.img 7ef138b07a8ed2e008371d8602900eb68e86ac2a832d16b53f462a9e64f24d53 + + # Unpack ISO (how handy that 7z can do this!) + # Only the Windows version of 7z can handle .img files? + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + w_try_cd "${W_PROGRAMS_X86_UNIX}"/7-Zip + w_try "${WINE}" 7z.exe x -y -o"${W_TMP_WIN}" "${W_CACHE_WIN}\\psdk2003\\5.2.3790.1830.15.PlatformSDK_Svr2003SP1_rtm.img" + + w_try_cd "${W_TMP}/Setup" + + # Sanity check... + w_verify_sha256sum d2605ae6f35a7fcc209e1d8dfbdfdb42afcb61e7d173f58fd608ae31db4ab1e7 PSDK-x86.msi + + w_try "${WINE}" msiexec /i PSDK-x86.msi ${W_OPT_UNATTENDED:+/qb} +} + +#---------------------------------------------------------------- + +w_metadata psdkwin71 apps \ + title="MS Windows 7.1 SDK" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="winsdk_web.exe" \ + installed_exe1="C:/Program Files/Microsoft SDKs/Windows/v7.1/Bin/SetEnv.Cmd" + +load_psdkwin71() +{ + w_call dotnet20 + w_call dotnet40 + w_call mfc42 # need mfc42u, or setup will abort + # https://www.microsoft.com/en-us/download/details.aspx?id=3138 + w_download https://download.microsoft.com/download/A/6/A/A6AC035D-DA3F-4F0C-ADA4-37C8E5D34E3D/winsdk_web.exe 9ea8d82a66a33946e8673df92d784971b35b8f65ade3e0325855be8490e3d51d + + # don't have a working unattended recipe. Maybe we'll have to + # do an AutoHotKey script until Microsoft gets its act together: + # https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/c053b616-7d5b-405d-9841-ec465a8e21d5/ + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" winsdk_web.exe + + if w_workaround_wine_bug 21362; then + # Assume user installed in default location + cat > "${W_TMP}"/set-psdk71.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs] + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows] +"CurrentVersion"="v7.1" +"CurrentInstallFolder"="C:\\\\Program Files\\\\Microsoft SDKs\\\\Windows\\\\v7.1\\\\" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows\\v7.1] +"InstallationFolder"="C:\\\\Program Files\\\\Microsoft SDKs\\\\Windows\\\\v7.1\\\\" +"ProductVersion"="7.0.7600.0.30514" +"ProductName"="Microsoft Windows SDK for Windows 7 (7.0.7600.0.30514)" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows\\v7.1\\WinSDKBuild] +"ComponentName"="Microsoft Windows SDK Headers and Libraries" +"InstallationFolder"="C:\\\\Program Files\\\\Microsoft SDKs\\\\Windows\\\\v7.1\\\\" +"ProductVersion"="7.0.7600.0.30514" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows\\v7.1\\WinSDKTools] +"ComponentName"="Microsoft Windows SDK Headers and Libraries" +"InstallationFolder"="C:\\\\Program Files\\\\Microsoft SDKs\\\\Windows\\\\v7.1\\\\bin\\\\" +"ProductVersion"="7.0.7600.0.30514" + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows\\v7.1\\WinSDKWin32Tools] +"ComponentName"="Microsoft Windows SDK Utilities for Win32 Development" +"InstallationFolder"="C:\\\\Program Files\\\\Microsoft SDKs\\\\Windows\\\\v7.1\\\\bin\\\\" +"ProductVersion"="7.0.7600.0.30514" +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-psdk71.reg + fi +} + +#---------------------------------------------------------------- + +w_metadata qq apps \ + title="QQ 8.9.6(Chinese chat app)" \ + publisher="Tencent" \ + year="2017" \ + media="download" \ + file1="QQ8.9.6.exe" \ + file2="QQ.tar.gz"\ + installed_exe1="${W_PROGRAMS_X86_WIN}/Tencent/QQ/Bin/QQScLauncher.exe" \ + homepage="https://www.qq.com/" \ + unattended="no" + +load_qq() +{ + w_download https://dldir1.qq.com/qqfile/qq/QQ8.9.6/22404/QQ8.9.6.exe d207f49a642be21c4e1b14fc9f4cf47a6a9a2718afbc8bd0685b607b65424ef6 + w_download https://hillwoodhome.net/wine/QQ.tar.gz eb5cd6371eb75ec9e2fc0271199df05cbb9f38a60c2e81d5d8ac7daeb40aba62 + + if w_workaround_wine_bug 5162 "Installing native riched20 to work around can't input username."; then + w_call riched20 + fi + + # Make sure chinese fonts are available + w_call fakechinese + + # uses mfc42u.dll + w_call mfc42 + + if w_workaround_wine_bug 38171 "Installing desktop file to work around bug"; then + w_try_cd "${W_TMP}/" + tar -zxf "${W_CACHE}/qq/QQ.tar.gz" + mkdir -p "${HOME}/.local/share/applications/wine/Programs/腾讯软件/QQ" + mkdir -p "${HOME}/.local/share/icons/hicolor/48x48/apps" + mkdir -p "${HOME}/.local/share/icons/hicolor/256x256/apps" + w_try mv QQ/腾讯QQ.desktop ~/.local/share/applications/wine/Programs/腾讯软件/QQ + w_try mv QQ/48x48/QQ.png ~/.local/share/icons/hicolor/48x48/apps + w_try mv QQ/256x256/QQ.png ~/.local/share/icons/hicolor/256x256/apps + # shellcheck disable=SC1001 + echo Exec=env WINEPREFIX="${WINEPREFIX}" "${WINE}" \""${W_PROGRAMS_X86_WIN}"/Tencent/QQ/bin/QQScLauncher.exe\" >> "${HOME}/.local/share/applications/wine/Programs/腾讯软件/QQ/腾讯QQ.desktop" + fi + + if w_workaround_wine_bug 37680 "Disable txplatform.exe to work around QQ can't be quit cleanly"; then + w_override_dlls disabled txplatform.exe + fi + + # Disable update, stay on the version. + w_override_dlls disabled txupd.exe + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata qqintl apps \ + title="QQ International Instant Messenger 2.11" \ + publisher="Tencent" \ + year="2014" \ + media="download" \ + file1="QQIntl2.11.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Tencent/QQIntl/Bin/QQ.exe" \ + homepage="https://www.imqq.com/" \ + unattended="no" + +load_qqintl() +{ + w_download https://dldir1.qq.com/qqfile/QQIntl/QQi_PC/QQIntl2.11.exe a08e5d8432ad41745cfe92479a9a0c3328a546c27f05486392ca7b77b1cb02a8 + + if w_workaround_wine_bug 33086 "Installing native riched20 to allow typing in username"; then + w_call riched20 + fi + + if w_workaround_wine_bug 37617 "Installing native wininet to work around crash"; then + w_call wininet + fi + + if w_workaround_wine_bug 37680 "Disable txplatform.exe to work around QQ can't be quit cleanly"; then + w_override_dlls disabled txplatform.exe + fi + + # Make sure chinese fonts are available + w_call fakechinese + + # wants mfc80u.dll + w_call vcrun2005 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" +} + +#---------------------------------------------------------------- + +w_metadata safari apps \ + title="Safari" \ + publisher="Apple" \ + year="2010" \ + media="download" \ + file1="SafariSetup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Safari/Safari.exe" + +load_safari() +{ + w_download http://appldnld.apple.com.edgesuite.net/content.info.apple.com/Safari5/061-7138.20100607.Y7U87/SafariSetup.exe a5b44032fe9cd0ede8571023912c91b1dcca106ad6a65a822be9ebd405510939 + + if [ -n "${W_OPT_UNATTENDED}" ]; then + w_warn "Safari's silent install is broken under Wine. See https://bugs.winehq.org/show_bug.cgi?id=23493. You should do a regular install if you want to use Safari." + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE_MULTI}" SafariSetup.exe ${W_OPT_UNATTENDED:+/qn} +} + +#---------------------------------------------------------------- + +w_metadata sketchup apps \ + title="SketchUp 8" \ + publisher="Google" \ + year="2012" \ + media="download" \ + file1="GoogleSketchUpWEN.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Google/Google SketchUp 8/SketchUp.exe" + +load_sketchup() +{ + w_download https://dl.google.com/sketchup/GoogleSketchUpWEN.exe e50c1b36131d72437eb32a124a5208fad22dc22b843683cfb520e1ef172b8352 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run GoogleSketchUpWEN.exe + WinWait, SketchUp, Welcome + if ( w_opt_unattended > 0 ) { + Sleep 4000 + Send {Enter} + WinWait, SketchUp, License + Sleep 1000 + ControlClick Button1 ; accept + Sleep 1000 + ControlClick Button4 ; Next + WinWait, SketchUp, Destination + Sleep 1000 + ControlClick Button1 ; Next + WinWait, SketchUp, Ready + Sleep 1000 + ControlClick Button1 ; Install + } + WinWait, SketchUp, Completed + if ( w_opt_unattended > 0 ) { + Sleep 1000 + ControlClick Button1 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata steam apps \ + title="Steam" \ + publisher="Valve" \ + year="2010" \ + media="download" \ + file1="SteamInstall.msi" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/Steam.exe" + +load_steam() +{ + # 2016/10/28: 029f918a29b2b311711788e8a477c8de529c11d7dba3caf99cbbde5a983efdad + # 2018/06/01: 3bc6942fe09f10ed3447bccdcf4a70ed369366fef6b2c7f43b541f1a3c5d1c51 + # 2021/03/27: 874788b45dfc043289ba05387e83f27b4a046004a88a4c5ee7c073187ff65b9d + # 2022/03/27: 3b616cb0beaacffb53884b5ba0453312d2577db598d2a877a3b251125fb281a1 + w_download http://media.steampowered.com/client/installer/SteamSetup.exe 3b616cb0beaacffb53884b5ba0453312d2577db598d2a877a3b251125fb281a1 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_try "${WINE}" SteamSetup.exe ${W_OPT_UNATTENDED:+ /S} + + # Not all users need this disabled, but let's play it safe for now + if w_workaround_wine_bug 22053 "Disabling gameoverlayrenderer to prevent game crashes on some machines."; then + w_override_dlls disabled gameoverlayrenderer + fi + + if w_workaround_wine_bug 44985 "Disabling libglesv2 to make Store and Library function correctly."; then + w_override_dlls disabled libglesv2 + fi + + # Otherwise Steam Store and Library don't show + w_call corefonts +} + +#---------------------------------------------------------------- + +w_metadata uplay apps \ + title="Uplay" \ + publisher="Ubisoft" \ + year="2013" \ + media="download" \ + file1="UplayInstaller.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Ubisoft/Ubisoft Game Launcher/Uplay.exe" + +load_uplay() +{ + # Changes too frequently, don't check anymore + w_download https://static3.cdn.ubi.com/orbit/launcher_installer/UplayInstaller.exe + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # NSIS installer + w_try "${WINE}" UplayInstaller.exe ${W_OPT_UNATTENDED:+ /S} +} + +#---------------------------------------------------------------- + +w_metadata utorrent apps \ + title="µTorrent 2.2.1" \ + publisher="BitTorrent" \ + year="2011" \ + media="manual_download" \ + file1="utorrent_2.2.1.exe" \ + installed_exe1="c:/windows/utorrent.exe" + +load_utorrent() +{ + # BitTorrent client supported on Windows, OS X, Linux through Wine + # 2012/03/07: sha256sum ec2c086ff784b06e4ff05243164ddb768b81ee32096afed6d5e574ff350b619e + w_download_manual "https://www.oldapps.com/utorrent.php?old_utorrent=38" utorrent_2.2.1.exe ec2c086ff784b06e4ff05243164ddb768b81ee32096afed6d5e574ff350b619e + + w_try cp -f "${W_CACHE}/utorrent/${file1}" "${W_WINDIR_UNIX}"/utorrent.exe +} + +#---------------------------------------------------------------- + +w_metadata utorrent3 apps \ + title="µTorrent 3.4" \ + publisher="BitTorrent" \ + year="2011" \ + media="download" \ + file1="uTorrent.exe" \ + installed_exe1="c:/users/${LOGNAME}/Application Data/uTorrent/uTorrent.exe" + +load_utorrent3() +{ + # 2017/03/26: sha256sum 482cfc0759f484ad4e6547cc160ef3f08057cb05969242efd75a51525ab9bd92 + w_download https://download-new.utorrent.com/endpoint/utorrent/os/windows/track/stable/ 482cfc0759f484ad4e6547cc160ef3f08057cb05969242efd75a51525ab9bd92 uTorrent.exe + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + # If you don't use /PERFORMINSTALL, it just runs µTorrent + # FIXME: That's no longer a quiet option, though.. + "${WINE}" "${file1}" /PERFORMINSTALL /NORUN + + # dang installer exits with status 1 on success + status=$? + case ${status} in + 0|1) ;; + *) w_die "Note: utorrent installer returned status '${status}'. Aborting." ;; + esac +} + +#---------------------------------------------------------------- + +w_metadata vc2005express apps \ + title="MS Visual C++ 2005 Express" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="VC.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Visual Studio 8/Common7/IDE/VCExpress.exe" + +load_vc2005express() +{ + # Thanks to https://blogs.msdn.microsoft.com/astebner/2006/03/14/how-to-create-an-installable-layout-for-visual-studio-2005-express-editions/ + # for the recipe + w_call dotnet20 + + # https://blogs.msdn.microsoft.com/astebner/2006/03/14/how-to-create-an-installable-layout-for-visual-studio-2005-express-editions/ + # https://go.microsoft.com/fwlink/?linkid=57034 + w_download https://download.microsoft.com/download/A/9/1/A91D6B2B-A798-47DF-9C7E-A97854B7DD18/VC.iso 5ae700d0285d94ec6df23828c7dc9f5634cd250363bed72e486916af22ff9545 + + # Unpack ISO (how handy that 7z can do this!) + w_try_7z "${W_TMP}" "${W_CACHE}"/vc2005express/VC.iso + + w_try_cd "${W_TMP}" + if [ -n "${W_OPT_UNATTENDED}" ]; then + chmod +x Ixpvc.exe + # Add /qn after ReallySuppress for a really silent install (but then you won't see any errors) + + w_try "${WINE}" Ixpvc.exe /t:"${W_TMP_WIN}" /q:a /c:"msiexec /i vcsetup.msi VSEXTUI=1 ADDLOCAL=ALL REBOOT=ReallySuppress" + + else + w_try "${WINE}" setup.exe + w_ahk_do " + SetTitleMatchMode, 2 + WinWait, Visual C++ 2005 Express Edition Setup + WinWaitClose, Visual C++ 2005 Express Edition Setup + " + fi +} + +#---------------------------------------------------------------- + +w_metadata vc2005expresssp1 apps \ + title="MS Visual C++ 2005 Express SP1" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="VS80sp1-KB926748-X86-INTL.exe" + +load_vc2005expresssp1() +{ + w_call vc2005express + + # https://www.microsoft.com/en-us/download/details.aspx?id=804 + if w_workaround_wine_bug 37375; then + w_warn "Installer currently fails" + fi + w_download https://download.microsoft.com/download/7/7/3/7737290f-98e8-45bf-9075-85cc6ae34bf1/VS80sp1-KB926748-X86-INTL.exe a959d1ea52674b5338473be32a1370f9ec80df84629a2ed3471aa911b42d9e50 + w_try ${WINE} "${W_CACHE}"/vc2005expresssp1/VS80sp1-KB926748-X86-INTL.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata vc2005trial apps \ + title="MS Visual C++ 2005 Trial" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="En_vs_2005_vsts_180_Trial.img" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Visual Studio 8/Common7/IDE/devenv.exe" + +load_vc2005trial() +{ + w_call dotnet20 + + # Without mfc42.dll, pidgen.dll won't load, and the app claims "A trial edition is already installed..." + w_call mfc42 + + w_download https://download.microsoft.com/download/6/f/5/6f5f7a01-50bb-422d-8742-c099c8896969/En_vs_2005_vsts_180_Trial.img 3ae9f611c60c64d82e1fa9c94714aa6b6c10f6c2c05446e14b5afb5a257f86dc + + # Unpack ISO (how handy that 7z can do this!) + # Only the Windows version of 7z can handle .img files? + WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip + w_try_cd "${W_PROGRAMS_X86_UNIX}"/7-Zip + w_try "${WINE}" 7z.exe x -y -o"${W_TMP_WIN}" "${W_CACHE_WIN}\\vc2005trial\\En_vs_2005_vsts_180_Trial.img" + + w_try_cd "${W_TMP}" + + # Sanity check... + w_verify_sha256sum e1d5ddd4bad46c2efe8105f8d73bd62857f6218942d3b9ac5da0e1a6a0a217e0 vs/wcu/runmsi.exe + + w_try_cd vs/Setup + w_ahk_do " + SetTitleMatchMode 2 + run setup.exe + winwait, Visual Studio, Setup is loading + if ( w_opt_unattended > 0 ) { + winwait, Visual Studio, Loading completed + sleep 1000 + controlclick, button2 + winwait, Visual Studio, Select features + sleep 1000 + controlclick, button38 + sleep 1000 + controlclick, button40 + winwait, Visual Studio, You have chosen + sleep 1000 + controlclick, button1 + winwait, Visual Studio, Select features + sleep 1000 + controlclick, button11 + } + ; this can take a while + winwait, Finish Page + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, button2 + } + winwaitclose, Finish Page + " +} + +#---------------------------------------------------------------- + +w_metadata vc2008express apps \ + title="MS Visual C++ 2008 Express" \ + publisher="Microsoft" \ + year="2008" \ + media="download" \ + file1="VS2008ExpressENUX1397868.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Visual Studio 9.0/Common7/IDE/VCExpress.exe" + +load_vc2008express() +{ + w_verify_cabextract_available + + w_call dotnet35 + + # This is the version without SP1 baked in. (SP1 requires dotnet35sp1, which doesn't work yet.) + w_download https://download.microsoft.com/download/8/B/5/8B5804AD-4990-40D0-A6AA-CE894CBBB3DC/VS2008ExpressENUX1397868.iso 632318ef0df5bad58fcb99852bd251243610e7a4d84213c45b4f693605a13ead + + # Unpack ISO + w_try_7z "${W_TMP}" "${W_CACHE}"/vc2008express/VS2008ExpressENUX1397868.iso + + # See also https://blogs.msdn.microsoft.com/astebner/2008/04/25/a-simpler-way-to-silently-install-visual-studio-2008-express-editions-with-a-caveat/ + w_try_cd "${W_TMP}"/VCExpress + w_try "${WINE}" setup.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata vc2010express apps \ + title="MS Visual C++ 2010 Express" \ + publisher="Microsoft" \ + year="2010" \ + media="download" \ + file1="VS2010Express1.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Visual Studio 10.0/Common7/IDE/VCExpress.exe" + +load_vc2010express() +{ + # Originally at: https://download.microsoft.com/download/1/E/5/1E5F1C0A-0D5B-426A-A603-1798B951DDAE/VS2010Express1.iso + # Mirror list at: http://www.filewatcher.com/_/?q=VS2010Express1.iso + # Formerly at: ftp://www.daba.lv/pub/Programmeeshana/VisualStudio/VS2010Express1.iso a9d5dcdf55e539a06547a8ebbc63d55dc167113e09ee9e42096ab9098313039b + w_download https://debian.fmi.uni-sofia.bg/~aangelov/VS2010Express1.iso a9d5dcdf55e539a06547a8ebbc63d55dc167113e09ee9e42096ab9098313039b + + # Unpack ISO + w_try_7z "${W_TMP}" "${W_CACHE}"/vc2010express/VS2010Express1.iso + w_try_cd "${W_TMP}"/VCExpress + + # Uninstall wine-mono, installer doesn't attempt to install native .Net if mono is installed, + # Then the installer throws an exception and fails + # See https://github.com/Winetricks/winetricks/issues/1165 + w_call remove_mono + + # dotnet40 leaves winver at win2k, which causes vc2010 to abort on + # start because it looks for c:\users\$LOGNAME\Application Data + w_set_winver winxp + + if w_workaround_wine_bug 12501 "Installing mspatcha to work around bug in SQL Server install"; then + w_call mspatcha + fi + + w_try ${WINE} setup.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +w_metadata vlc apps \ + title="VLC media player 2.2.1" \ + publisher="VideoLAN" \ + year="2015" \ + media="download" \ + file1="vlc-2.2.1-win32.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/VideoLAN/VLC/vlc.exe" \ + homepage="https://www.videolan.org/vlc/" + +load_vlc() +{ + w_download https://get.videolan.org/vlc/2.2.1/win32/vlc-2.2.1-win32.exe 2eaa3881b01a2464d2a155ad49cc78162571dececcef555400666c719a60794d + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} +} + +#---------------------------------------------------------------- + +w_metadata winamp apps \ + title="Winamp" \ + publisher="Radionomy (AOL (Nullsoft))" \ + year="2013" \ + media="download" \ + file1="winamp5666_full_all_redux.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Winamp/winamp.exe" \ + homepage="https://www.winamp.com/" + +load_winamp() +{ + w_info "may send information while installing, see https://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx?threatid=159633" + + # 2019/12/11: previously at https://winampplugins.co.uk/Winamp/winamp5666_full_all_redux.exe + w_download http://www.meggamusic.co.uk/winamp/winamp5666_full_all_redux.exe ea9a6ba81475d49876d0b8b300d93f28f7959b8e99ce4372dbde746567e14002 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if [ -n "${W_OPT_UNATTENDED}" ]; then + w_ahk_do " + SetWinDelay 500 + SetTitleMatchMode, 2 + Run ${file1} + WinWait, Installer Language, Please select + Sleep 500 + ControlClick, Button1 ; OK + WinWait, Winamp Installer, Welcome to the Winamp installer + Sleep 500 + ControlClick, Button2 ; Next + WinWait, Winamp Installer, License Agreement + Sleep 500 + ControlClick, Button2 ; I Agree + WinWait, Winamp Installer, Choose Install Location + Sleep 500 + ControlClick, Button2 ; Next + WinWait, Winamp Installer, Choose Components + Sleep 500 + ControlClick, Button2 ; Next for Full install + WinWait, Winamp Installer, Choose Start Options + Sleep 500 + ControlClick, Button4 ; uncheck start menu entry + Sleep 500 + ControlClick, Button5 ; uncheck ql icon + Sleep 500 + ControlClick, Button6 ; uncheck deskto icon + Sleep 500 + ControlClick, Button2 ; Install + WinWait, Winamp Installer, Installation Complete + Sleep 500 + ControlClick, Button4 ; uncheck launch when complete + Sleep 500 + ControlClick, Button2 ; Finish + WinWaitClose + " + else + w_try "${WINE}" "${file1}" + fi +} + +#---------------------------------------------------------------- + +w_metadata wme9 apps \ + title="MS Windows Media Encoder 9 (broken in Wine)" \ + publisher="Microsoft" \ + year="2002" \ + media="download" \ + file1="WMEncoder.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Windows Media Components/Encoder/wmenc.exe" + +load_wme9() +{ + w_package_unsupported_win64 + + # See also https://www.microsoft.com/en-us/download/details.aspx?id=17792 + # Formerly at: https://download.microsoft.com/download/8/1/f/81f9402f-efdd-439d-b2a4-089563199d47/WMEncoder.exe + # Mirror list: http://www.filewatcher.com/_/?q=WMEncoder.exe + # 2018-06-11: https://people.ok.ubc.ca/mberger/MiscSW/WMEncoder.exe + # 2022-03-31: http://galinet13.free.fr/codec/WMEncoder.exe + w_download http://galinet13.free.fr/codec/WMEncoder.exe 19d1610d12b51c969f64703c4d3a76aae30dee526bae715381b5f3369f717d76 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" WMEncoder.exe ${W_OPT_UNATTENDED:+/q} +} + +#---------------------------------------------------------------- + +# helper - not useful by itself +load_wm9codecs() +{ + # Note: must install WMP9 or 10 first, or installer will complain and abort. + + # The Microsoft page says that is supports XP, but in both 32/64 prefixes, it gives a message box saying it requires win98/winme/win2k + w_package_unsupported_win64 + + # See https://www.microsoft.com/en-us/download/details.aspx?id=507 + # Used by direct calls from load_wmp9, so we have to specify cache directory. + # http://birds.camden.rutgers.edu/ + w_download_to wm9codecs http://birds.camden.rutgers.edu/WM9Codecs9x.exe f25adf6529745a772c4fdd955505e7fcdc598b8a031bb0ce7e5856da5e5fcc95 + w_try_cd "${W_CACHE}/wm9codecs" + w_set_winver win2k + w_try "${WINE}" WM9Codecs9x.exe ${W_OPT_UNATTENDED:+/q} +} + +w_metadata wmp9 dlls \ + title="Windows Media Player 9" \ + publisher="Microsoft" \ + year="2003" \ + media="download" \ + file1="MPSetup.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}"/l3codeca.acm + +load_wmp9() +{ + w_skip_windows wmp9 && return + + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=52772" 6.6 + + # Not really expected to work well yet; see + # https://appdb.winehq.org/appview.php?versionId=1449 + + # This version of Windows Media Player can be installed only on Windows 98 Second Edition, Windows Millennium Edition, Windows 2000, Windows XP, and Windows .NET Server. + + w_call wsh57 + + w_set_winver winxp + + # See also https://support.microsoft.com/en-us/help/18612/windows-media-player + w_download https://web.archive.org/web/20180404022333if_/download.microsoft.com/download/1/b/c/1bc0b1a3-c839-4b36-8f3c-19847ba09299/MPSetup.exe 678c102847c18a92abf13c3fae404c3473a0770c871a046b45efe623c9938fc0 + + # remove builtin placeholders to allow update + rm -f "${W_SYSTEM32_DLLS}"/wmvcore.dll "${W_SYSTEM32_DLLS}"/wmp.dll + rm -f "${W_PROGRAMS_X86_UNIX}/Windows Media Player/wmplayer.exe" + # need native overrides to allow update and later checks to succeed + w_override_dlls native l3codeca.acm wmp wmplayer.exe wmvcore + + # FIXME: should we override quartz? Builtin crashes when you play + # anything, but maybe that's bug 30557 and only affects new systems? + # Wine's pidgen is too stubby, crashes, see Wine bug 31111 + w_override_app_dlls MPSetup.exe native pidgen + + w_try_cd "${W_CACHE}"/"${W_PACKAGE}" + if [ "${W_ARCH}" = "win64" ]; then + w_try cabextract -d "${W_TMP}" ./MPSetup.exe + w_try_cd "${W_TMP}" + w_try sed -i 's/IsWow64Process/IsNow64Process/' setup_wm.exe + w_try "${WINE}" setup_wm.exe ${W_OPT_UNATTENDED:+/Quiet} + w_warn "wm9codecs is not supported in win64 prefixes. If you need those codecs, reinstall wmp9 in a 32-bit prefix." + else + w_try "${WINE}" MPSetup.exe ${W_OPT_UNATTENDED:+/q} + load_wm9codecs + fi + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata wmp10 dlls \ + title="Windows Media Player 10" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="MP10Setup.exe" \ + installed_file1="${W_SYSTEM32_DLLS_WIN}/l3codecp.acm" + +load_wmp10() +{ + w_package_unsupported_win64 + + # FIXME: what versions of Windows are really bundled with wmp10? + w_skip_windows wmp10 && return + + # See https://appdb.winehq.org/appview.php?iVersionId=3212 + w_call wsh57 + + # https://www.microsoft.com/en-us/download/details.aspx?id=20426 + w_download https://web.archive.org/web/20200803205216/https://download.microsoft.com/download/1/2/a/12a31f29-2fa9-4f50-b95d-e45ef7013f87/MP10Setup.exe c1e71784c530035916aad5b09fa002abfbb7569b75208dd79351f29c6d197e03 + + w_set_winver winxp + + # remove builtin placeholders to allow update + rm -f "${W_SYSTEM32_DLLS}"/wmvcore.dll "${W_SYSTEM32_DLLS}"/wmp.dll + rm -f "${W_PROGRAMS_X86_UNIX}/Windows Media Player/wmplayer.exe" + # need native overrides to allow update and later checks to succeed + w_override_dlls native l3codeca.acm wmp wmplayer.exe wmvcore + + # Crashes on exit, but otherwise ok; see https://bugs.winehq.org/show_bug.cgi?id=12633 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try cabextract -d "${W_TMP}" ./MP10Setup.exe + w_try_cd "${W_TMP}" + "${WINE}" setup_wm.exe ${W_OPT_UNATTENDED:+/Quiet} + + # Disable WMP's services, since they depend on unimplemented stuff, they trigger the GUI debugger several times + w_try_regedit /D "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Cdr4_2K" + w_try_regedit /D "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Cdralw2k" + + load_wm9codecs + + w_set_winver 'default' +} + +#---------------------------------------------------------------- + +w_metadata wmp11 dlls \ + title="Windows Media Player 11" \ + publisher="Microsoft" \ + year="2007" \ + media="download" \ + file1="wmp11-windowsxp-x86-enu.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Windows Media Player/wmplayer.exe" + +load_wmp11() +{ + # See https://appdb.winehq.org/objectManager.php?sClass=version&iId=32057 + w_call wsh57 + w_call gdiplus + + if [ "${W_ARCH}" = "win32" ]; then + # https://appdb.winehq.org/objectManager.php?sClass=version&iId=8150 + w_download https://web.archive.org/web/20170628063001/http://download.microsoft.com/download/0/9/5/0953e553-3bb6-44b1-8973-106f1b7e5049/wmp11-windowsxp-x86-enu.exe ffd321a441a67001a893f3bde4bb1afba07d4d2c9659bfdb0fbb057e7945d970 + installer_exe=wmp11-windowsxp-x86-enu.exe + wmf_exe=wmfdist11.exe + wmf_exe=wmp11.exe + elif [ "${W_ARCH}" = "win64" ]; then + # https://appdb.winehq.org/objectManager.php?sClass=version&iId=32057 + w_download https://web.archive.org/web/20190512112704/https://download.microsoft.com/download/3/0/8/3080C52C-2517-43DE-BDB4-B7EAFD88F084/wmp11-windowsxp-x64-enu.exe 5af407cf336849aff435044ec28f066dd523bbdc22d1ce7aaddb5263084f5526 + installer_exe=wmp11-windowsxp-x64-enu.exe + wmf_exe=wmfdist11-64.exe + wmp_exe=wmp11-64.exe + fi + + w_set_winver winxp + + # remove builtin placeholders to allow update + w_try rm -f "${W_PROGRAMS_UNIX}/Windows Media Player/wmplayer.exe" \ + "${W_SYSTEM32_DLLS}"/wmp.dll "${W_SYSTEM32_DLLS}"/wmvcore.dll "${W_SYSTEM32_DLLS}"/mfplat.dll "${W_SYSTEM32_DLLS}"/wmasf.dll \ + "${W_SYSTEM32_DLLS}"/wmpnssci.dll \ + "${W_SYSTEM64_DLLS}"/wmp.dll "${W_SYSTEM64_DLLS}"/wmvcore.dll "${W_SYSTEM64_DLLS}"/mfplat.dll "${W_SYSTEM64_DLLS}"/wmasf.dll \ + "${W_SYSTEM64_DLLS}"/wmpnssci.dll + + # need native overrides to allow update and later checks to succeed + w_override_dlls native l3codeca.acm mfplat wmasf wmp wmplayer.exe wmpnssci wmvcore + + w_try_cd "${W_TMP}" + + # https://bugs.winehq.org/show_bug.cgi?id=10219#c1 + w_try_cabextract "${W_CACHE}/${W_PACKAGE}/${installer_exe}" + "${WINE}" "${wmf_exe}" /quiet + "${WINE}" "${wmp_exe}" /quiet + + # Disable WMP's services, since they depend on unimplemented stuff, they trigger the GUI debugger several times + w_try_regedit /D "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Cdr4_2K" + w_try_regedit /D "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Cdralw2k" + + w_set_winver 'default' +} + +#---------------------------------------------------------------- +# Benchmarks +#---------------------------------------------------------------- + +w_metadata 3dmark2000 benchmarks \ + title="3DMark2000" \ + publisher="MadOnion.com" \ + year="2000" \ + media="download" \ + file1="3dmark2000_v11_100308.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/MadOnion.com/3DMark2000/3DMark2000.exe" + +load_3dmark2000() +{ + # https://www.futuremark.com/download/3dmark2000/ + if ! test -f "${W_CACHE}/${W_PACKAGE}/3dmark2000_v11_100308.exe"; then + w_download http://www.ocinside.de/download/3dmark2000_v11_100308.exe 1b392776fd377de8cc6db7c1d8b1565485e20816d1b053de3f16a743e629048d + fi + + w_try_unzip "${W_TMP}/${W_PACKAGE}" "${W_CACHE}/${W_PACKAGE}"/3dmark2000_v11_100308.exe + w_try_cd "${W_TMP}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run Setup.exe + WinWait Welcome + ;ControlClick Button1 ; Next + Sleep 1000 + Send {Enter} ; Next + WinWait License + ;ControlClick Button2 ; Yes + Sleep 1000 + Send {Enter} ; Yes + ;WinWaitClose ahk_class #32770 ; License + WinWait ahk_class #32770, Destination + ;ControlClick Button1 ; Next + Sleep 1000 + Send {Enter} ; Next + ;WinWaitClose ahk_class #32770 ; Destination + WinWait, Start + ;ControlClick Button1 ; Next + Sleep 1000 + Send {Enter} ; Next + WinWait Registration + ControlClick Button1 ; Next + WinWait Complete + Sleep 1000 + ControlClick Button1 ; Unclick View Readme + ;ControlClick Button4 ; Finish + Send {Enter} ; Finish + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata 3dmark2001 benchmarks \ + title="3DMark2001" \ + publisher="MadOnion.com" \ + year="2001" \ + media="download" \ + file1="3dmark2001se_330_100308.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/MadOnion.com/3DMark2001 SE/3DMark2001SE.exe" + +load_3dmark2001() +{ + # https://www.futuremark.com/download/3dmark2001/ + if ! test -f "${W_CACHE}/${W_PACKAGE}"/3dmark2001se_330_100308.exe; then + w_download http://www.ocinside.de/download/3dmark2001se_330_100308.exe e34dfd32ef8fe8018a6f41f33fc3ab6dba45f2e90881688ac75a18b97dcd8813 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run 3dmark2001se_330_100308.exe + WinWait ahk_class #32770 ; welcome + if ( w_opt_unattended > 0 ) { + ControlClick Button2 ; Next + sleep 5000 + WinWait ahk_class #32770 ; License + ControlClick Button2 ; Next + WinWait ahk_class #32770, Destination + ControlClick Button1 ; Next + WinWait ahk_class #32770, Start + ControlClick Button1 ; Next + WinWait,, Registration + ControlClick Button2 ; Next + } + WinWait,, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Unclick View Readme + ControlClick Button4 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata 3dmark03 benchmarks \ + title="3D Mark 03" \ + publisher="Futuremark" \ + year="2003" \ + media="manual_download" \ + file1="3DMark03_v360_1901.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Futuremark/3DMark03/3DMark03.exe" + +load_3dmark03() +{ + # https://www.futuremark.com/benchmarks/3dmark03/download/ + if ! test -f "${W_CACHE}/${W_PACKAGE}/3DMark03_v360_1901.exe"; then + w_download_manual https://www.futuremark.com/download/3dmark03/ 3DMark03_v360_1901.exe 86d7f73747944c553e47e6ab5a74138e8bbca07fab8216ae70a61ac7f9a1c468 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_warn "Don't use mouse while this installer is running. Sorry..." + # This old installer doesn't seem to be scriptable the usual way, so spray and pray. + w_ahk_do " + SetTitleMatchMode, 2 + run 3DMark03_v360_1901.exe + WinWait 3DMark03 - InstallShield Wizard, Welcome + if ( w_opt_unattended > 0 ) { + WinActivate + Send {Enter} + Sleep 2000 + WinWait 3DMark03 - InstallShield Wizard, License + WinActivate + ; Accept license + Send a + Send {Enter} + Sleep 2000 + ; Choose Destination + Send {Enter} + Sleep 2000 + ; Begin install + Send {Enter} + ; Wait for install to finish + WinWait 3DMark03, Registration + ; Purchase later + Send {Tab} + Send {Tab} + Send {Enter} + } + WinWait, 3DMark03 - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ; Uncheck readme + Send {Space} + Send {Tab} + Send {Tab} + Send {Enter} + } + WinWaitClose, 3DMark03 - InstallShield Wizard, Complete + " +} + +#---------------------------------------------------------------- + +w_metadata 3dmark05 benchmarks \ + title="3D Mark 05" \ + publisher="Futuremark" \ + year="2005" \ + media="download" \ + file1="3dmark05_v130_1901.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Futuremark/3DMark05/3DMark05.exe" + +load_3dmark05() +{ + # https://www.futuremark.com/download/3dmark05/ + if ! test -f "${W_CACHE}/${W_PACKAGE}/3DMark05_v130_1901.exe"; then + w_download http://www.ocinside.de/download/3dmark05_v130_1901.exe af97f20665090985ee8a4ba83d137e796bfe12e0dfb7fe285712fae198b34334 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + run 3DMark05_v130_1901.exe + WinWait ahk_class #32770, Welcome + if ( w_opt_unattended > 0 ) { + Send {Enter} + WinWait, ahk_class #32770, License + ControlClick Button1 ; Accept + ControlClick Button4 ; Next + WinWait, ahk_class #32770, Destination + ControlClick Button1 ; Next + WinWait, ahk_class #32770, Install + ControlClick Button1 ; Install + WinWait, ahk_class #32770, Purchase + ControlClick Button4 ; Later + } + WinWait, ahk_class #32770, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Uncheck view readme + ControlClick Button3 ; Finish + } + WinWaitClose, ahk_class #32770, Complete + " + if w_workaround_wine_bug 22392; then + w_warn "You must run the app with the -nosysteminfo option to avoid a crash on startup" + fi +} + +#---------------------------------------------------------------- + +w_metadata 3dmark06 benchmarks \ + title="3D Mark 06" \ + publisher="Futuremark" \ + year="2006" \ + media="manual_download" \ + file1="3DMark06_v121_installer.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Futuremark/3DMark06/3DMark06.exe" + +load_3dmark06() +{ + w_download_manual https://www.futuremark.com/support/downloads 3DMark06_v121_installer.exe 362ebafd2b9c89a59a233e4328596438b74a32827feb65fe2837154c60a37da3 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + run ${file1} + WinWait ahk_class #32770, Welcome + if ( w_opt_unattended > 0 ) { + Send {Enter} + WinWait, ahk_class #32770, License + ControlClick Button1 ; Accept + ControlClick Button4 ; Next + WinWait, ahk_class #32770, Destination + ControlClick Button1 ; Next + WinWait, ahk_class #32770, Install + ControlClick Button1 ; Install + WinWait ahk_class OpenAL Installer + ControlClick Button2 ; OK + WinWait ahk_class #32770 + ControlClick Button1 ; OK + } + WinWait, ahk_class #32770, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Uncheck view readme + ControlClick Button3 ; Finish + } + WinWaitClose, ahk_class #32770, Complete + " + + if w_workaround_wine_bug 24417 "Installing shader compiler..."; then + # "Demo" button doesn't work without this. d3dcompiler_43 related. + w_call d3dx9_28 + w_call d3dx9_36 + fi + + if w_workaround_wine_bug 22392; then + w_warn "You must run the app with the -nosysteminfo option to avoid a crash on startup" + fi +} + +#---------------------------------------------------------------- + +w_metadata stalker_pripyat_bench benchmarks \ + title="S.T.A.L.K.E.R.: Call of Pripyat benchmark" \ + publisher="GSC Game World" \ + year="2009" \ + media="manual_download" \ + file1="stkcop-bench-setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Call Of Pripyat Benchmark/Benchmark.exe" + +load_stalker_pripyat_bench() +{ + # Much faster + w_download_manual http://www.bigdownload.com/games/stalker-call-of-pripyat/pc/stalker-call-of-pripyat-benchmark stkcop-bench-setup.exe 8c810fba1bbb9c58fc01f4f602479886680c9f4b491dd0afe935e27083f54845 + #w_download https://files.gsc-game.com/st/bench/stkcop-bench-setup.exe 8c810fba1bbb9c58fc01f4f602479886680c9f4b491dd0afe935e27083f54845 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + # FIXME: a bit fragile, if you're browsing the web while installing, it sometimes gets stuck. + w_ahk_do " + SetTitleMatchMode, 2 + run ${file1} + WinWait,Setup - Call Of Pripyat Benchmark + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick TNewButton1 ; Next + WinWait,Setup - Call Of Pripyat Benchmark,License + sleep 1000 + ControlClick TNewRadioButton1 ; accept + sleep 1000 + ControlClick TNewButton2 ; Next + WinWait,Setup - Call Of Pripyat Benchmark,Destination + sleep 1000 + ControlClick TNewButton3 ; Next + WinWait,Setup - Call Of Pripyat Benchmark,shortcuts + sleep 1000 + ControlClick TNewButton4 ; Next + WinWait,Setup - Call Of Pripyat Benchmark,performed + sleep 1000 + ControlClick TNewButton4 ; Next + WinWait,Setup - Call Of Pripyat Benchmark,ready + sleep 1000 + ControlClick, TNewButton4 ; Next (nah, who reads doc?) + } + WinWait,Setup - Call Of Pripyat Benchmark,finished + if ( w_opt_unattended > 0 ) { + sleep 1000 + Send {Space} ; uncheck launch + sleep 1000 + ControlClick TNewButton4 ; Finish + } + WinWaitClose,Setup - Call Of Pripyat Benchmark,finished + " + + if w_workaround_wine_bug 24868; then + w_call d3dx9_31 + w_call d3dx9_42 + fi +} + +#---------------------------------------------------------------- + +w_metadata unigine_heaven benchmarks \ + title="Unigen Heaven 2.1 Benchmark" \ + publisher="Unigen" \ + year="2010" \ + media="manual_download" \ + file1="Unigine_Heaven-2.1.msi" + +load_unigine_heaven() +{ + w_download_manual "https://www.fileplanet.com/212489/210000/fileinfo/Unigine-'Heaven'-Benchmark-2.1-%28Windows%29" 47113b285253a1ebce04527a31d734c0dfce5724e8d2643c6c1b822a940e7073 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run msiexec /i ${file1} + if ( w_opt_unattended > 0 ) { + WinWait ahk_class MsiDialogCloseClass + Send {Enter} + WinWait ahk_class MsiDialogCloseClass, License + ControlClick Button1 ; Accept + ControlClick Button3 ; Accept + WinWait ahk_class MsiDialogCloseClass, Choose + ControlClick Button1 ; Typical + WinWait ahk_class MsiDialogCloseClass, Ready + ControlClick Button2 ; Install + ; FIXME: on systems with OpenAL already (Win7?), the next four lines + ; are not needed. We should somehow wait for either OpenAL window + ; *or* Completed window. + WinWait ahk_class OpenAL Installer + ControlClick Button2 ; OK + WinWait ahk_class #32770 + ControlClick Button1 ; OK + } + WinWait ahk_class MsiDialogCloseClass, Completed + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Finish + Send {Enter} + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata wglgears benchmarks \ + title="wglgears" \ + publisher="Clinton L. Jeffery" \ + year="2005" \ + media="download" \ + file1="wglgears.exe" \ + installed_exe1="${W_SYSTEM32_DLLS_WIN}/wglgears.exe" + +load_wglgears() +{ + # Original site http://www2.cs.uidaho.edu/~jeffery/win32/wglgears.exe is 403 as of 2019/04/07 + w_download https://web.archive.org/web/20091001002702/http://www2.cs.uidaho.edu/~jeffery/win32/wglgears.exe 858ba95ea3c9af4ded1f4100e59b6e8e57024f3efef56304dbd48106e8f2f6f7 + cp "${W_CACHE}"/wglgears/wglgears.exe "${W_SYSTEM32_DLLS}" + chmod +x "${W_SYSTEM32_DLLS}/wglgears.exe" +} + +#---------------------------------------------------------------- +# Games +#---------------------------------------------------------------- + +w_metadata algodoo_demo games \ + title="Algodoo Demo" \ + publisher="Algoryx" \ + year="2009" \ + media="download" \ + file1="Algodoo_1_7_1-Win32.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Algodoo/Algodoo.exe" + +load_algodoo_demo() +{ + w_download http://www.algodoo.com/download/Algodoo_1_7_1-Win32.exe 99d3704ac35028fbc74fdf7c59df3f6caf636009bba19bcddf4f7e7797c14d71 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + ; This one's funny... on Wine, keyboard works once you click manually, but until then, only ControlClick seems to work. + run, Algodoo_1_7_1-Win32.exe + SetTitleMatchMode, 2 + winwait, Algodoo, Welcome + if ( w_opt_unattended > 0 ) { + ControlClick, TNewButton1 + winwait, Algodoo, License + ;send {Tab}a{Space}{Enter} + ControlClick, TNewRadioButton1 ; Accept + ControlClick, TNewButton2 ; Next + winwait, Algodoo, Destination + ;send {Enter} + ControlClick, TNewButton3 ; Next + winwait, Algodoo, Folder + ;send {Enter} + ControlClick, TNewButton4 ; Next + winwait, Algodoo, Select Additional Tasks + ;send {Enter} + ControlClick, TNewButton4 ; Next + winwait, Algodoo, Ready to Install + ;send {Enter} + ControlClick, TNewButton4 ; Next + } + winwait, Algodoo, Completing + if ( w_opt_unattended > 0 ) { + sleep 500 + send {Space}{Tab}{Space}{Tab}{Space}{Enter} ; decline to run app or view tutorials + } + WinWaitClose, Algodoo, Completing + " +} + +#---------------------------------------------------------------- + +w_metadata amnesia_tdd_demo games \ + title="Amnesia: The Dark Descent Demo" \ + publisher="Frictional Games" \ + year="2010" \ + media="manual_download" \ + file1="amnesia_tdd_demo_1.0.1.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Amnesia - The Dark Descent Demo/redist/Amnesia.exe" + +load_amnesia_tdd_demo() +{ + w_download_manual https://download.cnet.com/Amnesia-The-Dark-Descent-Demo/3000-2097_4-75312743.html amnesia_tdd_demo_1.0.1.exe ee4c07b40bfa59b506d2cee258c5c7a16028e11fc3a2bd243258c6bec8532dbc + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + Run, amnesia_tdd_demo_1.0.1.exe + if ( w_opt_unattended > 0 ) { + WinWait,Select Setup Language, language + ControlClick, TNewButton1 + WinWait, Amnesia - The Dark Descent Demo, Welcome + ControlClick, TNewButton1 + WinWait, Amnesia - The Dark Descent Demo, License + ControlClick, TNewRadioButton1 + ControlClick, TNewButton2 + WinWait, Amnesia - The Dark Descent Demo, installed? + ControlClick, TNewButton3 + WinWait, Folder Does Not Exist, created + ControlClick, Button1 + WinWait, Amnesia - The Dark Descent Demo, shortcuts + ControlClick, TNewButton4 + WinWait, Amnesia - The Dark Descent Demo, additional tasks + ControlClick, TNewButton4 + WinWait, Amnesia - The Dark Descent Demo, ready to begin installing + ControlClick, TNewButton4 + WinWait, Amnesia - The Dark Descent Demo, finished + ControlClick, TNewButton4 + WinWaitClose, Amnesia - The Dark Descent Demo, finished + } + " +} + +#---------------------------------------------------------------- + +w_metadata aoe3_demo games \ + title="Age of Empires III Trial" \ + publisher="Microsoft" \ + year="2005" \ + media="download" \ + file1="aoe3trial.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Games/Age of Empires III Trial/age3.exe" + +load_aoe3_demo() +{ + + w_download https://http.download.nvidia.com/downloads/nZone/demos/aoe3trial.exe 4ef69289dfa0817ec14942d85ef597835a9d2b09e1506c60b9938b20daa274ad + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + run aoe3trial.exe + WinWait,Empires,Welcome + if ( w_opt_unattended > 0 ) { + sleep 1000 + winactivate ; else next button click ignored on vista? + Sleep 500 + ControlClick Button1 ; Next + WinWait,Empires,Please + Sleep 500 + ControlClick Button4 ; Next + WinWait,Empires,Complete + Sleep 500 + ControlClick Button4 ; Finish + } + WinWaitClose + " + + if w_workaround_wine_bug 24912 "Killing off lingering installer" ,4.19; then + # kill off lingering installer + w_ahk_do " + SetTitleMatchMode, 2 + WinKill,Empires + " + # or should we just do w_wineserver -k, like fable_tlc does? + # shellcheck disable=SC2046 + kill $(pgrep -f IDriver) + fi +} + +#---------------------------------------------------------------- + +w_metadata acreedbro games \ + title="Assassin's Creed Brotherhood" \ + publisher="Ubisoft" \ + year="2011" \ + media="dvd" \ + file1="ACB.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Ubisoft/Assassin's Creed Brotherhood/AssassinsCreedBrotherhood.exe" + +load_acreedbro() +{ + w_mount ACB + w_read_key + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Brotherhood, Choose + if ( w_opt_unattended > 0 ) { + WinActivate + send {Enter} + ;ControlClick, Button3 ; Accept default (english) + winwait, Brotherhood, Welcome + WinActivate + send {Enter} ; Next + winwait, Brotherhood, License + WinActivate + send a ; Agree + sleep 500 + send {Enter} ; Next + winwait, Brotherhood, begin + send {Enter} ; Install + } + winwait, Brotherhood, Finish + if ( w_opt_unattended > 0 ) { + ControlClick Button4 + send {Enter} ; Finish + } + WinWaitClose + " + + w_download https://static3.cdn.ubi.com/ac_brotherhood/ac_brotherhood_1.01_ww.exe a8027b08840a7438a0bd1a1c17f962fcc386a2cb9fd1d3055de2486bf95778c2 + + # FIXME: figure out why these executables don't exit, and do a proper workaround or fix + sleep 10 + # shellcheck disable=SC2009 + if ps augxw | grep -i exe | grep -E 'winemenubuilder.exe|setup.exe|PnkBstrA.exe | grep -v grep'; then + w_warn "Killing processes so patcher does not complain about game still running" + w_wineserver -k + sleep 10 + fi + + w_info "Applying patch ${W_CACHE}/${W_PACKAGE}/ac_brotherhood_1.01_ww.exe..." + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ac_brotherhood_1.01_ww.exe + WinWait, Choose Setup Language, Select + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Brotherhood 1.01, License + WinActivate + send a ; Agree + sleep 500 + send {Enter} ; Next + winwait, Brotherhood 1.01, Details + ControlClick Button1 ; Next + } + winwait, Brotherhood 1.01, Complete + if ( w_opt_unattended > 0 ) { + send {Enter} + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata avatar_demo games \ + title="James Camerons Avatar: The Game Demo" \ + publisher="Ubisoft" \ + year="2009" \ + media="manual_download" \ + file1="Avatar_The_Game_Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Ubisoft/Demo/James Cameron's AVATAR - THE GAME (Demo)/bin/AvatarDemo.exe" + +load_avatar_demo() +{ + w_download_manual https://www.fileplanet.com/207386/200000/fileinfo/Avatar:-The-Game-Demo Avatar_The_Game_Demo.exe aec9cf718f9584edc23044ff94996d4e7309654d50fcea91cba4282576a1e9c8 + + if w_workaround_wine_bug 23094 "Installing Visual C++ 2005 runtime to avoid installer crash"; then + w_call vcrun2005 + fi + + w_try_cd "${W_TMP}" + w_try_unrar "${W_CACHE}/${W_PACKAGE}/Avatar_The_Game_Demo.exe" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run, setup.exe + winwait, Language + u = ${W_OPT_UNATTENDED} + if ( u > 0 ) { + WinActivate + controlclick, Button1 + winwait, AVATAR, Welcome + controlclick, Button1 + winwait, AVATAR, License + controlclick, Button5 + controlclick, Button2 + winwait, AVATAR, setup type + controlclick, Button2 + } + winwait AVATAR + if ( u > 0 ) { + ; Strange CRC error workaround. Will check this out. Stay tuned. + loop + { + ifwinexist, CRC Error + { + winactivate, CRC Error + controlclick, Button3, CRC Error ; ignore + } + ifwinexist, AVATAR, Complete + { + controlclick, Button4 + break + } + sleep 1000 + } + } + winwaitclose AVATAR + " +} + +#---------------------------------------------------------------- + +w_metadata bttf101 games \ + title="Back to the Future Episode 1" \ + publisher="Telltale" \ + year="2011" \ + media="manual_download" \ + file1="bttf_101_setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Telltale Games/Back to the Future The Game/Episode 1/BackToTheFuture101.exe" + +load_bttf101() +{ + w_download_manual "https://www.fileplanet.com/220151/220000/fileinfo/Back-to-the-Future:-The-Game---Episode-1-Client-%28Free-Game%29" bttf_101_setup.exe 8ad05063c5dae096697665ac36578f885937829ec7dac6a3a3644c76820e999c + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run, bttf_101_setup.exe + winwait, Back to the Future, Welcome + if ( w_opt_unattended > 0 ) { + ControlClick, Button2 ; Next + winwait, Back to the Future, Checking DirectX + ControlClick, Button5 ; Don't check + ControlClick, Button2 ; Next + winwait, Back to the Future, License + ControlClick, Button2 ; Agree + winwait, Back to the Future, Location + ControlClick, Button2 ; Install + } + winwait, Back to the Future, has been installed + if ( w_opt_unattended > 0 ) { + ControlClick Button4 ; Don't start now + ControlClick Button2 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata bioshock_demo games \ + title="Bioshock Demo" \ + publisher="2K Games" \ + year="2007" \ + media="download" \ + file1="nzd_BioShockPC.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/2K Games/BioShock Demo/Builds/Release/Bioshock.exe" + +load_bioshock_demo() +{ + w_download https://us.download.nvidia.com/downloads/nZone/demos/nzd_BioShockPC.zip 36f73251c0c1c6f4b6a83af9b6e44c642b4fce127c2c28cb6d2b25bc95baa934 + + w_info "Unzipping demo, installer will start in about 30 seconds." + w_try unzip "${W_CACHE}/${W_PACKAGE}/nzd_BioShockPC.zip" -d "${W_TMP}/${W_PACKAGE}" + w_try_cd "${W_TMP}/${W_PACKAGE}/BioShock PC Demo" + + w_ahk_do " + SetTitleMatchMode, 2 + run setup.exe + winwait, BioShock Demo - InstallShield Wizard, Choose Setup Language + if ( w_opt_unattended > 0 ) { + sleep 2000 + ControlClick, Button3 + ControlClick, Button3 + winwait, BioShock Demo - InstallShield Wizard, Welcome + sleep 1000 + ControlClick, Button1 + winwait, BioShock Demo - InstallShield Wizard, Please read + sleep 1000 + ControlClick, Button5 + sleep 1000 + ControlClick, Button2 + winwait, BioShock Demo - InstallShield Wizard, Select the setup type + sleep 1000 + ControlClick, Button2 + winwait, BioShock Demo - InstallShield Wizard, Click Install to begin + ControlClick, Button1 + } + winwait, BioShock Demo - InstallShield Wizard, The InstallShield Wizard has successfully installed BioShock + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick, Button2 ; don't launch + ControlClick, Button6 ; don't show readme + send {Enter} ; finish + } + winwaitclose + sleep 3000 ; wait for splash screen to close + " +} + +#---------------------------------------------------------------- + +w_metadata bioshock2 games \ + title="Bioshock 2" \ + publisher="2K Games" \ + year="2010" \ + media="dvd" \ + file1="BIOSHOCK_2.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/2K Games/BioShock 2/SP/Builds/Binaries/Bioshock2Launcher.exe" \ + installed_exe2="${W_PROGRAMS_X86_WIN}/2K Games/BioShock 2/MP/Builds/Binaries/Bioshock2Launcher.exe" + +load_bioshock2() +{ + w_mount BIOSHOCK_2 + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup.exe + if ( w_opt_unattended > 0 ) { + winwait BioShock 2, Language + controlclick Button3 + winwait BioShock 2, Welcome + controlclick Button1 ; Accept + winwait BioShock 2, License + controlclick Button3 ; Accept + sleep 500 + controlclick Button1 ; Next + winwait BioShock 2, Setup Type + controlclick Button4 ; Next + winwait BioShock 2, Ready to Install + controlclick Button1 ; Install + } + winwait BioShock 2, Complete + if ( w_opt_unattended > 0 ) { + controlclick Button4 ; Finish + } + " +} + +#---------------------------------------------------------------- + +w_metadata bfbc2 games \ + title="Battlefield Bad Company 2" \ + publisher="EA" \ + year="2010" \ + media="dvd" \ + file1="BFBC2.iso" + +load_bfbc2() +{ + # Title of installer Window gets the TM symbol wrong, even in UTF-8 locales. + # Is it like that in Windows, too? + w_mount BFBC2 + w_read_key + w_ahk_do " + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Bad Company, English + sleep 500 + ControlClick, Next, Bad Company + winwait, Bad Company, Registration Code + sleep 500 + send {RAW}${W_KEY} + ControlClick, Next, Bad Company, Registration Code + winwait, Bad Company, Setup Wizard will install + sleep 500 + ControlClick, Button1, Bad Company, Setup Wizard + winwait, Bad Company, License Agreement + sleep 500 + ControlClick, Button1, Bad Company, License Agreement + ControlClick, Button3, Bad Company, License Agreement + winwait, Bad Company, End-User License Agreement + sleep 500 + ControlClick, Button1, Bad Company, License Agreement + ControlClick, Button3, Bad Company, License Agreement + winwait, Bad Company, Destination Folder + sleep 500 + ControlClick, Button1, Bad Company, Destination Folder + winwait, Bad Company, Ready to install + sleep 500 + ControlClick, Install, Bad Company, Ready to install + winwait, Authenticate Battlefield + sleep 500 + ControlClick, Disc authentication, Authenticate Battlefield + ControlClick, Button4, Authenticate Battlefield + winwait, Bad Company, PunkBuster + sleep 500 + ControlClick, Button4, Bad Company, PunkBuster + ControlClick, Finish, Bad Company + winwaitclose + " + + w_warn "Patching to latest version..." + + w_try_cd "${W_PROGRAMS_X86_UNIX}/Electronic Arts/Battlefield Bad Company 2" + w_ahk_do " + SetTitleMatchMode, 2 + run, BFBC2Updater.exe + winwait, Updater, have to update to + sleep 500 + ControlClick, Yes, Updater, have to update + winwait, Updater, successfully updated + sleep 500 + ControlClick,No, Updater, successfully updated ; Button2 + " + + if w_workaround_wine_bug 22961; then + # shellcheck disable=SC2016 + w_warn 'If the game says "No CD/DVD error", try "sudo mount -o remount,unhide,uid=$(uid -u)". See https://bugs.winehq.org/show_bug.cgi?id=22961 for more info.' + fi +} + +#---------------------------------------------------------------- + +w_metadata cnc3_demo games \ + title="Command & Conquer 3 Demo" \ + publisher="EA" \ + year="2007" \ + media="download" \ + file1="CnC3Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Command & Conquer 3 Tiberium Wars Demo/CNC3Demo.exe" + +load_cnc3_demo() +{ + w_download "https://files.cncnz.com/cc3_tiberium_wars/demo/CnC3Demo.exe" 1e2499f441ef1fc3cbe447ac16361ad4247a02b9b8ec05f504161e7b5b1254e5 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, CnC3Demo.exe + winwait, Conquer 3, free space to install + if ( w_opt_unattended > 0 ) { + controlclick, button1 + winwait, WinZip, After installation + controlclick, button1 + winwait, Conquer 3, InstallShield + controlclick, button1 + winwait, Conquer 3, license + controlclick, button3 + controlclick, button5 + winwait, Conquer 3, setup type + controlclick, button5 + winwait, Conquer 3, EA Link + controlclick, button1 + winwait, Conquer 3, GameSpy + controlclick, button1 + } + winwait, Conquer 3, Launch the program + if ( w_opt_unattended > 0 ) + controlclick, button1 + + winwaitclose, Conquer 3, Launch the program + " +} + +#---------------------------------------------------------------- + +w_metadata cnc_redalert3_demo games \ + title="Command & Conquer Red Alert 3 Demo" \ + publisher="EA" \ + year="2008" \ + media="manual_download" \ + file1="RedAlert3Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Red Alert 3 Demo/RA3Demo.exe" + +load_cnc_redalert3_demo() +{ + w_download_manual 'https://www.fileplanet.com/194888/190000/fileinfo/Command-&-Conquer:-Red-Alert-3-Demo' RedAlert3Demo.exe 9c2fb15076830f0e11d89be1847f4777262d8e6ee3d51ae765535f812a8a8cb2 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if test ! "${W_OPT_UNATTENDED}"; then + w_try "${WINE}" "${file1}" + else + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ${file1} + winwait, Demo, readme + send {enter} ; Install button + winwait, Demo, Agreement + ControlFocus, TNewCheckListBox1, accept + send {space} ; accept license + sleep 1000 + send N ; Next + winwait, Demo, Agreement ; DirectX + ControlFocus, TNewCheckListBox1, accept + send {space} ; accept license + sleep 1000 + send N ; Next + winwait, Demo, Next + send N ; Next + winwait, Demo, Install + send {enter} ; Really install + winwait, Demo, Finish + send F ; finish + WinWaitClose + " + fi +} + +#---------------------------------------------------------------- + +# https://appdb.winehq.org/objectManager.php?sClass=version&iId=9320 + +w_metadata blobby_volley games \ + title="Blobby Volley" \ + publisher="Daniel Skoraszewsky" \ + year="2000" \ + media="manual_download" \ + file1="blobby.zip" \ + installed_exe1="c:/BlobbyVolley/volley.exe" + +load_blobby_volley() +{ + w_download_manual https://www.chip.de/downloads/Blobby-Volley_12990993.html blobby.zip ef7d2e61fabe5ac6a556fa7c254edc667df5a6659ea262ee2bc97ed61abc3f64 + w_try_unzip "${W_DRIVE_C}/BlobbyVolley" "${W_CACHE}/${W_PACKAGE}"/blobby.zip +} + +#---------------------------------------------------------------- + +w_metadata cim_demo games \ + title="Cities In Motion Demo" \ + publisher="Paradox Interactive" \ + year="2010" \ + media="manual_download" \ + file1="cim-demo-1-0-8.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Cities In Motion Demo/Cities In Motion.exe" + +load_cim_demo() +{ + # 29 Mar 2011 cf02066f496637c24f95cf0c4ddfae376951330802500fb11bd74cc6c8872995, Inno Setup installer + #w_download https://www.pcgamestore.com/games/cities-in-motion-nbsp/trial/cim-demo-1-0-8.exe cf02066f496637c24f95cf0c4ddfae376951330802500fb11bd74cc6c8872995 + w_download_manual https://www.fileplanet.com/218762/210000/fileinfo/Cities-in-Motion-Demo cim-demo-1-0-8.exe cf02066f496637c24f95cf0c4ddfae376951330802500fb11bd74cc6c8872995 + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" cim-demo-1-0-8.exe ${W_OPT_UNATTENDED:+ /sp- /silent /norestart} +} + +#---------------------------------------------------------------- + +w_metadata cod_demo games \ + title="Call of Duty demo" \ + publisher="Activision" \ + year="2003" \ + media="manual_download" \ + file1="call_of_duty_demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Call of Duty Single Player Demo/CoDSP.exe" + +load_cod_demo() +{ + w_download_manual https://www.gamefront.com/files/968870/call_of_duty_demo_exe Call_Of_Duty_Demo.exe a7773f1ddb0c9928f738a2be34614d52bc07ecc42c0fe704ab5a596da5421b08 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run Call_Of_Duty_Demo.exe + WinWait,Call of Duty Single Player Demo,Welcome + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick Button1 ; next + WinWait,Call of Duty Single Player Demo,License + sleep 1000 + WinActivate + send A ; I Agree + WinWait,Call of Duty Single Player Demo,System + sleep 1000 + send n ; Next + WinWait,Call of Duty Single Player Demo,Location + sleep 1000 + send {Enter} + WinWait,Call of Duty Single Player Demo,Select + sleep 1000 + send n + WinWait,Call of Duty Single Player Demo,Start + sleep 1000 + send i ; Install + WinWait,Create Shortcut + sleep 1000 + send n ; No + } + WinWait,Call of Duty Single Player Demo, Complete + if ( w_opt_unattended > 0 ) { + sleep 1000 + send {Enter} ; Finish + } + WinWaitClose + " + + if w_workaround_wine_bug 21558; then + # Work around a buffer overflow - not really Wine's fault + w_warn "If you get a buffer overflow error, set __GL_ExtensionStringVersion=17700 before starting Wine. See https://bugs.winehq.org/show_bug.cgi?id=21558." + fi +} + +#---------------------------------------------------------------- + +w_metadata cod1 games \ + title="Call of Duty" \ + publisher="Activision" \ + year="2003" \ + media="dvd" \ + file1="CoD1.iso" \ + file2="CoD2.iso" + +load_cod1() +{ + # FIXME: port load_harder from winetricks and use it when caching first disc + w_mount CoD1 + + w_read_key + + __GL_ExtensionStringVersion=17700 w_ahk_do " + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup.exe + WinWait, w_try_cd Key, enter + if ( w_opt_unattended > 0 ) { + send {Raw}${W_KEY} + ControlClick Button1 + WinWait, w_try_cd Key, valid + ControlClick Button1 + WinWait, Call of Duty, Welcome + ControlClick Button1 + WinWait, Call of Duty, License + ControlClick Button3 + WinWait, Call of Duty, Minimum + ControlClick Button4 + WinWait, Call of Duty, Location + ControlClick Button1 + WinWait, Call of Duty, Folder + ControlClick Button1 + WinWait, Call of Duty, Start + ControlClick Button1 + } + WinWait, Insert CD, Please insert the Call of Duty cd 2 + " + + "${WINE}" eject ${W_ISO_MOUNT_LETTER}: + w_mount CoD2 + + w_ahk_do " + SetTitleMatchMode, 2 + if ( w_opt_unattended > 0 ) { + Send {Enter} ;continue installation + } + WinWait, Insert CD, Please insert the Call of Duty cd 1 + " + + "${WINE}" eject ${W_ISO_MOUNT_LETTER}: + w_mount CoD1 + + w_ahk_do " + SetTitleMatchMode, 2 + if ( w_opt_unattended > 0 ) { + Send {Enter} ;finalize install + WinWait, Create Shortcut, Desktop + ControlClick Button1 + WinWait, DirectX, Call ;directx 9 + ControlClick Button6 + ControlClick Button1 + WinWait, Confirm DX settings, Are + ControlClick Button2 + } + ; handle crash here + WinWait, Installation Complete, Congratulations! + if ( w_opt_unattended > 0 ) { + ControlClick Button1 + } + WinWaitClose + " + "${WINE}" eject ${W_ISO_MOUNT_LETTER}: + + if w_workaround_wine_bug 21558; then + # Work around a buffer overflow - not really Wine's fault + w_warn "If you get a buffer overflow error, set __GL_ExtensionStringVersion=17700 before starting Wine. See https://bugs.winehq.org/show_bug.cgi?id=21558" + fi + w_warn "This game is copy-protected, and requires the real disc in a real drive to run." +} + +#---------------------------------------------------------------- + +w_metadata cod4mw_demo games \ + title="Call of Duty 4: Modern Warfare" \ + publisher="Activision" \ + year="2007" \ + media="manual_download" \ + file1="CoD4MWDemoSetup_v2.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Activision/Call of Duty 4 - Modern Warfare Demo/iw3sp.exe" + +load_cod4mw_demo() +{ + # 2017/03/28: Also at https://www.fileplanet.com/213663/210000/fileinfo/LEGO-Harry-Potter:-Years-1-4-Demo + w_download_manual https://download.cnet.com/Call-of-Duty-4-Modern-Warfare/3000-7441_4-11277584.html CoD4MWDemoSetup_v2.exe 715710678394e9b0edda5dd3a560c9711557297aa2849c83e5c109db9830fbbb + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, CoD4MWDemoSetup_v2.exe + WinWait,Modern Warfare,Welcome + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button1 ; Next + WinWait,Modern Warfare, License + Sleep 500 + ControlClick Button5 ; accept + Sleep 2000 + ControlClick Button2 ; Next + WinWait,Modern Warfare, System Requirements + Sleep 500 + ControlClick Button1 ; Next + Sleep 500 + ControlClick Button4 ; Next + WinWait,Modern Warfare, Typical + Sleep 500 + ControlClick Button4 ; License + Sleep 500 + ControlClick Button1 ; Next + WinWait,Question, shortcut + Sleep 500 + ControlClick Button1 ; Yes + WinWait,Microsoft DirectX Setup, license + Sleep 500 + ControlClick Button1 ; Yes + WinWait,Modern Warfare, finished + Sleep 500 + ControlClick Button1 ; Finished + } + WinWaitClose,WinZip Self-Extractor - CoD4MWDemoSetup_v2 + " +} + +#---------------------------------------------------------------- + +w_metadata cod5_waw games \ + title="Call of Duty 5: World at War" \ + publisher="Activision" \ + year="2008" \ + media="dvd" \ + file1="5330161c7960f0770e6b05f498ab9fd13be4cfad.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Activision/Call of Duty - World at War/CoDWaW.exe" + +load_cod5_waw() +{ + w_mount CODWAW + + w_read_key + + w_ahk_do " + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Call of Duty, Key Code + sleep 1000 + Send ${W_KEY} + sleep 1000 + ControlClick, Button1, Call of Duty, Key Code + winwait, Key Code Check + sleep 1000 + controlclick, Button1, Key Code Check + winwait, Call of Duty, License Agreement + sleep 1000 + controlclick, Button5, Call of Duty, License Agreement + sleep 1000 + controlclick, Button2, Call of Duty, License Agreement + ; It wants to install PunkBuster here...OH BOY! Luckily, we can say no (see below) + winwait, PunkBuster, Anti-Cheat software system + sleep 1000 + controlclick, Button1, PunkBuster, Anti-Cheat software system + winwait, Call of Duty, install PunkBuster + sleep 1000 + ; Punkbuster: both are scripted below, so you can toggle which one you want. + ; No: + ; controlclick, Button2, Call of Duty, install PunkBuster + ; Yes: + controlclick, Button1, Call of Duty, install PunkBuster + winwait, PunkBuster, License + sleep 1000 + controlclick, Button5, PunkBuster, License + sleep 1000 + controlclick, Button2, PunkBuster, License + ; /end punkbuster + winwait, Call of Duty, Minimum System + sleep 1000 + controlclick, Button1, Call of Duty, Minimum System + winwait, Call of Duty, Setup Type + sleep 1000 + controlclick, Button1, Call of Duty, Setup Type + ; Exits silently after install + ; Need to wait here else next verb will run before this one is done + winwaitclose, Call of Duty + " + + # FIXME: Install latest updates + w_warn "This game is copy-protected, and requires the real disc in a real drive to run." +} + +#---------------------------------------------------------------- + +w_metadata civ4_demo games \ + title="Civilization IV Demo" \ + publisher="Firaxis Games" \ + year="2005" \ + media="manual_download" \ + file1="Civilization4_Demo.zip" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Firaxis Games/Sid Meier's Civilization 4 Demo/Civilization4.exe" + +load_civ4_demo() +{ + w_download_manual https://download.cnet.com/Civilization-IV-demo/3000-7489_4-10465206.html Civilization4_Demo.zip aaafc7fcbf0fc16c9b28c2422400721a40818b867e9291268877c5d3841122a2 + + w_try_unzip "${W_TMP}" "${W_CACHE}/${W_PACKAGE}"/Civilization4_Demo.zip + w_try_cd "${W_TMP}/${W_PACKAGE}" + chmod +x setup.exe + w_ahk_do " + SetTitleMatchMode, 2 + run, setup.exe + winwait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + sleep 1000 + Send {enter} + winwait, Civilization 4, Welcome + ControlClick &Next >, Civilization 4 + winwait, Civilization 4, I &accept the terms of the license agreement + ControlClick I &accept, Civilization 4 + ControlClick &Next >, Civilization 4 + winwait, Civilization 4, Express Install + ControlClick &Next >, Civilization 4 + winwait, Civilization 4, begin installation + ControlClick &Install, Civilization 4 + winwait, Civilization 4, InstallShield Wizard Complete + ControlClick Finish, Civilization 4 + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata crayonphysics_demo games \ + title="Crayon Physics Deluxe demo" \ + publisher="Kloonigames" \ + year="2011" \ + media="download" \ + file1="crayon_release52demo.exe" \ + installed_exe1="${W_PROGRAMS_WIN}/Crayon Physics Deluxe Demo/crayon.exe" \ + homepage="http://crayonphysics.com" + +load_crayonphysics_demo() +{ + w_download https://crayonphysicsdeluxe.s3.amazonaws.com/crayon_release52demo.exe 3c221f4c4283d89c180337071b5d3f8b88b68cea0558e6f72abcb34ef954b923 + # Inno Setup installer + w_try "${WINE}" "${W_CACHE}/${W_PACKAGE}/${file1}" ${W_OPT_UNATTENDED:+ /sp- /silent /norestart} +} + +#---------------------------------------------------------------- + +w_metadata crysis2 games \ + title="Crysis 2" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="Crysis2.exe" \ + installed_file1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Crytek/Crysis 2/bin32/Crysis2.exe" + +load_crysis2() +{ + w_mount "Crysis 2" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay, 1000 + run ${W_ISO_MOUNT_LETTER}:EASetup.exe + if ( w_opt_unattended > 0 ) { + Loop { + ; On Windows, this window does not pop up + ifWinExist, Microsoft Visual C++ 2008 Redistributable Setup + { + winwait, Microsoft Visual C++ 2008 Redistributable Setup + controlclick, Button12 ; Next + winwait, Visual C++, License + controlclick, Button11 ; Agree + controlclick, Button8 ; Install + winwait, Setup, configuring + winwaitclose + winwait, Visual C++, Complete + controlclick, Button2 ; Finish + break + } + ifWinExist, Setup, Please read the End User + { + break + } + sleep 1000 + } + winwait, Setup, Please read the End User + controlclick, Button1 ; accept + sleep 500 + ;controlclick, Button3 ; next + send {Enter} + ; Again for DirectX + winwait, Setup, Please read the following End + ;controlclick, Button1 ; accept + send a + sleep 1000 + ;controlclick, Button3 ; next + send {Enter} + winwait,Setup, Ready to install + controlclick, Button1 + } + winwait, Setup, Click the Finish button + if ( w_opt_unattended > 0 ) { + controlclick, Button5 ; Don't install EA Download Manager + controlclick, Button1 ; Finish + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata csi6_demo games \ + title="CSI: Fatal Conspiracy Demo" \ + publisher="Ubisoft" \ + year="2010" \ + media="manual_download" \ + file1="CSI6_PC_Demo_05.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Ubisoft/Telltale Games/CSI - Fatal Conspiracy Demo/CSI6Demo.exe" + +load_csi6_demo() +{ + w_download_manual https://www.fileplanet.com/217175/download/CSI:-Fatal-Conspiracy-Demo CSI6_PC_Demo_05.exe dd80e8e2ad2716a49ae292da99c4d069e2193d64ee62ca2941ce93fd7ee3b015 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run, CSI6_PC_Demo_05.exe + winwait, Installer Language, Please select + if ( w_opt_unattended > 0 ) { + ControlClick, Button1 ; Accept default (english) + ;send {Enter} ; Accept default (english) + winwait, CSI - Fatal Conspiracy Demo Setup + send {Enter} ; Next + winwait, CSI - Fatal Conspiracy Demo Setup, License + send {Enter} ; Agree + winwait, CSI - Fatal Conspiracy Demo Setup, Location + send {Enter} ; Install + } + winwait, CSI - Fatal Conspiracy Demo Setup, Finish + if ( w_opt_unattended > 0 ) { + ControlClick Button4 + send {Enter} ; Finish + WinWaitClose + } + " +} + +#---------------------------------------------------------------- + +w_metadata darknesswithin2_demo games \ + title="Darkness Within 2 Demo" \ + publisher="Zoetrope Interactive" \ + year="2010" \ + media="manual_download" \ + file1="DarknessWithin2Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Iceberg Interactive/Darkness Within 2 Demo/DarkLineage.exe" + +load_darknesswithin2_demo() +{ + w_download_manual http://www.bigdownload.com/games/darkness-within-2-the-dark-lineage/pc/darkness-within-2-the-dark-lineage-demo DarknessWithin2Demo.exe + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, DarknessWithin2Demo.exe + winwait, Darkness Within, will install + if ( w_opt_unattended > 0 ) { + ControlClick, TNewButton1 + winwait, Darkness, License + ControlClick, TNewRadioButton1 + ControlClick, TNewButton2 + winwait, Darkness, Location + ControlClick, TNewButton3 + winwait, Darkness, shortcuts + ControlClick, TNewButton4 + winwait, Darkness, additional + ControlClick, TNewButton4 + winwait, Darkness, Ready to Install + ControlClick, TNewButton4 + winwait, PhysX, License + ControlClick, Button3 + ControlClick, Button4 + winwait, PhysX, successfully + ControlClick, Button1 + } + winwait, Darkness, Setup has finished + if ( w_opt_unattended > 0 ) { + ControlClick, TNewListBoxButton1 + ControlClick, TNewButton4 + } + winwaitclose, Darkness, Setup has finished + " +} + +#---------------------------------------------------------------- + +w_metadata darkspore games \ + title="Darkspore" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="DARKSPORE.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Darkspore/DarksporeBin/Darkspore.exe" \ + homepage="http://darkspore.com/" + +load_darkspore() +{ + # Mount disc, verify that expected file is present + w_mount DARKSPORE Darkspore.ico + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup.exe + if ( w_opt_unattended > 0 ) { + winwait, Choose Setup Language + controlclick, Button1 ; ok (accept default, English) + winwait, InstallShield Wizard, Welcome + controlclick, Button1 ; Next + winwait, InstallShield Wizard, License Agreement + controlclick, Button3 ; Accept + sleep 1000 + controlclick, Button1 ; Next + winwait, InstallShield Wizard, Select Features + controlclick, Button5 ; Next + winwait, InstallShield Wizard, Ready to Install the Program + controlclick, Button1 ; Install + winwait, DirectX + controlclick, Button1 ; Accept + sleep 1000 + controlclick, Button4 ; Next + winwait, DirectX, DirectX setup + controlclick, Button4 + winwait, DirectX, components installed + controlclick, Button5 ; Finish + } + winwait, InstallShield Wizard, You are now ready + if ( w_opt_unattended > 0 ) { + controlclick, Button1 ; Uncheck View Readme.txt + controlclick, Button4 ; Finish + } + WinWaitClose, InstallShield Wizard + " +} + +#---------------------------------------------------------------- + +w_metadata dcuo games \ + title="DC Universe Online" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="DCUO - Disc 1.iso" \ + file2="DCUO - Disc 2.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Sony Online Entertainment/Installed Games/DC Universe Online Live/LaunchPad.exe" + +load_dcuo() +{ + w_mount "DCUO - Disc 1" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:setup.exe + if ( w_opt_unattended > 0 ) { + winwait, DC Universe, Anti-virus + ControlClick, Button1 ; next + winwait, DC Universe, License + ControlClick, Button5 ; accept + sleep 500 + ControlClick, Button2 ; next + winwait, DC Universe, Shortcut + ControlClick, Button3 ; next + Loop + { + IfWinExist, DC Universe, not enough space + { + exit 1 ; dang, have to quit + } + IfWinExist, DC Universe, Ready + { + break + } + Sleep 1000 + } + winwait, DC Universe, Ready + ControlClick, Button1 ; next + } + winwait, Setup Needs The Next Disk, Please insert disk 2 + " + + w_mount "DCUO - Disc 2" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + winwait, Setup Needs The Next Disk, Please insert disk 2 + if ( w_opt_unattended > 0 ) { + ControlClick, Button2 ; next + winwaitclose + Loop + { + IfWinExist, DirectX, Welcome + { + ControlClick, Button1 ; accept + Sleep 1000 + ControlClick, Button4 ; next + WinWait, DirectX, Runtime Install + ControlClick, Button4 ; next + WinWait, DirectX, Complete + ControlClick, Button4 ; next + sleep 1000 + process, close, dxsetup.exe ; work around strange 'next button does nothing' bug + } + IfWinExist, Flash ; a newer version of flash is already installed + { + ControlClick, Button3 ; quit + } + IfWinExist, DC Universe, Complete + { + break + } + Sleep 1000 + } + } + WinWait, DC Universe, Complete + if ( w_opt_unattended > 0 ) { + ControlClick, Button4 ; finish + } + winwaitclose + " + w_warn "Now let the wookie install itself, and then quit." +} + +#---------------------------------------------------------------- + +w_metadata deadspace games \ + title="Dead Space" \ + publisher="EA" \ + year="2008" \ + media="dvd" \ + file1="DEADSPACE.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Dead Space/Dead Space.exe" + +load_deadspace() +{ + w_mount DEADSPACE + + if w_workaround_wine_bug 23324; then + msvcrun_me_harder=" + winwait, Microsoft + controlclick, Button1 + " + else + msvcrun_me_harder="" + fi + + w_read_key + + w_ahk_do " + SetTitleMatchMode, 2 + ; note: if this is the second run, the installer skips the registration code prompt + run, ${W_ISO_MOUNT_LETTER}:EASetup.exe + winwait, Dead + send {Enter} + winwait, Dead, Registration Code + send {RAW}${W_KEY} + Sleep 1000 + controlclick, Button2 + ${msvcrun_me_harder} + winwait, Setup, License + Sleep 1000 + controlclick, Button1 + Sleep 1000 + send {Enter} + winwait, Setup, License + Sleep 1000 + controlclick, Button1 + Sleep 1000 + send {Enter} + winwait, Setup, Destination + Sleep 1000 + controlclick, Button1 + winwait, Setup, begin + Sleep 1000 + controlclick, Button1 + winwait, Setup, Finish + Sleep 1000 + controlclick, Button5 + controlclick, Button1 + " +} + +#---------------------------------------------------------------- + +w_metadata deadspace2 games \ + title="Dead Space 2" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="Disc1.iso" \ + file2="Disc2.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/EA Games/Dead Space 2/deadspace2.exe" \ + +load_deadspace2() +{ + w_read_key + + w_mount Disc1 + + # FIXME: this bug was fixed in 1.3.36, so this is unneccessary + # + # Work around bug 25963 (fails to switch discs) + w_warn "Copying discs to hard drive. This will take a few minutes." + w_try_cd "${W_TMP}" + # Copy takes a LONG time, so offer a way to avoid copy while debugging verb + # You'll need to comment out the five "rm -rf"'s, too. + if test ! -f easetup.exe; then + w_try cp -R "${W_ISO_MOUNT_ROOT}"/* . + # Make the directories writable, else 2nd disc copy will fail. + w_try chmod -R +w . + w_mount Disc2 + # On Linux, use symlinks for disc 2. (On Cygwin, we'd have to copy.) + w_try ln -s "${W_ISO_MOUNT_ROOT}"/*.dat . + mkdir -p movies/en movies/fr + w_try ln -s "${W_ISO_MOUNT_ROOT}"/movies/en/* movies/en/ + w_try ln -s "${W_ISO_MOUNT_ROOT}"/movies/fr/* movies/fr/ + # Make the files writable, otherwise you'll get errors when trying to remove the temp directory. + chmod -R +w . + fi + + # Install takes a long time, so offer a way to skip installation + # and go straight to activation while debugging that + if ! test -f "${W_PROGRAMS_X86_UNIX}/EA Games/Dead Space 2/deadspace2.exe"; then + w_ahk_do " + run easetup.exe + if ( w_opt_unattended > 0 ) { + SetTitleMatchMode, 2 + ; Not all systems need the Visual C++ runtime + loop + { + ifwinexist, Microsoft Visual C++ 2008 Redistributable Setup + { + sleep 500 + controlclick, Button12 ; Next + winwait, Visual C++, License + sleep 500 + controlclick, Button11 ; Agree + sleep 500 + controlclick, Button8 ; Install + winwait, Setup, configuring + winwaitclose + winwait, Visual C++, Complete + sleep 500 + controlclick, Button2 ; Finish + break + } + ifwinexist, Setup, Dead Space + { + break + } + sleep 1000 + } + winwait, Setup, License ; Dead Space license + sleep 500 + controlclick Button1 ; accept + controlclick Button3 ; next + SetTitleMatchMode, slow ; since word DirectX in next dialog can only be read 'slowly' + winwait, Setup, DirectX ; DirectX license + sleep 500 + controlclick Button1 ; accept + controlclick Button3 ; next + winwait, Setup, Ready to install + sleep 500 + controlclick Button1 ; Install + } + winwait, Setup, Completed + if ( w_opt_unattended > 0 ) { + controlclick Button5 ; (Don't) install EA Download Manager + controlclick Button1 ; Finish + } + winwaitclose + " + fi + + # Activate the game + w_try_cd "${W_PROGRAMS_X86}/EA Games/Dead Space 2" + w_ahk_do " + run activation.exe + if ( w_opt_unattended > 0 ) { + SetTitleMatchMode, 2 + WinWait, Product activation + sleep 500 + controlclick TBitBtn2 ; Next + WinWait, Product activation, Serial + sleep 500 + send ${W_KEY} + controlclick TBitBtn3 ; Next + WinWait, Information + sleep 4000 ; let user see what happened + send {Enter} + } + WinWaitClose, Product activation + " +} + +#---------------------------------------------------------------- + +w_metadata deusex2_demo games \ + title="Deus Ex 2 / Deus Ex: Invisible War Demo" \ + publisher="Eidos" \ + year="2003" \ + media="manual_download" \ + file1="dxiw_demo.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Deus Ex - Invisible War Demo/System/DX2.exe" + +load_deusex2_demo() +{ + w_download_manual https://www.fileplanet.com/133479/130000/fileinfo/Deus-Ex:-INVISIBLE-WAR-Demo dxiw_demo.zip cd3804a03301afd582c9c9374a670944b8cc1470ad1c2e5f3cd602c60d70244f + + w_try unzip "${W_CACHE}/${W_PACKAGE}/dxiw_demo.zip" -d "${W_TMP}" + w_try_cd "${W_TMP}" + w_ahk_do " + SetTitleMatchMode 2 + SetWinDelay 500 + run setup.exe + winwait Deus Ex, Launch + if ( w_opt_unattended > 0 ) { + controlclick button2 + winwait Deus Ex, Welcome + controlclick button1 + winwait Deus Ex, License + controlclick button3 ;accept + controlclick button1 ;next + winwait Deus Ex, Setup Type + controlclick button4 + winwait Deus Ex, Install + controlclick button1 + winwait Question, Readme + controlclick button2 + winwait Question, play + controlclick button2 + } + winwait Deus Ex, Complete + if ( w_opt_unattended > 0 ) + controlclick button4 + winwaitclose Deus Ex, Complete + " +} + +#---------------------------------------------------------------- + +w_metadata diablo2 games \ + title="Diablo II" \ + publisher="Blizzard" \ + year="2000" \ + media="cd" \ + file1="INSTALL.iso" \ + file2="PLAYDISC.iso" \ + file3="CINEMATICS.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Diablo II/Diablo II.exe" + +load_diablo2() +{ + w_download http://ftp.blizzard.com/pub/diablo2/patches/PC/D2Patch_113c.exe 3d7a488c2a76a12e5a21fc71ca313cf9440f67ded6f65dc6bc49e30f6f557672 + + w_read_key + + w_mount INSTALL + w_ahk_do " + SetWinDelay 500 + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Diablo II Setup + send {i} + winwait, Choose Installation Size + send {u} + send {Enter} + send {Raw}${LOGNAME} + send {Tab}{Raw}${W_KEY} + send {Enter} + winwait, Diablo II - choose install directory + send {Enter} + winwait, Desktop Shortcut + send {N} + winwait, Insert Disc" + w_mount PLAYDISC + # Needed by patch 1.13c to avoid disc swapping + cp "${W_ISO_MOUNT_ROOT}"/d2music.mpq "${W_PROGRAMS_UNIX}/Diablo II/" + w_ahk_do " + send, {Enter} + Sleep 1000 + winwait, Insert Disc" + w_mount CINEMATICS + w_ahk_do " + send, {Enter} + Sleep 1000 + winwait, Insert Disc" + w_mount INSTALL + w_ahk_do " + send, {Enter} + Sleep 1000 + winwait, View ReadMe? + ControlClick &No, View ReadMe? + winwait, Register Diablo II Electronically? + send {N} + winwait, Diablo II Setup - Video Test + ControlClick &Cancel, Diablo II Setup - Video Test + winclose, Diablo II Setup" + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" D2Patch_113c.exe + w_ahk_do " + winwait, Blizzard Updater v2.72, has completed + Sleep 1000 + send {Enter} + winwait Diablo II + Sleep 1000 + ControlClick &Cancel, Diablo II" + # Dagnabbit, the darn updater starts the game after it updates, no matter what I do? + w_killall "Game.exe" +} + +w_metadata digitanks_demo games \ + title="Digitanks Demo" \ + publisher="Lunar Workshop" \ + year="2011" \ + media="download" \ + file1="digitanks.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Digitanks/digitanksdemo.exe" \ + homepage="http://www.digitanks.com" + +load_digitanks_demo() +{ + # 2011/11/11: bc98de67680e907a30ee1ab5d062e098c07a87292e3fb82ae62ad2d7175e94ff + w_download "http://static.digitanks.com/files/digitanks.exe" bc98de67680e907a30ee1ab5d062e098c07a87292e3fb82ae62ad2d7175e94ff + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_try "${WINE}" "${file1}" ${W_OPT_UNATTENDED:+ /S} + if w_workaround_wine_bug 8060 "installing corefonts"; then + w_call corefonts + fi +} + +w_metadata dirt2_demo games \ + title="Dirt 2 Demo" \ + publisher="Codemasters" \ + year="2009" \ + media="manual_download" \ + file1="Dirt2Demo.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Codemasters/DiRT2 Demo/dirt2.exe" + +load_dirt2_demo() +{ + w_download_manual https://www.fileplanet.com/207823/200000/fileinfo/DiRT-2-Demo Dirt2Demo.zip fbae62d04e3e33790fe78803577efc8ef9ff7e552220c944023b53315e0db9de + + w_try_unzip "${W_TMP}/${W_PACKAGE}" "${W_CACHE}/${W_PACKAGE}/Dirt2Demo.zip" + + if w_workaround_wine_bug 23532; then + w_call gfw + fi + + if w_workaround_wine_bug 24868; then + w_call d3dx9_36 + fi + + w_try_cd "${W_TMP}/${W_PACKAGE}" + + w_ahk_do " + Run, Setup.exe + WinWait, Choose Setup Language, Select + if ( w_opt_unattended > 0 ) { + sleep 500 + ControlClick Button1 ;next + WinWait, DiRT2 Demo - InstallShield Wizard, Welcome + sleep 500 + ControlClick Button1 ;next + WinWait, DiRT2 Demo - InstallShield Wizard, License + sleep 500 + ControlClick Button3 ;i accept + sleep 500 + ControlClick Button1 ;next + WinWait, DiRT2 Demo - InstallShield Wizard, Setup + sleep 500 + ControlClick Button4 ;next + WinWait, InstallShield Wizard, In order + sleep 500 + ControlClick Button1 ;next + WinWait, DiRT2 Demo - InstallShield Wizard, Ready + sleep 500 + ControlClick Button1 ;next + } + WinWait, DiRT2 Demo - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + sleep 500 + ControlClick Button4 ;finish + } + WinWaitClose, DiRT2 Demo - InstallShield Wizard, Complete + " +} + +#---------------------------------------------------------------- + +w_metadata demolition_company_demo games \ + title="Demolition Company demo" \ + publisher="Giants Software" \ + year="2010" \ + media="manual_download" \ + file1="DemolitionCompanyDemoENv2.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Demolition Company Demo/DemolitionCompany.exe" + +load_demolition_company_demo() +{ + w_download_manual https://www.demolitioncompany-thegame.com/demo.php DemolitionCompanyDemoENv2.exe + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, DemolitionCompanyDemoENv2.exe + winwait, Setup - Demolition, This will install + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, TNewButton1, Setup - Demolition, This will install + winwait, Setup - Demolition, License Agreement + sleep 1000 + controlclick, TNewRadioButton1, Setup - Demolition, License Agreement + sleep 1000 + controlclick, TNewButton2, Setup - Demolition, License Agreement + winwait, Setup - Demolition, Setup Type + sleep 1000 + controlclick, TNewButton2, Setup - Demolition, Setup Type + winwait, Setup - Demolition, Ready to Install + sleep 1000 + controlclick, TNewButton2, Setup - Demolition, Ready to Install + winwait, Setup - Demolition, Completing + sleep 1000 + controlclick, TNewButton2, Setup - Demolition, Completing + } + winwaitclose, Setup - Demolition + " +} + +#---------------------------------------------------------------- + +w_metadata dragonage games \ + title="Dragon Age: Origins" \ + publisher="Bioware / EA" \ + year="2009" \ + media="dvd" \ + file1="DragonAge.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Dragon Age/bin_ship/daorigins.exe" + +load_dragonage() +{ + w_read_key + + # game can do this, why do we need to? + w_call physx + + w_mount DragonAge + + w_ahk_do " + SetWinDelay 1000 + Run, ${W_ISO_MOUNT_LETTER}:Setup.exe + SetTitleMatchMode, 2 + winwait, Installer Language + if ( w_opt_unattended > 0 ) { + WinActivate + send {Enter} + winwait, Dragon Age: Origins Setup + ControlClick Next, Dragon Age: Origins Setup + winwait, Dragon Age: Origins Setup, End User License + ;ControlClick Button4, Dragon Age: Origins Setup ; agree + send {Tab}a ; agree + ;ControlClick I agree, Dragon Age: Origins Setup + send {Enter} ; continue + SetTitleMatchMode, 1 + winwait, Dragon Age: Origins, Registration + send ${W_KEY} + send {Enter} + } + winwait, Dragon Age: Origins Setup, Install Type + if ( w_opt_unattended > 0 ) + send {Enter} + winwaitclose + " + # Since the installer explodes on exit, just wait for the + # last file it's known to create + while ! test -f "${W_PROGRAMS_X86_UNIX}/Dragon Age/bin_ship/DAOriginsLauncher-MCE.png"; do + w_info "Waiting for installer to finish..." + sleep 1 + done + + # FIXME: does this directory name change in Windows 7? + ini="${W_DRIVE_C}/users/${LOGNAME}/My Documents/BioWare/Dragon Age/Settings/DragonAge.ini" + if ! test -f "${ini}"; then + w_warn "${ini} not found?" + else + cp -f "${ini}" "${ini}.old" + fi + + if w_workaround_wine_bug 22557 "Setting UseVSync=0 to avoid black menu" ,4.15; then + sed 's,UseVSync=1,UseVSync=0,' < "${ini}" > "${ini}.new" + mv -f "${ini}.new" "${ini}" + fi +} + +#---------------------------------------------------------------- + +w_metadata dragonage_ue games \ + title="Dragon Age: Origins - Ultimate Edition" \ + publisher="Bioware / EA" \ + year="2010" \ + media="dvd" \ + file1="DRAGONAGE-1.iso" \ + file2="DRAGONAGE-2.iso" + +load_dragonage_ue() +{ + w_read_key + + w_mount DRAGONAGE Setup.exe 1 + + # Annoyingly, it runs a web browser so you can activate the extra stuff. Disable that, and w_warn the user after install: + WINEDLLOVERRIDES="winebrowser.exe=" + export WINEDLLOVERRIDES + + w_ahk_do " + SetTitleMatchMode, 2 + SetTitleMatchMode, slow + SetWinDelay 1000 + Run, ${W_ISO_MOUNT_LETTER}:Setup.exe + winwait, Installer, English + if ( w_opt_unattended > 0 ) { + ControlClick Button1, Installer, English + winwait, Dragon Age: Origins Setup + ControlClick Button2, Dragon Age: Origins Setup + winwait, Dragon Age: Origins Setup, License Agreement + ControlClick Button4, Dragon Age: Origins Setup + ControlClick Button2, Dragon Age: Origins Setup + winwait, Dragon Age: Origins, Registration + controlclick, Edit1 + sleep 1000 + send ${W_KEY} + send {Enter} + winwait, Dragon Age: Origins Setup, Install Type + controlclick, Button2, Dragon Age: Origins Setup, Install Type + winwait, Dragon Age: Origins Setup, expanded content + controlclick, Button1 + } + winwait, Insert Disc... + " + w_mount DRAGONAGE data/ultimate_en.rar 2 + + w_ahk_do " + sleep 5000 + SetTitleMatchMode, 2 + if ( w_opt_unattended > 0 ) { + controlclick, Button2, Insert Disc... + winwait, Dragon Age, Setup was completed successfully + controlclick, Button2, Dragon Age, Setup was completed successfully + } + winwait, Dragon Age, Click Finish to close + if ( w_opt_unattended > 0 ) { + controlclick, Button5, Dragon Age, Click Finish to close + controlclick, Button2, Dragon Age, Click Finish to close + } + winwaitclose + " + + if w_workaround_wine_bug 23730 "Run with WINEDEBUG=-all to reduce flickering" ,4.15; then + : + fi + + if w_workaround_wine_bug 23081 "If you still see flickering, try applying the patch from https://bugs.winehq.org/show_bug.cgi?id=23081" ,4.15; then + : + fi + + w_warn "To activate the additional content, visit https://social.bioware.com/redeem_code.php?path=/dragonage/pc/dlcactivate/en" +} + +#---------------------------------------------------------------- + +w_metadata dragonage2_demo games \ + title="Dragon Age II demo" \ + publisher="EA/Bioware" \ + year="2011" \ + media="download" \ + file1="DragonAge2Demo_F93M2qCj_EnEsItPlRu.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Dragon Age 2 Demo/bin_ship/DragonAge2Demo.exe" + +load_dragonage2_demo() +{ + w_download https://lvlt.bioware.cdn.ea.com/bioware/u/f/eagames/bioware/dragonage2/demo/DragonAge2Demo_F93M2qCj_EnEsItPlRu.exe 615c014deed9b97de5662774fe25074862a7873c430d5d3650d07c7ce2727e9d + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 500 + SetTitleMatchMode, 2 + run, DragonAge2Demo_F93M2qCj_EnEsItPlRu.exe + winwait, Installer Language + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Dragon Age II Demo Setup + send {Enter} + winwait, Dragon Age II Demo Setup, License + send !a + send {Enter} + winwait, Dragon Age II Demo Setup, Select + send {Enter} + } + winwait, Dragon Age II Demo Setup, Complete, completed + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Dragon Age II Demo Setup, Completing + send {Enter} + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata eve games \ + title="EVE Online Tyrannis" \ + publisher="CCP Games" \ + year="2017" \ + media="download" \ + file1="EveLauncher-1104888.exe" \ + installed_exe1="c:/EVE/eve.exe" + +load_eve() +{ + # https://community.eveonline.com/support/download/ + w_download https://binaries.eveonline.com/EveLauncher-1104888.exe d1d66ea0a0e4a476a926307dcdb3d7b5e777d7cff7feb172ce7779dac9fdae8f + + if test "${W_OPT_UNATTENDED}"; then + w_warn "Quiet mode doesn't work with latest eve update, button names don't appear in AHK." + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + run, ${file1} + WinWait, EVE Online + if ( w_opt_unattended > 0 ) { + WinActivate + send {Enter} ; Next + WinWait, EVE,License Agreement + WinActivate + send {Enter} ; Next + WinWait, EVE,Choose Install + WinActivate + send {Enter} ; Install + WinWait, EVE,has been installed + WinActivate + ;Send {Tab}{Tab}{Tab} ; select Launch + ;Send {Space} ; untick Launch + ControlClick Button4 ; untick Launch + Send {Enter} ; Finish (Button2) + } + WinWaitClose, EVE Online + " +} + +#---------------------------------------------------------------- + +w_metadata fable_tlc games \ + title="Fable: The Lost Chapters" \ + publisher="Microsoft" \ + year="2005" \ + media="cd" \ + file1="FABLE_DISC_1.iso" \ + file2="FABLE DISC 2.iso" \ + file3="FABLE DISC 3.iso" \ + file4="FABLE DISC 4.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Games/Fable - The Lost Chapters/Fable.exe" + +load_fable_tlc() +{ + w_read_key + + if w_workaround_wine_bug 657; then + w_call mfc42 + fi + + w_mount FABLE_DISK_1 + w_ahk_do " + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:setup.exe + WinWait,Fable,Welcome + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button1 ; Next + WinWait,Fable,Please + Sleep 500 + ControlClick Button4 ; Next + WinWait,Fable,Product Key + Sleep 500 + Send ${W_KEY} + Send {Enter} + } + WinWait,Fable,Disk 2 + " + w_mount "FABLE DISK 2" + w_ahk_do " + SetTitleMatchMode, 2 + WinWait,Fable,Disk 2 + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button2 ; Retry + } + WinWait,Fable,Disk 3 + " + + w_mount "FABLE DISK 3" + w_ahk_do " + SetTitleMatchMode, 2 + WinWait,Fable,Disk 3 + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button2 ; Retry + } + WinWait,Fable,Disk 4 + " + + w_mount "FABLE DISK 4" + w_ahk_do " + SetTitleMatchMode, 2 + WinWait,Fable,Disk 4 + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button2 ; Retry + } + WinWait,Fable,Disk 1 + WinKill + " + + # Now tell game what the real disc is so user can insert disc 1 and run the game! + # FIXME: don't guess it's D: + cat > "${W_TMP}/${W_PACKAGE}.reg" <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\D3BE9C3CAF4226447B48E06CAACF2DDD\\InstallProperties] +"InstallSource"="D:\\" + +_EOF_ + try_regedit "${W_TMP_WIN}\\${W_PACKAGE}.reg" + + # Also accept EULA + cat > "${W_TMP}/${W_PACKAGE}.reg" <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft Games\\Fable TLC] +"FIRSTRUN"=dword:00000001 + +_EOF_ + try_regedit "${W_TMP_WIN}\\${W_PACKAGE}.reg" + + if w_workaround_wine_bug 24912 "Killing off lingering installer" ,4.19; then + # kill off lingering installer + w_ahk_do " + SetTitleMatchMode, 2 + WinKill,Fable + " + w_killall IDriverT.exe + w_killall IDriver.exe + fi + + if w_workaround_wine_bug 20074 "Installing native d3dx9_36" ,4.18; then + w_call d3dx9_36 + fi +} + +#---------------------------------------------------------------- + +w_metadata fifa11_demo games \ + title="FIFA 11 Demo" \ + publisher="EA Sports" \ + year="2010" \ + media="download" \ + file1="fifa11_pc_demo_NA.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/EA Sports/FIFA 11 Demo/Game/fifa.exe" + +load_fifa11_demo() +{ + # From https://www.ea.com/uk/football/news/fifa11-download-2 + w_download "http://static.cdn.ea.com/fifa/u/f/fifa11_pc_demo_NA.zip" 8b51b5d7b017c4a198fdfae1c348666f99cd60271835d608357f2ad893e5be43 + + w_try unzip -d "${W_TMP}" "${W_CACHE}/${W_PACKAGE}/fifa11_pc_demo_NA.zip" + w_try_cd "${W_TMP}" + + w_ahk_do " + SetTitleMatchMode, 2 + run, EASetup.exe + winwait, Microsoft Visual C++ 2008, wizard + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, Button12, Microsoft Visual C++ 2008, wizard + winwait, Microsoft Visual C++ 2008, License Terms + sleep 1000 + controlclick, Button11, Microsoft Visual C++ 2008, License Terms + sleep 1000 + controlclick, Button8, Microsoft Visual C++ 2008, License Terms + winwait, Setup, is configuring + winwaitclose + winwait, Microsoft Visual C++ 2008, Setup Complete + sleep 1000 + controlclick, Button2 + ; There are two license agreements...one is for Directx + winwait, FIFA 11, I &accept the terms in the End User License Agreement + sleep 1000 + controlclick, Button1 + sleep 1000 + controlclick, Button3 + winwaitclose + winwait, FIFA 11, I &accept the terms in the End User License Agreement + sleep 1000 + controlclick, Button1, FIFA 11, I &accept the terms in the End User License Agreement + sleep 1000 + controlclick, Button3, FIFA 11, I &accept the terms in the End User License Agreement + winwait, FIFA 11, Ready to install FIFA 11 + sleep 1000 + controlclick, Button1, FIFA 11, Ready to install FIFA 11 + } + winwait, FIFA 11, Click the Finish button to exit the Setup Wizard. + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, Button5, FIFA 11, Click the Finish button to exit the Setup Wizard. + sleep 1000 + controlclick, Button1, FIFA 11, Click the Finish button to exit the Setup Wizard. + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata hon games \ + title="Heroes of Newerth" \ + publisher="S2 Games" \ + year="2018" \ + media="download" \ + file1="HoNClient.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Heroes of Newerth/hon.exe" + +load_hon() +{ + # 2017/03/28: 0f3c3431a88964647fc4d9540490e43afedc2e48573c260892882ecf48172317 + # 2018/06/03: d4c82a3c5fdaee193675838e2fe6ade6b9fcdc4bdaf57848300c0eb09e71a945 + w_download http://dl.heroesofnewerth.com/installers/win32/HoNClient.exe d4c82a3c5fdaee193675838e2fe6ade6b9fcdc4bdaf57848300c0eb09e71a945 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, ${file1} + winwait, Installer Language + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Heroes of Newerth + sleep 1000 + controlclick, Button2, Heroes of Newerth + winwait, Heroes of Newerth, License + sleep 1000 + controlclick, Button2, Heroes of Newerth, License + winwait, Heroes of Newerth, Install Location + sleep 1000 + controlclick, Button2, Heroes of Newerth, Install Location + winwait, Heroes of Newerth, Start Menu + sleep 1000 + controlclick, Button2, Heroes of Newerth, Start Menu + winwait, Heroes of Newerth, Finish + sleep 1000 + controlclick, Button2, Heroes of Newerth, Finish + } + winwaitclose, Heroes of Newerth, Finish + " +} + +#---------------------------------------------------------------- + +w_metadata hordesoforcs2_demo games \ + title="Hordes of Orcs 2 Demo" \ + publisher="Freeverse" \ + year="2010" \ + media="manual_download" \ + file1="HoO2Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Hordes of Orcs 2 Demo/HoO2.exe" + +load_hordesoforcs2_demo() +{ + w_download_manual https://www.fileplanet.com/216619/download/Hordes-of-Orcs-2-Demo HoO2Demo.exe 9c26e420c56268ca14e5cfa6552a9034fc2ea974714b5bfd427e611dfde197be + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + SetTitleMatchMode, slow + run HoO2Demo.exe + WinWait,Orcs + if ( w_opt_unattended > 0 ) { + WinActivate + ControlFocus, Button1, Hordes ; Next + sleep 500 + Send n ; next + WinWait,Orcs,conditions + ControlFocus, Button4, Hordes, agree + Send {Space} + Send {Enter} ; next + WinWait,Orcs,files + Send {Enter} ; next + WinWait,Orcs,exist ; Destination does not exist, create? + Send {Enter} ; yes + WinWait,Orcs,Start + Send {Enter} ; Start + } + WinWait,Orcs,successfully + if ( w_opt_unattended > 0 ) { + Send {Space} ; Finish + } + winwaitclose Orcs + " +} + +#---------------------------------------------------------------- + +w_metadata mfsxde games \ + title="Microsoft Flight Simulator X: Deluxe Edition" \ + publisher="Microsoft" \ + year="2006" \ + media="dvd" \ + file1="FSX DISK 1.iso" \ + file2="FSX DISK 2.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Games/Microsoft Flight Simulator X/fsx.exe" + +load_mfsxde() +{ + if w_workaround_wine_bug 25139 "Setting virtual desktop so license screen shows up on first run."; then + w_call vd=1024x768 + fi + + w_mount "FSX DISK 1" + + if w_workaround_wine_bug 25558 "Copying disc to hard drive. This will take a few minutes."; then + w_try_cd "${W_CACHE}/${W_PACKAGE}" + # Copy takes a LONG time, so offer a way to avoid copy while debugging verb + if test ! -f bothdiscs/setup.exe; then + mkdir bothdiscs + w_try_cd bothdiscs + w_try cp -R "${W_ISO_MOUNT_ROOT}"/* . + + # A few files are on both DVDs. Remove them manually so cp doesn't complain. + rm -f DVDCheck.exe autorun.inf fsx.ico vcredist_x86.exe + + # Make the directories writable, else 2nd disc copy will fail. + w_try chmod -R +w . + + w_mount "FSX DISK 2" + + # On Linux, use symlinks for disc 2. (On Cygwin, we'd have to copy.) + w_try ln -s "${W_ISO_MOUNT_ROOT}"/* . + + # Make the files writable, otherwise you'll get errors when trying to remove bothdiscs. + chmod -R +w . + + # If you leave it mounted, it doesn't ask for the second disk to be inserted. + # If you mount it without extracting though, the install fails. + # Apparently it uses the files from the cache, but does a disk check. + else + w_try_cd bothdiscs + fi + else + w_die "non-broken case not yet supported for this game" + fi + + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run setup.exe,,,mfs_pid + winwait, Microsoft Flight Simulator X, To continue, click Install + ControlClick, Button1, Microsoft Flight Simulator X, To continue + ; Accept license: + winwait, Flight Simulator X - End User License Agreement + controlclick, Button1, Flight Simulator X - End User License Agreement + winwait, Microsoft Flight Simulator X Product Activation Wizard + ; Activate later, currently broken on Wine, see https://bugs.winehq.org/show_bug.cgi?id=25579 + controlclick, Button2, Microsoft Flight Simulator X Product Activation Wizard + sleep 1000 + controlclick, Button5, Microsoft Flight Simulator X Product Activation Wizard + ; Close main window: + winwait, Microsoft Flight Simulator, LEARNING CENTER + ; A winclose/winkill isn't forceful enough: + process, close, fsx.exe + ; Setup doesn't close on its own, because this process doesn't exit cleanly + process, close, IDriver.exe + " +} + +#---------------------------------------------------------------- + +w_metadata mfsx_demo games \ + title="Microsoft Flight Simulator X Demo" \ + publisher="Microsoft" \ + year="2006" \ + media="download" \ + file1="FSXDemo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Games/Microsoft Flight Simulator X Demo/fsx.exe" + +load_mfsx_demo() +{ + if w_workaround_wine_bug 25139 "Setting virtual desktop so license screen shows up on first run"; then + w_call vd=1024x768 + fi + + # 2017/03/28: also available at http://www.gamewatcher.com/downloads/flight-simulator-x-download/flight-simulator-x-final-demo + w_download_manual "https://www.fileplanet.com/166127/160000/fileinfo/Microsoft-Flight-Simulator-X-Demo-[Final]" fsxdemo.exe 0d616d8fb6315c15e9919a29968f98b1feda14a2a284721dad114395154e58be + w_try_cd "${W_TMP}" + unzip "${W_CACHE}/${W_PACKAGE}"/FSXDemo.exe + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run setup.exe,,,mfs_pid + winwait, Microsoft Flight Simulator X, To continue, click Install + ControlClick, Button1, Microsoft Flight Simulator X, To continue + ; Accept license: + winwait, Flight Simulator X - End User License Agreement + controlclick, Button1, Flight Simulator X - End User License Agreement + winwait, Microsoft Flight Simulator X Product Activation Wizard + ; Activate later, currently broken on Wine, see https://bugs.winehq.org/show_bug.cgi?id=25579 + controlclick, Button2, Microsoft Flight Simulator X Product Activation Wizard + sleep 1000 + controlclick, Button5, Microsoft Flight Simulator X Product Activation Wizard + ; Close main window: + winwait, Microsoft Flight Simulator, LEARNING CENTER + ; A winclose/winkill isn't forceful enough: + process, close, fsx.exe + ; Setup doesn't close on its own, because this process doesn't exit cleanly + process, close, IDriver.exe + " +} + +#---------------------------------------------------------------- + +w_metadata gta_vc games \ + title="Grand Theft Auto: Vice City" \ + publisher="Rockstar" \ + year="2003" \ + media="cd" \ + file1="GTA_VICE_CITY.iso" \ + file2="VICE_CITY_PLAY.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Rockstar Games/Grand Theft Auto Vice City/gta-vc.exe" + +load_gta_vc() +{ + w_mount GTA_VICE_CITY + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + Run, ${W_ISO_MOUNT_LETTER}:Setup.exe + winwait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + Send {enter} + winwait, Grand Theft Auto Vice City, Welcome to the InstallShield Wizard + Send {enter} + winwait, Grand Theft Auto Vice City, License Agreement + Send !a + send {enter} + winwait, Grand Theft Auto Vice City, Customer Information + controlclick, edit1 + send ${LOGNAME} + send {tab} + send company ; installer won't proceed without something here + send {enter} + winwait, Grand Theft Auto Vice City, Choose Destination Location + controlclick, Button1 + winwait, Grand Theft Auto Vice City, Select Components + controlclick, Button2 + winwait, Grand Theft Auto Vice City, Ready to Install the Program + send {enter} + } + winwait, Setup Needs The Next Disk, Please insert disk 2 + " + w_mount VICE_CITY_PLAY + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + winwait, Setup Needs The Next Disk, Please insert disk 2 + if ( w_opt_unattended > 0 ) { + controlclick, Button2 + } + winwait, Grand Theft Auto Vice City, InstallShield Wizard Complete + if ( w_opt_unattended > 0 ) { + send {enter} + } + winwaitclose + " + + if w_workaround_wine_bug 26322 "Setting virtual desktop"; then + w_call vd=800x600 + fi + + myexec="Exec=env WINEPREFIX=\"${WINEPREFIX}\" wine cmd /c 'C:\\\\\\\\Run-gta_vc.bat'" + mymenu="${XDG_DATA_HOME}/applications/wine/Programs/Rockstar Games/Grand Theft Auto Vice City/Play GTA Vice City.desktop" + if test -f "${mymenu}" && w_workaround_wine_bug 26304 "Fixing system menu"; then + # this is a hack, hopefully the wine bug will be fixed soon + sed -i "s,Exec=.*,${myexec}," "${mymenu}" + fi +} + +#---------------------------------------------------------------- + +w_metadata kotor1 games \ + title="Star Wars: Knights of the Old Republic" \ + publisher="LucasArts" \ + year="2003" \ + media="cd" \ + file1="KOTOR_1.iso" \ + file2="KOTOR_2.iso" \ + file3="KOTOR_3.iso" \ + file4="KOTOR_4.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/LucasArts/SWKotOR/swkotor.exe" + +load_kotor1() +{ + w_mount "KOTOR_1" + w_ahk_do " + SetTitleMatchMode 2 + SetWinDelay 500 + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait Star Wars, Welcome + if ( w_opt_unattended > 0 ) { + controlclick button1 + winwait Star Wars, Licensing Agreement + controlclick button2 + winwait Question, Licensing Agreement + controlclick button1 + winwait Star Wars, Destination Folder + controlclick button1 + winwait Star Wars, Program Folder + controlclick button2 + winwait Star Wars, Additional Shortcuts + ;unselect start menu shortcuts + controlclick button1 + controlclick button2 + controlclick button3 + controlclick button4 + controlclick button5 + controlclick button11 + winwait Star Wars, Review settings + controlclick button1 + } + winwait Next Disk, Please insert disk 2 + " + w_mount "KOTOR_2" + w_ahk_do " + SetTitleMatchMode 2 + if ( w_opt_unattended > 0 ) { + winwait Next Disk + controlclick button2 + } + winwait Next Disk, Please insert disk 3 + " + w_mount "KOTOR_3" + w_ahk_do " + SetTitleMatchMode 2 + if ( w_opt_unattended > 0 ) { + winwait Next Disk + controlclick button2 + } + winwait Next Disk, Please insert disk 4 + " + w_mount "KOTOR_4" + w_ahk_do " + SetTitleMatchMode 2 + if ( w_opt_unattended > 0 ) { + winwait Next Disk + controlclick button2 + winwait Question, Desktop + controlclick button2 + winwait Question, DirectX + controlclick button2 ;don't install directx + } + winwait Star Wars, Complete + if ( w_opt_unattended > 0 ) { + controlclick button1 ;don't launch game + controlclick button4 + } + winwaitclose Star Wars, Complete + " +} + +#---------------------------------------------------------------- + +w_metadata losthorizon_demo games \ + title="Lost Horizon Demo" \ + publisher="Deep Silver" \ + year="2010" \ + media="manual_download" \ + file1="Lost_Horizon_Demo_EN.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Deep Silver/Lost Horizon Demo/fsasgame.exe" + +load_losthorizon_demo() +{ + w_download_manual https://www.fileplanet.com/215704/download/Lost-Horizon-Demo Lost_Horizon_Demo_EN.exe + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + run Lost_Horizon_Demo_EN.exe + WinWait,Lost Horizon Demo, Destination + # shellcheck disable=SC2086 + if ( w_opt_unattended > 0 ) { + Sleep 500 + Send {RAW}${W_TMP} + ControlClick Button2 ;Install + WinWaitClose,Lost Horizon Demo,Installation + Sleep 1000 + Click, Left, 169, 371 + WinWait,Lost Horizon Demo - InstallShield Wizard,Welcome + Sleep 500 + ControlClick Button1 ;Next + WinWait,Lost Horizon Demo - InstallShield Wizard,License + ControlFocus,Button3,Lost Horizon Demo + Sleep 500 + Send {Space} + ControlClick Button1 ;Next + WinWait,Lost Horizon Demo - InstallShield Wizard,program + Sleep 500 + ControlClick Button2 ;Next + WinWait,Lost Horizon Demo - InstallShield Wizard,features + Sleep 500 + ControlClick Button4 ;Next + WinWait,Lost Horizon Demo - InstallShield Wizard,begin + Sleep 500 + ControlClick Button1 ;Next + } + WinWaitClose + WinWait,Lost Horizon Demo - InstallShield Wizard,Complete + if ( w_opt_unattended > 0 ) { + ControlFocus,Button2,Lost Horizon + Sleep 500 + Send {Space} + Sleep 500 + ControlClick Button4 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata lhp_demo games \ + title="LEGO Harry Potter Demo [Years 1-4]" \ + publisher="Travellers Tales / WB" \ + year="2010" \ + media="manual_download" \ + file1="LEGOHarryPotterDEMO.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/WB Games/LEGO_Harry_Potter_DEMO/LEGOHarryPotterDEMO.exe" + +load_lhp_demo() +{ + case "${LANG}" in + *UTF-8*|*utf8*) ;; + pt*) + w_warn "O instalaou falhou em uma localização não utf-8. Utilize 'export LANG=en_US.UTF-8' para contornar." + LANG=en_US.UTF-8 + export LANG + ;; + *) + w_warn "This installer fails in non-utf-8 locales. Doing 'export LANG=en_US.UTF-8' is a workaround." + LANG=en_US.UTF-8 + export LANG + ;; + esac + + w_download_manual "https://www.fileplanet.com/213663/210000/fileinfo/LEGO-Harry-Potter:-Years-1-4-Demo" "${file1}" 01d8e88511d71f5dd1492034ea4b00eacdbbf891ef23cffa31413d232eee3647 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + run, ${file1} + winwait, LEGO, language + if ( w_opt_unattended > 0 ) { + controlclick, Button1 + winwait, LEGO, License + controlclick, Button1 + controlclick, Button2 + winwait, LEGO, installation method + controlclick, Button2 + } + winwait, LEGO, Finish + if ( w_opt_unattended > 0 ) + controlclick, Button1 + + winwaitclose, LEGO, Finish + " + + # Work around locale issues by symlinking the app's directory to not have a funny char + # Won't really work on Cygwin, but that's ok. + w_try_cd "${W_PROGRAMS_X86_UNIX}/WB Games" + ln -s LEGO*Harry\ Potter*DEMO LEGO_Harry_Potter_DEMO +} + +#---------------------------------------------------------------- + +w_metadata lswcs games \ + title="Lego Star Wars Complete Saga" \ + publisher="Lucasarts" \ + year="2009" \ + media="dvd" \ + file1="LEGOSAGA.iso" \ + installed_file1="${W_PROGRAMS_X86_WIN}/LucasArts/LEGO Star Wars - The Complete Saga/LEGOStarWarsSaga.exe" + +load_lswcs() +{ + w_mount LEGOSAGA + w_ahk_do " + run ${W_ISO_MOUNT_LETTER}:setup.exe + SetTitleMatchMode, 2 + winwait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, LEGO, License Agreement + send a{Enter} + } + winwait, LEGO, method + if ( w_opt_unattended > 0 ) { + ControlClick Easy Installation + sleep 1000 + } + winwaitclose, LEGO + " + w_warn "This game is copy-protected, and requires the real disc in a real drive to run." +} + +#---------------------------------------------------------------- + +w_metadata lemonysnicket games \ + title="Lemony Snicket: A Series of Unfortunate Events" \ + publisher="Activision" \ + year="2004" \ + media="cd" \ + file1="Lemony Snicket.iso" + +load_lemonysnicket() +{ + w_mount "Lemony Snicket" + w_ahk_do " + SetTitleMatchMode, 2 + Run, ${W_ISO_MOUNT_LETTER}:setup.exe + WinWait, Lemony, Welcome + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick, Button1 ; Next + WinWait, Lemony, License + sleep 1000 + ControlClick, Button2 ; Accept + WinWait, Lemony, Minimum System + sleep 1000 + ControlClick, Button2 ; Yes + WinWait, Lemony, Destination + sleep 1000 + ControlClick, Button1 ; Next + WinWait, Lemony, Select Program Folder + sleep 1000 + ControlClick, Button2 ; Next + WinWait, Lemony, Start Copying + sleep 1000 + ControlClick, Button1 ; Next + WinWait, Question, Would you like to add a desktop shortcut + sleep 1000 + ControlClick, Button2 ; No + WinWait, Question, Would you like to register + sleep 1000 + ControlClick, Button2 ; No + ;WinWait, Information, Please register + ;sleep 1000 + ;ControlClick, Button1 ; OK + WinWait, Lemony, Complete + sleep 1000 + ControlClick, Button4 ; Finish + WinWait, Lemony, Play + sleep 1000 + ControlClick, Button6 ; Exit + WinWait, Lemony, Are you sure + sleep 1000 + ControlClick, Button1 ; Yes already + } + WinWaitClose, Lemony + " +} + +#---------------------------------------------------------------- + +w_metadata luxor_ar games \ + title="Luxor Amun Rising" \ + publisher="MumboJumbo" \ + year="2006" \ + media="cd" \ + file1="LUXOR_AMUNRISING.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/MumboJumbo/Luxor Amun Rising/Luxor AR.exe" + +load_luxor_ar() +{ + w_mount LUXOR_AMUNRISING + + w_ahk_do " + SetWinDelay, 500 + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:Luxor_AR_Setup.exe + winwait, Luxor + if ( w_opt_unattended > 0 ) { + ControlClick, Button2 ; Agree + winwait, Folder + ControlClick, Button2 ; Install + winwait, Completed + ControlClick, Button2 ; Next + } + winwait, Success + if ( w_opt_unattended > 0 ) { + ControlClick, Button6 ; Uncheck Play + ControlClick, Button2 ; Close + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata masseffect2 games \ + title="Mass Effect 2 (DRM broken on Wine)" \ + publisher="BioWare" \ + year="2010" \ + media="dvd" \ + file1="MassEffect2.iso" \ + file2="ME2_Disc2.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Mass Effect 2/Binaries/MassEffect2.exe" + +load_masseffect2() +{ + w_mount MassEffect2 + w_read_key + + w_ahk_do " + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:Setup.exe + winwait, Installer Language + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Mass Effect + send {Enter} + winwait, Mass Effect, License + ControlClick, Button4 + ControlClick, Button2 + winwait, Mass Effect, Registration Code + send ${W_KEY} + ControlClick, Button2 + winwait, Mass Effect, Install Type + ControlClick, Button2 + } + winwait, Insert Disc + " + sleep 5 + w_mount ME2_Disc2 + w_ahk_do " + SetTitleMatchMode, 2 + if ( w_opt_unattended > 0 ) { + winwait, Insert Disc + ControlClick, Button4 + ; on windows, the first click doesn't seem to do it, so press enter, too + sleep 1000 + send {Enter} + } + ; Some installs may not get to this point due to an installer hang/crash (bug 22919) + ; The hang/crash happens after the PhysX install but does not seem to affect gameplay + loop + { + ifwinexist, Mass Effect, Finish + { + if ( w_opt_unattended > 0 ) { + winkill, Mass Effect + } + break + } + Process, exist, Installer.exe + me2pid = %ErrorLevel% + if me2pid = 0 + break + sleep 1000 + } + " +} + +#---------------------------------------------------------------- + +w_metadata masseffect2_demo games \ + title="Mass Effect 2" \ + publisher="BioWare" \ + year="2010" \ + media="download" \ + file1="MassEffect2DemoEN.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Mass Effect 2 Demo/Binaries/MassEffect2.exe" + +load_masseffect2_demo() +{ + w_download http://static.cdn.ea.com/bioware/u/f/eagames/bioware/masseffect2/ME2_DEMO/MassEffect2DemoEN.exe 4ec5ce1dc90c10512324d24cba2b5b9ba1e1872ed4c23e3ede0fc0accc7d2ff2 + + # Don't let self-extractor write into $W_CACHE + case "${W_PLATFORM}" in + windows_cmd|wine_cmd) + cp "${W_CACHE}/${W_PACKAGE}/MassEffect2DemoEN.exe" "${W_TMP}" + chmod +x "${W_TMP}"/MassEffect2DemoEN.exe ;; + *) + ln -sf "${W_CACHE}/${W_PACKAGE}/MassEffect2DemoEN.exe" "${W_TMP}" ;; + esac + w_try_cd "${W_TMP}" + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run, MassEffect2DemoEN.exe + winwait, Mass Effect 2 Demo + if ( w_opt_unattended > 0 ) { + send {Enter} + winwait, Mass Effect 2 Demo, conflicts + send {Enter} + winwait, Mass Effect, License + ControlClick, Button4 + ;ControlClick, Button2 + send {Enter} + winwait, Mass Effect, Install Type + ControlClick, Button2 + } + ; Some installs may not get to this point due to an installer hang/crash (bug 22919) + ; The hang/crash happens after the PhysX install but does not seem to affect gameplay + loop + { + ifwinexist, Mass Effect, Finish + { + if ( w_opt_unattended > 0 ) { + winkill, Mass Effect + } + break + } + Process, exist, Installer.exe + me2pid = %ErrorLevel% + if me2pid = 0 + break + sleep 1000 + } + " +} + +#---------------------------------------------------------------- + +w_metadata maxmagicmarker_demo games \ + title="Max & the Magic Marker Demo" \ + publisher="Press Play" \ + year="2010" \ + media="download" \ + file1="max_demo_pc.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/maxmagicmarker_demo/max and the magic markerdemo pc.exe" + +load_maxmagicmarker_demo() +{ + w_download https://www.maxandthemagicmarker.com/maxdemo/max_demo_pc.zip 6e2abd0cbd0ad04bfea9663402d7e9f24864d3f1c32df69eebf92dfc469fe6dd + + w_try_unzip "${W_PROGRAMS_X86_UNIX}/${W_PACKAGE}" "${W_CACHE}/${W_PACKAGE}"/max_demo_pc.zip + # Work around bug in game?! + w_try_cd "${W_PROGRAMS_X86_UNIX}/${W_PACKAGE}" + mv "max and the magic markerdemo pc" "max and the magic markerdemo pc"_Data +} + +#---------------------------------------------------------------- + +w_metadata mdk games \ + title="MDK (3dfx)" \ + publisher="Playmates International" \ + year="1997" \ + media="cd" \ + file1="MDK.iso" \ + installed_exe1="C:/SHINY/MDK/MDK3DFX.EXE" + +load_mdk() +{ + # Needed even on Windows, some people say. Haven't tried the D3D version on win7 yet. + w_call glidewrapper + + w_download http://www.falconfly.de/downloads/patch-mdk3dfx.zip 9b9413609ed147944fa44bb5f51b35cf6baa7657e7e1a9891ad68d858275e00b + + w_mount MDK + w_try_cd "${W_ISO_MOUNT_ROOT}" + w_ahk_do " + SetTitleMatchMode, 2 + SetTitleMatchMode, slow + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, MDK + if ( w_opt_unattended > 0 ) { + click, left, 80, 80 ; USA + winwait, Welcome, purchasing MDK + ControlClick, Button1 ; Next + winwait, Select Target Platform + ControlClick, Button6 ; Next + winwait, Select Installation Options + ControlClick, Button3 ; Large + ControlClick, Button6 ; Next + winwait, Destination + ControlClick, Button1 ; Next + winwait, Program Folder + ControlClick, Button2 ; Next + winwait, Start + ControlClick, Button1 ; Next + Loop { + IfWinExist, Setup, ProgramFolder + send {Enter} + IfWinExist, Setup Complete + break + sleep 500 + } + } + WinWait, Setup Complete + if ( w_opt_unattended > 0 ) { + ControlClick, Button1 ; uncheck readme + ControlClick, Button4 ; Finish + WinWait, Question, DirectX + ControlClick, Button2 ; No + WinWait, Information, complete + ControlClick, Button1 ; No + } + WinWaitClose + " + w_try_cd "${W_DRIVE_C}/SHINY/MDK" + w_try_unzip . "${W_CACHE}/${W_PACKAGE}"/patch-mdk3dfx.zip + + # TODO: Wine fails to install menu items, add a workaround for that +} + +#---------------------------------------------------------------- + +w_metadata menofwar games \ + title="Men of War" \ + publisher="Aspyr Media" \ + year="2009" \ + media="dvd" \ + file1="Men of War.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Aspyr/Men of War/mow.exe" + +load_menofwar() +{ + w_mount "Men of War" + + w_try_cd "${W_ISO_MOUNT_ROOT}" + w_ahk_do " + SetTitleMatchMode, 2 + SetTitleMatchMode, slow + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Select Setup Language, Select the language + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick, TNewButton1, Select Setup Language, Select the language + winwait, Men of War + sleep 1000 + ControlClick, TButton4, Men of War + winwait, Setup - Men of War, ACCEPTANCE OF AGREEMENT + sleep 1000 + ControlClick, TNewRadioButton1, Setup - Men of War, ACCEPTANCE OF AGREEMENT + ControlClick, TNewButton1, Setup - Men of War, ACCEPTANCE OF AGREEMENT + } + winwait, Setup - Men of War, Setup has finished installing + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick, x242 y254 + ControlClick, x242 y278 + ControlClick, TNewButton1, Setup - Men of War, Setup has finished + } + " +} + +#---------------------------------------------------------------- + +w_metadata myth2_demo games \ + title="Myth II demo 1.8.0" \ + publisher="Project Magma" \ + year="2011" \ + media="download" \ + file1="Myth2_Demo_180.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Myth II Demo/Myth II Demo.exe" \ + homepage="https://projectmagma.net/" + +load_myth2_demo() +{ + # Originally a 1998 game by Bungie; according to Wikipedia, they handed the + # source code to Project Magma for further development. + + # 2017/03/27: 1a5e11be25c43491e2b4da5291b646ffe5330a6289bef236f404906e3b4f5e96 + w_download https://tain.totalcodex.net/items/download/myth-ii-demo-windows 1a5e11be25c43491e2b4da5291b646ffe5330a6289bef236f404906e3b4f5e96 "${file1}" + + w_try_cd "${W_TMP}" + w_try unzip "${W_CACHE}/${W_PACKAGE}/${file1}" + + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run, ${file1} + winwait, Setup, Welcome + if ( w_opt_unattended > 0 ) { + winactivate + send {Enter} ; next + winwait, Setup, Components + send {Enter} ; next + winwait, Setup, Location + send {Enter} ; install + } + winwait, Setup, Complete + if ( w_opt_unattended > 0 ) { + controlclick, Button4 ; Do not run + controlclick, Button2 ; Finish + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata nfsshift_demo games \ + title="Need for Speed: SHIFT Demo" \ + publisher="EA" \ + year="2009" \ + media="download" \ + file1="NFSSHIFTPCDEMO.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/Need for Speed SHIFT Demo/shiftdemo.exe" + +load_nfsshift_demo() +{ + #w_download http://cdn.needforspeed.com/data/downloads/shift/NFSSHIFTPCDEMO.exe 5ad011e7dd42e3404e3191009cd81c05b891e7c138d61f958fce9506ff8c9de3 + w_download http://www.legendaryreviews.com/download-center/demos/NFSSHIFTPCDEMO.exe 5ad011e7dd42e3404e3191009cd81c05b891e7c138d61f958fce9506ff8c9de3 + + w_try cp "${W_CACHE}/${W_PACKAGE}/${file1}" "${W_TMP}" + + w_try_cd "${W_TMP}" + w_ahk_do " + SetTitleMatchMode, 2 + SetTitleMatchMode, slow + run, ${file1} + winwait, WinRAR + if ( w_opt_unattended > 0 ) { + ControlClick, Button2 + winwait, SHIFT, View the readme + controlclick, Button1 + ; Not all systems need the Visual C++ runtime + loop + { + ifwinexist, Visual C++ + { + controlclick, Button1 + break + } + ifwinexist, Setup, SHIFT Demo License + { + break + } + sleep 1000 + } + winwait, Setup, SHIFT Demo License + Sleep 1000 + send {Space} + Sleep 1000 + send {Enter} + winwait, Setup, DirectX + Sleep 1000 + send {Space} + Sleep 1000 + send {Enter} + winwait, Setup, Destination + Sleep 1000 + send {Enter} + winwait, Setup, begin + Sleep 1000 + controlclick, Button1 + } + winwait, Setup, Finish + if ( w_opt_unattended > 0 ) { + Sleep 1000 + controlclick, Button5 + controlclick, Button1 + } + winwaitclose, Setup, Finish + " +} + +#---------------------------------------------------------------- + +w_metadata oblivion games \ + title="Elder Scrolls: Oblivion" \ + publisher="Bethesda Game Studios" \ + year="2006" \ + media="dvd" \ + file1="Oblivion.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Bethesda Softworks/Oblivion/Oblivion.exe" + +load_oblivion() +{ + w_mount "Oblivion" + + w_try_cd "${W_ISO_MOUNT_ROOT}" + w_ahk_do " + SetTitleMatchMode, 2 + run, Setup.exe + winwait, Oblivion, Welcome to the + if ( w_opt_unattended > 0 ) { + sleep 500 + controlclick, Button1 + winwait, Oblivion, License Agreement + sleep 500 + controlclick, Button3 + sleep 500 + controlclick, Button1 + winwait, Oblivion, Choose Destination + sleep 500 + controlclick, Button1 + winwait, Oblivion, Ready to Install + sleep 500 + controlclick, Button1 + winwait, Oblivion, Complete + sleep 500 + controlclick, Button1 + sleep 500 + controlclick, Button2 + sleep 500 + controlclick, Button3 + } + winwaitclose, Oblivion, Complete + " + + if w_workaround_wine_bug 20074 "Installing native d3dx9_36" ,4.18; then + w_call d3dx9_36 + fi +} + +#---------------------------------------------------------------- + +w_metadata penpenxmas games \ + title="Pen-Pen Xmas Olympics" \ + publisher="Army of Trolls / Black Cat" \ + year="2007" \ + media="download" \ + file1="PenPenXmasOlympics100.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/PPO/PPO.exe" + +load_penpenxmas() +{ + W_BROWSERAGENT=1 \ + w_download http://retrospec.sgn.net/download/files/PenPenXmasOlympics100.exe c35c5c6a9a3fa62d6b099713e72390d0490320534dba958b57b94f0a6ab458db + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + "${WINE}" PenPenXmasOlympics100.exe ${W_OPT_UNATTENDED:+/S} +} + +#---------------------------------------------------------------- + +w_metadata popfs games \ + title="Prince of Persia: The Forgotten Sands" \ + publisher="Ubisoft" \ + year="2010" \ + media="dvd" \ + file1="PoP_TFS.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Ubisoft/Prince of Persia The Forgotten Sands/Prince of Persia.exe" + +load_popfs() +{ + w_mount PoP_TFS + + w_ahk_do " + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:Setup.exe + winwait, Prince of Persia, Language + if ( w_opt_unattended > 0 ) { + sleep 500 + ControlClick, Button3 + winwait, Prince of Persia, Welcome + sleep 500 + ControlClick, Button1 + winwait, Prince of Persia, License + sleep 500 + ControlClick, Button5 + sleep 500 + ControlClick, Button2 + winwait, Prince of Persia, Click Install + sleep 500 + ControlClick, Button1 + ; Avoid error when creating desktop shortcut + Loop + { + IfWinActive, Prince of Persia, Click Finish + break + IfWinExist, Prince of Persia, desktop shortcut + { + sleep 500 + ControlClick, Button1, Prince of Persia, desktop shortcut + break + } + sleep 5000 + } + } + winwait, Prince of Persia, Click Finish + if ( w_opt_unattended > 0 ) { + sleep 500 + ControlClick, Button4 + } + " +} + +#---------------------------------------------------------------- + +w_metadata rct3deluxe games \ + title="RollerCoaster Tycoon 3 Deluxe (DRM broken on Wine)" \ + publisher="Atari" \ + year="2004" \ + media="cd" \ + file1="RCT3.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Atari/RollerCoaster Tycoon 3/RCT3.EXE" + +load_rct3deluxe() +{ + if w_workaround_wine_bug 21448; then + w_warn "DRM doesn't work, see https://bugs.winehq.org/show_bug.cgi?id=21448" + fi + + w_mount RCT3 + + # FIXME: make videos and music work + # Game still doesn't show .wmv logo videos nor play .wma background audio in menu + # though it does in Jake's screencast. Loading wmp9 and devenum gets it to + # try to load the .wmv logos, but it crashes in quartz :-( + # But at least it's playable without the logo videos and background. + + w_ahk_do " + SetWinDelay 500 + SetTitleMatchMode, 2 + run ${W_ISO_MOUNT_LETTER}:setup-rtc3.exe + if ( w_opt_unattended > 0 ) { + WinWait, Select Setup Language + controlclick, TButton1 ; accept + WinWait Setup - RollerCoaster Tycoon 3, Welcome + controlclick, TButton1 ; Next + WinWait Setup - RollerCoaster Tycoon 3, License + controlclick, TRadioButton1 ; Accept + sleep 500 + controlclick, TButton2 ; Next + WinWait Setup - RollerCoaster Tycoon 3, Destination + controlclick, TButton3 ; Next + WinWait Setup - RollerCoaster Tycoon 3, Start Menu + controlclick, TButton4 ; Next + WinWait Setup - RollerCoaster Tycoon 3, Additional + controlclick, TButton4 ; Next + WinWait Setup - RollerCoaster Tycoon 3, begin + controlclick, TButton4 ; Install + WinWait, Atari Product Registration + controlclick, Button6 ; Close + WinWait, Product Registration, skip + controlclick, Button2 ; Yes, skip + } + WinWait Setup - RollerCoaster Tycoon 3, finished + if ( w_opt_unattended > 0 ) { + controlclick, TNewCheckListBox1 ; uncheck Launch + controlclick, TButton4 ; Finish + } + WinWaitClose Setup - RollerCoaster Tycoon 3, finished + " +} + +#---------------------------------------------------------------- + +w_metadata riseofnations_demo games \ + title="Rise of Nations Trial" \ + publisher="Microsoft" \ + year="2003" \ + media="manual_download" \ + file1="RiseOfNationsTrial.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Microsoft Games/Rise of Nations Trial/nations.exe" + +load_riseofnations_demo() +{ + w_download_manual https://download.cnet.com/Rise-of-Nations-Trial-Version/3000-7562_4-10730812.html RiseOfNationsTrial.exe f0bd8be3999164e669aad33583e372ca0f530b1a2ac0194a4c13b265e9cdf744 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + run RiseOfNationsTrial.exe + WinWait,Rise Of Nations Trial Setup + if ( w_opt_unattended > 0 ) { + sleep 2500 + ControlClick CButtonClassName2 + WinWait,Rise Of Nations Trial Setup, installed + sleep 2500 + ControlClick CButtonClassName7 + } + WinWaitClose + " + + if w_workaround_wine_bug 9027; then + w_call directmusic + fi +} + +#---------------------------------------------------------------- + +w_metadata secondlife games \ + title="Second Life Viewer" \ + publisher="Linden Labs" \ + year="2003-2011" \ + media="download" \ + file1="Second_Life_3-2-8-248931_Setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/SecondLifeViewer/SecondLife.exe" + +load_secondlife() +{ + w_download http://download.cloud.secondlife.com/Viewer-3/Second_Life_3-2-8-248931_Setup.exe d155366f16bfe23f33a6b6d63f366691be2d0554429916da875ea78d0e0de8a6 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run, ${file1} + if ( w_opt_unattended > 0 ) { + winwait, Installer Language + send {Enter} + winwait, Installation Folder + send {Enter} + } + winwait, Second Life, Start Second Life now + if ( w_opt_unattended > 0 ) { + send {Tab}{Enter} + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata sims3 games \ + title="The Sims 3 (DRM broken on Wine)" \ + publisher="EA" \ + year="2009" \ + media="dvd" \ + file1="Sims3.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/The Sims 3/Game/Bin/TS3.exe" + +load_sims3() +{ + w_read_key + + w_mount Sims3 + # Default lang, USA, accept defaults, uncheck EA dl mgr, uncheck readme + w_ahk_do " + run ${W_ISO_MOUNT_LETTER}:Sims3Setup.exe + winwait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + send {Enter} + SetTitleMatchMode, 2 + winwait, - InstallShield Wizard + sleep 1000 + ControlClick &Next >, - InstallShield Wizard + sleep 1000 + send uuuuuu{Tab}{Tab}{Enter} + sleep 1000 + send a{Enter} + sleep 1000 + send {Raw}${W_KEY} + send {Enter} + winwait, - InstallShield Wizard, Setup Type + send {Enter} + winwait, - InstallShield Wizard, Click Install to begin + send {Enter} + winwait, - InstallShield Wizard, EA Download Manager + ControlClick Yes, - InstallShield Wizard + send {Enter} + } + winwait, - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ControlClick View the readme file, - InstallShield Wizard + ControlClick Finish, - InstallShield Wizard + } + winwaitclose + " + w_umount + + # DVD region code is last digit. + # FIXME: download appropriate one rather than just US version. + w_download http://akamai.cdn.ea.com/eadownloads/u/f/sims/sims3/patches/TS3_1.19.44.010001_Update.exe 9428b32638108e51e63455b60f3cfd5b5aca07b55ce58a200087631a02b5336c + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + run TS3_1.19.44.010001_Update.exe + SetTitleMatchMode, 2 + winwait, - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Finish, - InstallShield Wizard + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata simsmed games \ + title="The Sims Medieval (DRM broken on Wine)" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="TSimsM.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/The Sims Medieval/Game/Bin/TSM.exe" + +load_simsmed() +{ + w_read_key + + w_mount TSimsM + # Default lang, USA, accept defaults, uncheck EA dl mgr, uncheck readme + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 1000 + run ${W_ISO_MOUNT_LETTER}:SimsMedievalSetup.exe + winwait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + send {Enter} + SetTitleMatchMode, 2 + winwait, - InstallShield Wizard + ControlClick &Next >, - InstallShield Wizard + sleep 1000 + send uuuuuu{Tab}{Tab}{Enter} + WinWait, Sims, License + ControlClick Button3 ; Accept + sleep 1000 + ControlClick Button1 ; Next + sleep 1000 + send {Raw}${W_KEY} + send {Enter} + winwait, - InstallShield Wizard, Setup Type + ControlClick &Complete ; was not defaulting to complete? + send {Enter} + winwait, - InstallShield Wizard, Click Install to begin + send {Enter} + + ; Handle optional dialogs + ; In Wine-1.3.16 and lower, before + ; https://www.winehq.org/pipermail/wine-cvs/2011-March/076262.html, + ; wine didn't claim to already have .net 4 installed, + ; and ran into bug 25535. + Loop + { + ; .net 4 install sometimes fails nicely + ifWinExist,, .NET Framework 4 has not been installed + { + ControlClick Button3 ; Finish + } + ; .net 4 install sometimes explodes + ifWinExist .NET Framework Initialization Error + { + send {Enter} + } + ifWinExist, Sims, Customer Experience Improvement + { + send {Enter} ; Next + } + ifWinExist, - InstallShield Wizard, Complete + break + sleep 1000 + } + } + winwait, - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Do not view readme + send {Enter} ; Finish + } + winwaitclose + " + + # DVD region code is last digit. + # FIXME: download appropriate one rather than just US version. + w_download http://akamai.cdn.ea.com/eadownloads/u/f/sims/sims/patches/TheSimsMedievalPatch_1.1.10.00001_Update.exe 01c0f9e3394d93869f67f1319b80a1257fe421bbdf911a15c8c7ab43f2e73683 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run TheSimsMedievalPatch_1.1.10.00001_Update.exe + winwait, Medieval, will reset any in-progress quests + send {Enter} + winwait, Medieval, Welcome + if ( w_opt_unattended > 0 ) { + send {Enter} + } + winwait, - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Finish, - InstallShield Wizard + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata sims3_gen games \ + title="The Sims 3: Generations (DRM broken on Wine)" \ + publisher="EA" \ + year="2011" \ + media="dvd" \ + file1="Sims3EP04.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/The Sims 3 Generations/Game/Bin/TS3EP04.exe" + +load_sims3_gen() +{ + if [ ! -f "${W_PROGRAMS_X86_WIN}/Electronic Arts/The Sims 3/Game/Bin/TS3.exe" ]; then + w_die "You must have sims3 installed to install sims3_gen!" + fi + + w_read_key + w_mount Sims3EP04 + + # Default lang, USA, accept defaults, uncheck EA dl mgr, uncheck readme + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 1000 + run ${W_ISO_MOUNT_LETTER}:Sims3EP04Setup.exe + winwait, - InstallShield Wizard + if ( w_opt_unattended > 0 ) { + send {Enter} + loop + { + SetTitleMatchMode, 2 + ifwinexist, - InstallShield Wizard, Setup will now attempt to update + { + ControlClick, Button1, - InstallShield Wizard + sleep 1000 + winwait, - InstallShield Wizard, Setup has finished updating The Sims + sleep 1000 + controlclick, Button1, - InstallShield Wizard + sleep 1000 + } + ifwinexist, Sims, License + { + winactivate, Sims, License + sleep 1000 + ControlClick, Button3 + sleep 1000 + ControlClick, Button1 + sleep 1000 + break + } + sleep 1000 + } + winwait, Sims, Please enter the entire Registration Code + sleep 1000 + send {Raw}${W_KEY} + send {Enter} + winwait, - InstallShield Wizard, Setup Type + ControlClick &Complete ; was not defaulting to complete? + send {Enter} + winwait, - InstallShield Wizard, Click Install to begin + send {Enter} + winwait, - InstallShield Wizard, Would you like to install the latest + sleep 1000 + ControlClick, Button4 ; No thanks + sleep 1000 + ControlClick, Button1 + sleep 1000 + } + winwait, - InstallShield Wizard, Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Do not view readme + send {Enter} ; Finish + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata splitsecond games \ + title="Split Second" \ + publisher="Disney" \ + year="2010" \ + media="dvd" \ + file1="SplitSecond.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Disney Interactive Studios/Split Second/SplitSecond.exe" + +load_splitsecond() +{ + # Key is used in first run activation, no need to read it here. + w_mount SplitSecond + + # Aborts with dialog about FirewallInstallHelper.dll if that's not on the path (e.g. in current dir) + w_try_cd "${W_ISO_MOUNT_ROOT}" + w_ahk_do " + SetTitleMatchMode, 2 + run setup.exe + winwait, Split, Language + sleep 500 + ControlClick, Next, Split, Language ; FIXME: Use button name + winwait, Split, game installation + sleep 500 + ControlClick, Button1, Split, game installation + winwait, Split, license + sleep 500 + ControlClick, Button5, Split, license + sleep 500 + ControlClick, Button2, Split, license + winwait, Split, DirectX + sleep 500 + ControlClick, Button5, Split, DirectX + sleep 500 + ControlClick, Button2, Split, DirectX + winwait, Split, installation method + sleep 500 + controlclick, Next, Split, installation method ; FIXME: Use button name + winwait, DirectX needs to be updated + sleep 500 + send {Enter} + winwait, Split, begin + sleep 500 + ControlClick, Button1 + winwait, Split, completed + sleep 500 + ControlClick, Button1, Split + sleep 500 + ControlClick, Button4, Split + " +} + +#---------------------------------------------------------------- + +w_metadata spore games \ + title="Spore" \ + publisher="EA" \ + year="2008" \ + media="dvd" \ + file1="SPORE.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/SPORE/Sporebin/SporeApp.exe" + +load_spore() +{ + w_mount SPORE + + w_read_key + + w_ahk_do " + SetTitleMatchMode, 2 + run, ${W_ISO_MOUNT_LETTER}:SPORESetup.exe + winwait, Language + if ( w_opt_unattended > 0 ) { + sleep 500 + controlclick, Button1 + winwait, SPORE, Welcome + sleep 500 + controlclick, Button1 + winwait, SPORE, License + sleep 500 + controlclick, Button3 + sleep 500 + controlclick, Button1 + winwait, SPORE, Registration Code + send {RAW}${W_KEY} + sleep 500 + controlclick, Button2 + winwait, SPORE, Setup Type + sleep 500 + controlclick, Button6 + winwait, SPORE, Shortcut + sleep 500 + controlclick, Button6 + winwait, SPORE, begin + sleep 500 + controlclick, Button1 + winwait, Question + ; download managers are usually a pain, so always say no to such questions + sleep 500 + controlclick, Button2 + } + winwait, SPORE, complete + sleep 500 + if ( w_opt_unattended > 0 ) { + controlclick, Button1 + sleep 500 + controlclick, Button2 + sleep 500 + controlclick, Button4 + } + winwaitclose, SPORE, complete + " +} + +#---------------------------------------------------------------- + +w_metadata spore_cc_demo games \ + title="Spore Creature Creator trial" \ + publisher="EA" \ + year="2008" \ + media="download" \ + file1="792248d6ad421d577132c2b648bbed45_scc_trial_na.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Electronic Arts/SPORE/Sporebin/SporeCreatureCreator.exe" + +load_spore_cc_demo() +{ + w_download http://akamai.cdn.ea.com/eamaster/u/f/eagames/spore/scc/promo/792248d6ad421d577132c2b648bbed45_scc_trial_na.exe a7fbc5ca02a49be9772b54caf3ab1a60bdda16e43e14051de407ace527bece15 + + w_info "The installer runs on for about a minute after it's done." + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + if test "${W_OPT_UNATTENDED}"; then + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + run ${file1} + winwait, Wizard, Welcome to the SPORE + send N + winwait, Wizard, Please read the following + send a + send N + winwait, Wizard, your setup + send N + winwait, Wizard, options below + send N + winwait, Wizard, We're ready + ;send i ; didn't take once? + ControlClick, Button1 + winwait, Question, do not install the latest + send N ; reject EA Download Manager + winwait, Wizard, Launch + send {SPACE}{DOWN}{SPACE}{ENTER} + winwaitclose + " + while pgrep -f "${file1}" > /dev/null; do + w_info "Waiting for installer to finish." + sleep 2 + done + else + w_try "${WINE}" "${file1}" + fi +} + +#---------------------------------------------------------------- + +w_metadata starcraft2_demo games \ + title="Starcraft II Demo" \ + publisher="Blizzard" \ + year="2010" \ + media="manual_download" \ + file1="SC2-WingsOfLiberty-enUS-Demo-Installer.zip" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/StarCraft II Demo/StarCraft II.exe" + +load_starcraft2_demo() +{ + w_download_manual https://www.fileplanet.com/217982/210000/fileinfo/Starcraft-2-Demo SC2-WingsOfLiberty-enUS-Demo-Installer.zip 6ba192a726fc8b58031a7de961ad9392f60df05cfb206342f02f7a80b57c0784 + + w_try_cd "${W_TMP}" + w_try_unzip . "${W_CACHE}/${W_PACKAGE}"/SC2-WingsOfLiberty-enUS-Demo-Installer.zip + + w_ahk_do " + SetTitleMatchMode, 2 + Run, Installer.exe + WinWait, StarCraft II Installer + if ( w_opt_unattended > 0 ) { + sleep 500 + ControlClick, x300 y200 + winwait, End User License Agreement + winactivate + ;MouseMove, 300, 300 + ;Click WheelDown, 70 + Sleep, 1000 + ControlClick, Button2 ; Accept + winwaitclose + winwait, StarCraft II Installer + sleep 1000 + ControlClick, x800 y500 + ; Is there any better wait to await completion? + Loop { + PixelGetColor, color, 473, 469 ; the 1 in 100% + ; The digits are drawn white, but because the whole + ; window is flickering, it cycles through about 20 + ; brightnesses. Check a bunch of them to reduce + ; chances of getting stuck for a long time. + ifEqual, color, 0xffffff + break + ifEqual, color, 0xf4f4f4 + break + ifEqual, color, 0xf1f1f1 + break + ifEqual, color, 0xf0f0f0 + break + ifEqual, color, 0xeeeeee + break + ifEqual, color, 0xebebeb + break + ifEqual, color, 0xe4e4e4 + break + sleep 500 ; changes rapidly, so sample often + } + ControlClick, x800 y500 ; Finish + winwaitclose + ; no way to tell game to not start? + process, wait, SC2.exe + sleep 2000 + process, close, SC2.exe + } + " +} + +#---------------------------------------------------------------- + +w_metadata theundergarden_demo games \ + title="The UnderGarden Demo" \ + publisher="Atari" \ + year="2010" \ + media="manual_download" \ + file1="TheUnderGarden_PC_B34_SRTB.30_28OCT10.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/The UnderGarden/TheUndergarden.exe" + +load_theundergarden_demo() +{ + w_download_manual http://www.bigdownload.com/games/the-undergarden/pc/the-undergarden-demo TheUnderGarden_PC_B34_SRTB.30_28OCT10.exe acf90c422ac2f2f242100f39bedfe7df0c95f7a + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + Run, TheUnderGarden_PC_B34_SRTB.30_28OCT10.exe + WinWait,WinRAR + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick Button2 ; Install + WinWait,Select Setup Language, during + Sleep 500 + ControlClick TNewButton1 ;OK + WinWait,Setup - The UnderGarden, your + Sleep 500 + ControlClick TNewButton1 ;OK + WinWait,Setup - The UnderGarden, License + Sleep 500 + ControlClick TNewRadioButton1 ; accept + Sleep 500 + ControlClick TNewButton2 ; Next + WinWait,Setup - The UnderGarden, different + Sleep 500 + ControlClick TNewButton3 ;Next + WinWait,Setup - The UnderGarden, shortcuts + Sleep 500 + ControlClick TNewButton4 ;OK + WinWait,Setup - The UnderGarden, additional + Sleep 500 + ControlFocus,TNewCheckListBox1,desktop + Sleep 500 + Send {Space} + Sleep 500 + ControlClick TNewButton4 ; Next + WinWait,Setup - The UnderGarden, review + Sleep 500 + ControlClick TNewButton4 ;Install + WinWait,Microsoft Visual C, Visual + Sleep 500 + ControlClick Button13 ;Cancel + WinWait,Microsoft Visual C, want + Sleep 500 + ControlClick Button1 ;Yes + WinWait,Microsoft Visual C, chosen + Sleep 500 + ControlClick Button2 ;Finish + WinWait,Framework 3, Press + Sleep 500 + ControlClick Button21 ;Cancel + WinWait,Framework 3, want + Sleep 500 + ControlClick Button1 ;Yes + WinWait,Installing Microsoft, Runtime + Sleep 500 + ControlClick Button6 ;Cancel + } + WinWait,Setup,launched + if ( w_opt_unattended > 0 ) { + Sleep 500 + ControlClick TNewButton4 ;Finish + } + WinWaitClose,Setup,launched + " +} + +#---------------------------------------------------------------- + +w_metadata tmnationsforever games \ + title="TrackMania Nations Forever" \ + publisher="Nadeo" \ + year="2009" \ + media="download" \ + file1="tmnationsforever_setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/TmNationsForever/TmForever.exe" + +load_tmnationsforever() +{ + # 2011/03/29: 2f659138ed4409da404970841e18f03d29921beaf6a424824c8312ddb20f6355 + w_download "http://files.trackmaniaforever.com/tmnationsforever_setup.exe" 2f659138ed4409da404970841e18f03d29921beaf6a424824c8312ddb20f6355 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + Run, tmnationsforever_setup.exe + WinWait,Select Setup Language + if ( w_opt_unattended > 0 ) { + Sleep 1000 + ControlClick TNewButton1 ; OK + WinWait,Setup - TmNationsForever,Welcome + Sleep 1000 + ControlClick TNewButton1 ; Next + WinWait,Setup - TmNationsForever,License + Sleep 1000 + ControlClick TNewRadioButton1 ; Accept + Sleep 1000 + ControlClick TNewButton2 ; Next + WinWait,Setup - TmNationsForever,Where + Sleep 1000 + ControlClick TNewButton3 ; Next + WinWait,Setup - TmNationsForever,shortcuts + Sleep 1000 + ControlClick TNewButton4 ; Next + WinWait,Setup - TmNationsForever,perform + Sleep 1000 + ControlClick TNewButton4 ; Next + WinWait,Setup - TmNationsForever,installing + Sleep 1000 + ControlClick TNewButton4 ; Install + } + WinWait,Setup - TmNationsForever,finished + if ( w_opt_unattended > 0 ) { + Sleep 1000 + ControlFocus, TNewCheckListBox1, TmNationsForever, finished + Sleep 1000 + Send {Space} ; don't start game + ControlClick TNewButton4 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata trainztcc_2004 games \ + title="Trainz: The Complete Collection: TRS2004" \ + publisher="Paradox Interactive" \ + year="2008" \ + media="dvd" \ + file1="TRS2006DVD.iso" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Auran/TRS2004/TRS2004.exe" + +load_trainztcc_2004() +{ + w_call mfc42 + + w_read_key + # yup, they got the volume name wrong + w_mount TRS2006DVD + w_try_cd ${W_ISO_MOUNT_ROOT}/TRS2004_SP4_DVD_Installer_BUILD_2370/Installer/Disk1 + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run setup.exe + if ( w_opt_unattended > 0 ) { + winwait TRS2004 Setup, Please install the latest drivers + send {Enter} + winwait TRS2004, Welcome + send {Enter} + winwait TRS2004, License + ControlClick Button2 + winwait TRS2004, serial + winactivate + send ${W_RAW_KEY}{Enter} + winwait TRS2004, Destination + send {Enter} + winwait Install DirectX + send n + winwait Windows Update, Your computer already + send {Enter} + } + winwait TRS2004, Complete + if ( w_opt_unattended > 0 ) { + send {Space} ; uncheck View Readme + send {Enter} ; Finish + } + winwaitclose + " + + # And, while we're at it, also install the accompanying paint shed app + w_try_cd ${W_ISO_MOUNT_ROOT}/TRAINZ_PAINTSHED + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run Trainz_Paint_Shed_Setup.exe + if ( w_opt_unattended > 0 ) { + winwait Trainz Paint Shed, Welcome + send {Enter} + winwait Trainz Paint Shed, License + send a ; accept + send {Enter} ; Next + winwait Trainz Paint Shed, Destination + send {Enter} + winwait Trainz Paint Shed, Install + send {Enter} + } + winwait Trainz Paint Shed, Complete + if ( w_opt_unattended > 0 ) { + send {Enter} ; Finish + } + winwaitclose + " +} + +#---------------------------------------------------------------- + +w_metadata sammax301_demo games \ + title="Sam & Max 301: The Penal Zone" \ + publisher="Telltale Games" \ + year="2010" \ + media="manual_download" \ + file1="SamMax301_PC_Setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Telltale Games/Sam and Max - The Devil's Playhouse/The Penal Zone/SamMax301.exe" + +load_sammax301_demo() +{ + w_download_manual "https://www.fileplanet.com/211314/210000/fileinfo/Sam-&-Max:-Devil's-Playhouse---Episode-One-Demo" SamMax301_PC_Setup.exe bed2c16c0254881e7770743f936b8926fa202b91d281bb8c2dd34305d0c0a84a + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + SetWinDelay 500 + run SamMax301_PC_Setup.exe + winwait Sam and Max The Penal Zone Setup, Welcome + if ( w_opt_unattended > 0 ) { + controlclick button2 ; Next + winwait Sam and Max The Penal Zone Setup, DirectX + controlclick button5 ; Uncheck check directx + controlclick button2 ; Next + winwait Sam and Max The Penal Zone Setup, License + controlclick button2 ; I Agree + winwait Sam and Max The Penal Zone Setup, Location + controlclick button2 ; Install + winwait Sam and Max The Penal Zone Setup, Finish + controlclick button4 ; Uncheck play now + controlclick button5 ; Uncheck create shortcut + controlclick button2 ; Finish + } + winwaitclose Sam and Max The Penal Zone Setup + " +} + +#---------------------------------------------------------------- + +w_metadata sammax304_demo games \ + title="Sam & Max 304: Beyond the Alley of the Dolls" \ + publisher="Telltale Games" \ + year="2010" \ + media="manual_download" \ + file1="SamMax304_PC_setup.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Telltale Games/Sam and Max - The Devil's Playhouse/Beyond the Alley of the Dolls/SamMax304.exe" + +load_sammax304_demo() +{ + w_download_manual "https://www.fileplanet.com/214770/210000/fileinfo/Sam-&-Max:-The-Devi's-Playhouse---Beyond-the-Alley-of-the-Dolls-Demo" SamMax304_PC_setup.exe 51c85e98857d15c59d9bb808ee16794cc0caf39799c50545bffdf359eac4c70a + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetTitleMatchMode, 2 + Run, ${file1} + WinWait,Sam and Max Beyond the Alley of the Dolls Setup + if ( w_opt_unattended > 0 ) { + ControlClick Button2 ; Next + WinWait,Sam and Max Beyond the Alley of the Dolls Setup,DirectX + ControlClick Button2 ; Next - Directx check defaulted + WinWait,Sam and Max Beyond the Alley of the Dolls Setup,License + ControlClick Button2 ; Agree + WinWait,Sam and Max Beyond the Alley of the Dolls Setup,Location + ControlClick Button2 ; Install + WinWait,Sam and Max Beyond the Alley of the Dolls Setup,Finish + ControlClick Button4 ; Uncheck Play Now + ControlClick Button2 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata tropico3_demo games \ + title="Tropico 3 Demo" \ + publisher="Kalypso Media GmbH" \ + year="2009" \ + media="manual_download" \ + file1="Tropico3Demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Kalypso/Tropico 3 Demo/Tropico3 Demo.exe" + +load_tropico3_demo() +{ + w_download_manual https://www.fileplanet.com/204947/200000/fileinfo/Tropico-3-Demo Tropico3Demo.exe c4c06858cb1e0b9ff29dc8de6ecb8eb9cf699ce31609fbfa848d5dbc83c9d3e0 + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetWinDelay 1000 + SetTitleMatchMode, 2 + Run, Tropico3Demo.exe + WinWait,Installer + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; OK + WinWait,Tropico,Welcome + ControlClick Button2 ; Next + WinWait,Tropico,License + ControlClick Button2 ; Agree + WinWait,Tropico,Typical + ControlClick Button2 ; Next + } + WinWait,Tropico,Completing + if ( w_opt_unattended > 0 ) { + ControlClick Button4 ; Uncheck Run Now + ControlClick Button2 ; Finish + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata singularity games \ + title="Singularity" \ + publisher="Activision" \ + year="2010" \ + media="dvd" \ + file1="SNG_DVD.iso" + +load_singularity() +{ + w_read_key + w_mount SNG_DVD + + w_ahk_do " + run ${W_ISO_MOUNT_LETTER}:setup.exe + winwait, Activision(R) - InstallShield, Select the language for the installation from the choices below. + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, Button1, Activision(R) - InstallShield, Select the language for the installation from the choices below. + sleep 1000 + winwait, Singularity(TM), Keycode Check + sleep 1000 + Send ${W_KEY} + sleep 1000 + Send {Enter} + ; Well this is annoying... + Winwait, Keycode Check, The Keycode you entered appears to be valid. + sleep 1000 + Send {Enter} + winwait, Singularity(TM), The InstallShield Wizard will install Singularity(TM) on your computer + sleep 1000 + controlclick, Button1, Singularity(TM), The InstallShield Wizard will install Singularity(TM) on your computer + winwait, Singularity(TM), Please read the following license agreement carefully + sleep 1000 + controlclick, Button5, Singularity(TM), Please read the following license agreement carefully + sleep 1000 + controlclick, Button2, Singularity(TM), Please read the following license agreement carefully + winwait, Singularity(TM), Minimum System Requirements + sleep 1000 + controlclick, Button1, Singularity(TM), Minimum System Requirements + winwait, Singularity(TM), Select the setup type to install + controlclick, Button4, Singularity(TM), Select the setup type to install + } + ; Loop until installer window has been gone for at least two seconds + Loop + { + sleep 1000 + IfWinExist, Singularity + continue + IfWinExist, Activision + continue + sleep 1000 + IfWinExist, Singularity + continue + IfWinExist, Activision + continue + break + } + " + + # Clean up crap left over in c:\ when the installer runs the vc 2008 redistributable installer + w_try_cd "${W_DRIVE_C}" + rm -f VC_RED.* eula.*.txt globdata.ini install.exe install.ini install.res.*.dll vcredist.bmp +} + +#---------------------------------------------------------------- + +w_metadata torchlight games \ + title="Torchlight - boxed version" \ + publisher="Runic Games" \ + year="2009" \ + media="dvd" \ + file1="Torchlight.iso" + +load_torchlight() +{ + w_mount "Torchlight" + w_ahk_do " + SetTitleMatchMode, 2 + Run, ${W_ISO_MOUNT_LETTER}:Torchlight.exe + WinWait, Torchlight Setup, This wizard will guide + if ( w_opt_unattended > 0 ) { + sleep 1000 + ControlClick, Button2, Torchlight Setup, This wizard will guide + WinWait, Torchlight Setup, Please review the license terms + sleep 1000 + ControlClick, Button2, Torchlight Setup, Please review the license terms + WinWait, Torchlight Setup, Choose Install Location + sleep 1000 + ControlClick, Button2, Torchlight Setup, Choose Install Location + WinWait, Torchlight Setup, Installation Complete + sleep 1000 + ControlClick, Button2, Torchlight Setup, Installation Complete + WinWait, Torchlight Setup, Completing the Torchlight Setup Wizard + sleep 1000 + ControlClick, Button4, Torchlight Setup, Completing the Torchlight Setup Wizard + ControlClick, Button2, Torchlight Setup, Completing the Torchlight Setup Wizard + } + WinWaitClose, Torchlight Setup + " +} + +#---------------------------------------------------------------- + +w_metadata twfc games \ + title="Transformers: War for Cybertron" \ + publisher="Activision" \ + year="2010" \ + media="dvd" \ + file1="TWFC_DVD.iso" + +load_twfc() +{ + w_read_key + w_mount TWFC_DVD + + w_ahk_do " + run ${W_ISO_MOUNT_LETTER}:setup.exe + SetTitleMatchMode, 2 + winwait, Activision, Select the language for the installation + if ( w_opt_unattended > 0 ) { + sleep 1000 + controlclick, Button1, Activision, Select the language for the installation + winwait, Transformers, Press NEXT to verify your key + sleep 1000 + send ${W_KEY} + send {Enter} + winwait, Keycode Check, The Keycode you entered appears to be valid + sleep 1000 + send {Enter} + winwait, Transformers, The InstallShield Wizard will install Transformers + sleep 1000 + controlclick, Button1, Transformers, The InstallShield Wizard will install Transformers + winwait, Transformers, License Agreement + sleep 1000 + controlclick, Button5, Transformers, License Agreement + sleep 1000 + controlclick, Button2, Transformers, License Agreement + winwait, Transformers, Minimum System Requirements + sleep 1000 + controlclick, Button1, Transformers, Minimum System Requirements + winwait, Transformers, Select the setup type to install + sleep 1000 + controlclick, Button4, Transformers, Select the setup type to install + } + ; Installer exits silently. Prevent an early umount + Loop + { + sleep 1000 + IfWinExist, Transformers + continue + IfWinExist, Activision + continue + sleep 1000 + IfWinExist, Transformers + continue + IfWinExist, Activision + continue + break + } + " + + # Clean up crap left over in c:\ when the installer runs the vc 2008 redistributable installer + w_try_cd "${W_DRIVE_C}" + rm -f VC_RED.* eula.*.txt globdata.ini install.exe install.ini install.res.*.dll vcredist.bmp +} + +#---------------------------------------------------------------- + +w_metadata typingofthedead_demo games \ + title="Typing of the Dead Demo" \ + publisher="Sega" \ + year="1999" \ + media="manual_download" \ + file1="Tod_e_demo.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/SEGA/TOD-Demo/Tod_e_demo.exe" + +load_typingofthedead_demo() +{ + w_download_manual "https://www.fileplanet.com/54947/50000/fileinfo/The-Typing-of-the-Dead-Demo" tod-demo.zip feb0888b6cf1d51af2bf3d752e1727b5d248c2704ca053561f384b55e86267ea + w_try_cd "${W_TMP}" + w_try_unzip . "${W_CACHE}/${W_PACKAGE}/tod-demo.zip" + w_ahk_do " + SetTitleMatchMode, 2 + run SETUP.EXE + if ( w_opt_unattended > 0 ) { + WinWait,InstallShield Wizard,where + sleep 1000 + ControlClick Button1 ; Next + WinWait,InstallShield Wizard,icons + sleep 1000 + ControlClick Button2 ; Next + } + ; installer crashes here? + Sleep 20000 + " +} + +#---------------------------------------------------------------- + +w_metadata ut3 games \ + title="Unreal Tournament 3" \ + publisher="Midway Games" \ + year="2007" \ + media="dvd" \ + file1="UT3_RC7.iso" \ + file2="UT3Patch5.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Unreal Tournament 3/Binaries/UT3.exe" + +load_ut3() +{ + w_download_manual "http://www.filefront.com/13709855/UT3Patch5.exe" UT3Patch5.exe + w_try w_mount UT3_RC7 + + w_ahk_do " + run ${W_ISO_MOUNT_LETTER}:SetupUT3.exe + SetTitleMatchMode, slow ; else can't see EULA text + SetTitleMatchMode, 2 + SetWinDelay 1000 + WinWait, Choose Setup Language + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; OK + WinWait, Unreal Tournament 3, GAMESPY ; License Agreement + ControlClick Button2 ; Yes + WinWait, Unreal Tournament 3, UnrealEd ; License Agreement + ControlClick Button2 ; Yes + WinWait, , Choose Destination + ControlClick Button1 ; Next + WinWait, AGEIA PhysX v7.09.13 Setup, License + ControlClick Button3 ; Accept + sleep 1000 + ControlClick Button4 ; Next + WinWait, AGEIA PhysX v7.09.13, Finish + ControlClick Button1 ; Finish + ; game now begins installing + } + WinWait, , InstallShield Wizard Complete + if ( w_opt_unattended > 0 ) { + ControlClick Button4 ; Finish + } + WinWaitClose + " + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + + w_ahk_do " + SetTitleMatchMode, 2 + run UT3Patch5.exe + WinWait, License + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; Accept + WinWait, End User License Agreement + ControlClick Button1 ; Accept + WinWait, Patch UT3 + ControlClick Button1 ; Yes + } + WinWait, , UT3 was successfully patched! + if ( w_opt_unattended > 0 ) { + ControlClick Button1 ; OK + } + WinWaitClose + " +} + +#---------------------------------------------------------------- + +w_metadata wog games \ + title="World of Goo Demo" \ + publisher="2D Boy" \ + year="2008" \ + media="download" \ + file1="WorldOfGooDemo.1.0.exe" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/WorldOfGooDemo/WorldOfGoo.exe" + +load_wog() +{ + if ! test -f "${W_CACHE}/wog/WorldOfGooDemo.1.0.exe"; then + # Get temporary download location + w_download "https://www.worldofgoo.com/dl2.php?lk=demo&filename=WorldOfGooDemo.1.0.exe" + URL=$(grep WorldOfGooDemo.1.0.exe "${W_CACHE}/wog/dl2.php?lk=demo&filename=WorldOfGooDemo.1.0.exe" \ + | sed 's,.*http,http,;s,".*,,') + w_try rm "${W_CACHE}/wog/dl2.php?lk=demo&filename=WorldOfGooDemo.1.0.exe" + + w_download "${URL}" 07892e927e0c403a178717b67928d3b4126dd0ed4f82afa20a4bd2496706c5e9 + fi + + w_try_cd "${W_CACHE}/${W_PACKAGE}" + w_ahk_do " + SetWinDelay 500 + run WorldOfGooDemo.1.0.exe + winwait, World of Goo Setup, License Agreement + if ( w_opt_unattended > 0 ) { + sleep 1000 + WinActivate + send {Enter} + winwait, World of Goo Setup, Choose Components + send {Enter} + winwait, World of Goo Setup, Choose Install Location + send {Enter} + winwait, World of Goo Setup, Thank you + ControlClick, Make me dirty right now, World of Goo Setup, Thank you + send {Enter} + } + winwaitclose, World of Goo Setup + " +} + +#---------------------------------------------------------------- +# Steam Games +#---------------------------------------------------------------- + +w_metadata alienswarm_steam games \ + title="Alien Swarm (Steam)" \ + publisher="Valve" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/alien swarm/swarm.exe" + +load_alienswarm_steam() +{ + w_steam_install_game 630 "Alien Swarm" +} + +#---------------------------------------------------------------- + +w_metadata bioshock2_steam games \ + title="Bioshock 2 (Steam)" \ + publisher="2k" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/bioshock2/blort.exe" + +load_bioshock2_steam() +{ + w_steam_install_game 8850 "BioShock 2" +} + +#---------------------------------------------------------------- + +w_metadata borderlands_steam games \ + title="Borderlands (Steam, non-free)" \ + publisher="2K Games" \ + year="2009" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/borderlands/Binaries/Borderlands.exe" + +load_borderlands_steam() +{ + w_steam_install_game 8980 "Borderlands" +} + +#---------------------------------------------------------------- + +w_metadata civ5_demo_steam games \ + title="Civilization V Demo (Steam)" \ + publisher="2K Games" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/sid meier's civilization v - demo/CivilizationV.exe" + +load_civ5_demo_steam() +{ + # Start AutoHotKey watching for DirectX 9 option in the background, and select it when it comes up + w_ahk_do " + SetWinDelay 500 + loop + { + ifWinExist, Sid Meier's Civilization V - Demo - Steam + { + winactivate + click 26,108 ; select directx9 + sleep 500 + click 200,150 ; Play + } + ifWinExist, Updating Sid Meier's Civilization V - Demo + { + break + } + sleep 1000 + } + " & + _job=$! + # While that's running, install the game. + # You'll see *two* AutoHotKey icons until that first script + # finds the dialog it's looking for, clicks, and exits. + w_info "If you already own the full Civ 5 game on Steam, the installer won't even appear." + w_steam_install_game 65900 "Sid Meier's Civilization V - Demo" + kill -s HUP "${_job}" # just in case +} + +#---------------------------------------------------------------- + +w_metadata ruse_demo_steam games \ + title="Ruse Demo (Steam)" \ + publisher="Ubisoft" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/r.u.s.e. demo/Ruse.exe" + +load_ruse_demo_steam() +{ + w_steam_install_game 33310 "R.U.S.E." +} + +#---------------------------------------------------------------- + +w_metadata supermeatboy_steam games \ + title="Super Meat Boy (Steam, non-free)" \ + publisher="Independent" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/super meat boy/SuperMeatBoy.exe" + +load_supermeatboy_steam() +{ + w_steam_install_game 40800 "Super Meat Boy" +} + +#---------------------------------------------------------------- + +w_metadata trine_steam games \ + title="Trine (Steam)" \ + publisher="Frozenbyte" \ + year="2009" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/trine/trine_launcher.exe" + +load_trine_steam() +{ + w_steam_install_game 35700 "Trine" +} + +#---------------------------------------------------------------- + +w_metadata trine_demo_steam games \ + title="Trine Demo (Steam)" \ + publisher="Frozenbyte" \ + year="2009" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/trine demo/trine_launcher.exe" + +load_trine_demo_steam() +{ + w_steam_install_game 35710 "Trine Demo" +} + +#---------------------------------------------------------------- + +w_metadata wormsreloaded_demo_steam games \ + title="Worms Reloaded Demo (Steam)" \ + publisher="Team17" \ + year="2010" \ + media="download" \ + installed_exe1="${W_PROGRAMS_X86_WIN}/Steam/steamapps/common/worms reloaded/WormsReloaded.exe" + +load_wormsreloaded_demo_steam() +{ + w_steam_install_game 22690 "Worms Reloaded Demo" +} + +####################### +# settings +####################### + +#### +# settings->desktop +#---------------------------------------------------------------- +# DirectInput settings + +w_metadata mwo=force settings \ + title_uk="Встановити примусове DirectInput MouseWarpOverride (необхідно для деяких ігор)" \ + title="Set DirectInput MouseWarpOverride to force (needed by some games)" +w_metadata mwo=enabled settings \ + title_uk="Увімкнути DirectInput MouseWarpOverride (за замовчуванням)" \ + title="Set DirectInput MouseWarpOverride to enabled (default)" +w_metadata mwo=disable settings \ + title_uk="Вимкнути DirectInput MouseWarpOverride" \ + title="Set DirectInput MouseWarpOverride to disable" + +load_mwo() +{ + # Filter out/correct bad or partial values + # Confusing because dinput uses 'disable', but d3d uses 'disabled' + # see alloc_device() in dlls/dinput/mouse.c + case "$1" in + enable*) arg=enabled;; + disable*) arg=disable;; + force) arg=force;; + *) w_die "illegal value $1 for MouseWarpOverride";; + esac + + echo "Setting MouseWarpOverride to ${arg}" + cat > "${W_TMP}"/set-mwo.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\DirectInput] +"MouseWarpOverride"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-mwo.reg +} + +#---------------------------------------------------------------- + +w_metadata fontfix settings \ + title_uk="Перевірка шрифтів" \ + title="Check for broken fonts" + +load_fontfix() +{ + # Focht says Samyak is bad news, and font substitution isn't a good workaround. + # I've seen psdkwin7 setup crash because of this; the symptom was a messagebox saying + # SDKSetup encountered an error: The type initializer for 'Microsoft.WizardFramework.WizardSettings' threw an exception + # and WINEDEBUG=+relay,+seh shows an exception very quickly after + # Call KERNEL32.CreateFileW(0c83b36c L"Z:\\USR\\SHARE\\FONTS\\TRUETYPE\\TTF-ORIYA-FONTS\\SAMYAK-ORIYA.TTF",80000000,00000001,00000000,00000003,00000080,00000000) ret=70d44091 + if [ -x "$(command -v xlsfonts 2>/dev/null)" ] ; then + if xlsfonts 2>/dev/null | grep -E -i "samyak.*oriya" ; then + w_die "Please uninstall the Samyak/Oriya font, e.g. 'sudo dpkg -r ttf-oriya-fonts', then log out and log in again. That font causes strange crashes in .net programs." + fi + else + w_warn "xlsfonts not found. If you have (older versions of) Samyak/Oriya fonts installed, you may get crashes/bugs. If so, uninstall, then logout/login again to resolve." + fi +} + +#---------------------------------------------------------------- + +w_metadata fontsmooth=disable settings \ + title_uk="Вимкнути згладжування шрифту" \ + title="Disable font smoothing" +w_metadata fontsmooth=bgr settings \ + title_uk="Увімкнути субпіксельне згладжування шрифту для BGR LCD моніторів" \ + title="Enable subpixel font smoothing for BGR LCDs" +w_metadata fontsmooth=rgb settings \ + title_uk="Увімкнути субпіксельне згладжування шрифту для RGB LCD моніторів" \ + title="Enable subpixel font smoothing for RGB LCDs" +w_metadata fontsmooth=gray settings \ + title_uk="Увімкнути субпіксельне згладжування шрифту" \ + title="Enable subpixel font smoothing" + +load_fontsmooth() +{ + case "$1" in + disable) FontSmoothing=0; FontSmoothingOrientation=1; FontSmoothingType=0;; + gray|grey) FontSmoothing=2; FontSmoothingOrientation=1; FontSmoothingType=1;; + bgr) FontSmoothing=2; FontSmoothingOrientation=0; FontSmoothingType=2;; + rgb) FontSmoothing=2; FontSmoothingOrientation=1; FontSmoothingType=2;; + *) w_die "unknown font smoothing type $1";; + esac + + echo "Setting font smoothing to $1" + + cat > "${W_TMP}"/fontsmooth.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Control Panel\\Desktop] +"FontSmoothing"="${FontSmoothing}" +"FontSmoothingGamma"=dword:00000578 +"FontSmoothingOrientation"=dword:0000000${FontSmoothingOrientation} +"FontSmoothingType"=dword:0000000${FontSmoothingType} + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\fontsmooth.reg +} + +#---------------------------------------------------------------- +# Mac Driver settings + +w_metadata macdriver=mac settings \ + title_uk="Увімкнути рідний Mac Quartz драйвер (за замовчуванням)" \ + title="Enable the Mac native Quartz driver (default)" +w_metadata macdriver=x11 settings \ + title_uk="Вимкнути рідний Mac Quartz драйвер та використовувати замість нього X11" \ + title="Disable the Mac native Quartz driver, use X11 instead" + +load_macdriver() +{ + echo "Setting MacDriver to ${arg}" + cat > "${W_TMP}"/set-mac.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Drivers] +"Graphics"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-mac.reg +} + +#---------------------------------------------------------------- + +w_metadata mackeyremap=both settings \ + title="Enable mapping opt->alt and cmd->ctrl keys for the Mac native driver" +w_metadata mackeyremap=left settings \ + title="Enable mapping of left opt->alt and cmd->ctrl keys for the Mac native driver" +w_metadata mackeyremap=none settings \ + title="Do not remap keys for the Mac native driver (default)" + +load_mackeyremap() +{ + case "$1" in + both|y) arg=both; _W_arg_l=y; _W_arg_r=y ;; + left) arg=left; _W_arg_l=y; _W_arg_r=n ;; + none|n) arg=none; _W_arg_l=n; _W_arg_r=n ;; + *) w_die "illegal value $1 for MacKeyRemap";; + esac + + echo "Setting MacKeyRemap to ${arg}" + cat > "${W_TMP}"/set-mackeyremap.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Mac Driver] +"LeftCommandIsCtrl"="${_W_arg_l}" +"LeftOptionIsAlt"="${_W_arg_l}" +"RightCommandIsCtrl"="${_W_arg_r}" +"RightOptionIsAlt"="${_W_arg_r}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-mackeyremap.reg + + unset _W_arg_l _W_arg_r +} + +#---------------------------------------------------------------- +# X11 Driver settings + +w_metadata grabfullscreen=y settings \ + title_uk="Примусове захоплення курсору для повноекранних вікон (необхідно для деяких ігор)" \ + title="Force cursor clipping for full-screen windows (needed by some games)" +w_metadata grabfullscreen=n settings \ + title_uk="Вимкнути примусове захоплення курсору для повноекранних вікон (за замовчуванням)" \ + title="Disable cursor clipping for full-screen windows (default)" + +load_grabfullscreen() +{ + case "$1" in + y|n) arg=$1;; + *) w_die "illegal value $1 for GrabFullscreen";; + esac + + echo "Setting GrabFullscreen to ${arg}" + cat > "${W_TMP}"/set-gfs.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver] +"GrabFullscreen"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-gfs.reg +} + +w_metadata windowmanagerdecorated=y settings \ + title_uk="Дозволити менеджеру вікон декорувати вікна (за замовчуванням)" \ + title="Allow the window manager to decorate windows (default)" +w_metadata windowmanagerdecorated=n settings \ + title_uk="Не дозволяти менеджеру вікон декорувати вікна" \ + title="Prevent the window manager from decorating windows" + +#---------------------------------------------------------------- + +w_metadata usetakefocus=y settings \ + title_cz="Aktivovat UseTakeFocus" \ + title_uk="Увімкнути фокусування на вікні" \ + title_sk="Aktivovať UseTakeFocus" \ + title_tlh="Qorwagh buSchoH \'e\' chu\'" \ + title="Enable UseTakeFocus" +w_metadata usetakefocus=n settings \ + title_cz="Deaktivovat UseTakeFocus (výchozí)" \ + title_uk="Вимкнути фокусування на вікні (за замовчуванням)" \ + title_sk="Deaktivovať UseTakeFocus (výchozí)" \ + title_tlh="Qorwagh buSchoH \'e\' chu\'Ha\' (DuH choHlu\'pu\'be\'bogh)" \ + title="Disable UseTakeFocus (default)" + +load_usetakefocus() +{ + case "$1" in + y) arg="Y";; + n) arg="N";; + *) w_die "illegal value $1 for UseTakeFocus";; + esac + + echo "Setting UseTakeFocus to ${arg}" + cat > "${W_TMP}"/set-usetakefocus.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver] +"UseTakeFocus"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-usetakefocus.reg +} + +#---------------------------------------------------------------- + +load_windowmanagerdecorated() +{ + case "$1" in + y|n) arg=$1;; + *) w_die "illegal value $1 for Decorated";; + esac + + echo "Setting Decorated to ${arg}" + cat > "${W_TMP}"/set-wmd.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver] +"Decorated"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-wmd.reg +} + +w_metadata windowmanagermanaged=y settings \ + title_uk="Дозволити менеджеру вікон керування вікнами (за замовчуванням)" \ + title="Allow the window manager to control windows (default)" +w_metadata windowmanagermanaged=n settings \ + title_uk="Не дозволяти менеджеру вікон керування вікнами" \ + title="Prevent the window manager from controlling windows" + +#---------------------------------------------------------------- + +load_windowmanagermanaged() +{ + case "$1" in + y|n) arg=$1;; + *) w_die "illegal value $1 for Managed";; + esac + + echo "Setting Managed to ${arg}" + cat > "${W_TMP}"/set-wmm.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver] +"Managed"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-wmm.reg +} + +#---------------------------------------------------------------- + +w_metadata vd=off settings \ + title_uk="Вимкнути віртуальний робочий стіл" \ + title="Disable virtual desktop" +w_metadata vd=640x480 settings \ + title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 640x480" \ + title="Enable virtual desktop, set size to 640x480" +w_metadata vd=800x600 settings \ + title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 800x600" \ + title="Enable virtual desktop, set size to 800x600" +w_metadata vd=1024x768 settings \ + title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1024x768" \ + title="Enable virtual desktop, set size to 1024x768" +w_metadata vd=1280x1024 settings \ + title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1280x1024" \ + title="Enable virtual desktop, set size to 1280x1024" +w_metadata vd=1440x900 settings \ + title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1440x900" \ + title="Enable virtual desktop, set size to 1440x900" + +load_vd() +{ + size="$1" + case ${size} in + off|disabled) + cat > "${W_TMP}"/vd.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Explorer] +"Desktop"=- +[HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops] +"Default"=- + +_EOF_ + ;; + [1-9]*x[1-9]*) + cat > "${W_TMP}"/vd.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Explorer] +"Desktop"="Default" +[HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops] +"Default"="${size}" + +_EOF_ + ;; + *) + w_die "you want a virtual desktop of ${size}? I don't understand." + ;; + esac + w_try_regedit "${W_TMP_WIN}"/vd.reg +} + +#---------------------------------------------------------------- +# MIME-type file associations settings + +w_metadata mimeassoc=on settings \ + title="Enable exporting MIME-type file associations to the native desktop (default)" +w_metadata mimeassoc=off settings \ + title="Disable exporting MIME-type file associations to the native desktop" + +load_mimeassoc() +{ + case "$1" in + off) arg=N;; + on) arg=Y;; + *) w_die "illegal value $1 for mimeassoc";; + esac + + echo "Setting mimeassoc to ${arg}" + cat > "${W_TMP}"/set-mimeassoc.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\FileOpenAssociations] +"Enable"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP}"/set-mimeassoc.reg +} + +#### +# settings->direct3d + +winetricks_set_wined3d_var() +{ + # Filter out/correct bad or partial values + # Confusing because dinput uses 'disable', but d3d uses 'disabled' + # see wined3d_dll_init() in dlls/wined3d/wined3d_main.c + # and DllMain() in dlls/ddraw/main.c + case $2 in + disable*) arg=disabled;; + enable*) arg=enabled;; + hard*) arg=hardware;; + repack) arg=repack;; + arb|backbuffer|fbo|gdi|gl|glsl|no3d|none|readdraw|readtex|texdraw|textex|vulkan|auto) arg=$2;; + [0-9]*) arg=$2;; + *) w_die "illegal value $2 for $1";; + esac + + echo "Setting Direct3D/$1 to ${arg}" + cat > "${W_TMP}"/set-wined3d.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D] +"$1"="${arg}" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-wined3d.reg +} + +#---------------------------------------------------------------- +# CheckFloatConstants settings + +w_metadata cfc=enabled settings \ + title_uk="Увімкнути CheckFloatConstants" \ + title="Enable CheckFloatConstants" +w_metadata cfc=disabled settings \ + title_uk="Вимкнути CheckFloatConstants (за замовчуванням)" \ + title="Disable CheckFloatConstants (default)" + +load_cfc() +{ + winetricks_set_wined3d_var CheckFloatConstants "$1" +} +#---------------------------------------------------------------- +# CSMT settings + +w_metadata csmt=force settings \ + title_uk="Увімкнути та примусити серіалізацію команд OpenGL або Vulkan між кількома потоками команд в одній програмі" \ + title="Enable and force serialisation of OpenGL or Vulkan commands between multiple command streams in the same application" +w_metadata csmt=on settings \ + title_uk="Увімкнути Command Stream Multithreading (за замовчуванням)" \ + title="Enable Command Stream Multithreading (default)" +w_metadata csmt=off settings \ + title_uk="Вимкнути Command Stream Multithreading"\ + title="Disable Command Stream Multithreading" + +load_csmt() +{ + case "$1" in + off) arg=0;; + on) arg=1;; + force) arg=3;; + *) w_die "illegal value $1 for csmt";; + esac + + echo "Setting csmt to ${arg}" + cat > "${W_TMP}"/set-csmt.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D] +"csmt"=dword:${arg} + +_EOF_ + w_try_regedit "${W_TMP}"/set-csmt.reg +} + +#---------------------------------------------------------------- +# DirectDraw settings + +w_metadata gsm=0 settings \ + title_uk="Встановити MaxShaderModelGS на 0" \ + title="Set MaxShaderModelGS to 0" +w_metadata gsm=1 settings \ + title_uk="Встановити MaxShaderModelGS на 1" \ + title="Set MaxShaderModelGS to 1" +w_metadata gsm=2 settings \ + title_uk="Встановити MaxShaderModelGS на 2" \ + title="Set MaxShaderModelGS to 2" +w_metadata gsm=3 settings \ + title_uk="Встановити MaxShaderModelGS на 3" \ + title="Set MaxShaderModelGS to 3" + +load_gsm() +{ + winetricks_set_wined3d_var MaxShaderModelGS "$1" +} + +#---------------------------------------------------------------- + +w_metadata npm=repack settings \ + title_uk="Встановити NonPower2Mode на repack" \ + title="Set NonPower2Mode to repack" + +load_npm() +{ + winetricks_set_wined3d_var NonPower2Mode "$1" +} + +#---------------------------------------------------------------- + +w_metadata orm=fbo settings \ + title_uk="Встановити OffscreenRenderingMode=fbo (за замовчуванням)" \ + title="Set OffscreenRenderingMode=fbo (default)" +w_metadata orm=backbuffer settings \ + title_uk="Встановити OffscreenRenderingMode=backbuffer" \ + title="Set OffscreenRenderingMode=backbuffer" + +load_orm() +{ + winetricks_set_wined3d_var OffscreenRenderingMode "$1" +} + +#---------------------------------------------------------------- + +w_metadata psm=0 settings \ + title_uk="Встановити MaxShaderModelPS на 0" \ + title="Set MaxShaderModelPS to 0" +w_metadata psm=1 settings \ + title_uk="Встановити MaxShaderModelPS на 1" \ + title="Set MaxShaderModelPS to 1" +w_metadata psm=2 settings \ + title_uk="Встановити MaxShaderModelPS на 2" \ + title="Set MaxShaderModelPS to 2" +w_metadata psm=3 settings \ + title_uk="Встановити MaxShaderModelPS на 3" \ + title="Set MaxShaderModelPS to 3" + +load_psm() +{ + winetricks_set_wined3d_var MaxShaderModelPS "$1" +} + +#---------------------------------------------------------------- + +w_metadata shader_backend=glsl settings \ + title_uk="Встановити shader_backend на glsl" \ + title="Set shader_backend to glsl" +w_metadata shader_backend=arb settings \ + title_uk="Встановити shader_backend на arb" \ + title="Set shader_backend to arb" +w_metadata shader_backend=none settings \ + title_uk="Встановити shader_backend на none" \ + title="Set shader_backend to none" + +load_shader_backend() +{ + winetricks_set_wined3d_var shader_backend "$1" +} + +#---------------------------------------------------------------- + +w_metadata ssm=disabled settings \ + title_uk="Вимкнути Struct Shader Math (за замовчуванням)" \ + title="Disable Struct Shader Math (default)" +w_metadata ssm=enabled settings \ + title_uk="Увімкнути Struct Shader Math"\ + title="Enable Struct Shader Math" + +load_ssm() +{ + case "$1" in + disabled) arg=0;; + enabled) arg=1;; + *) w_die "illegal value $1 for csmt";; + esac + + echo "Setting strict_shader_math to ${arg}" + cat > "${W_TMP}"/set-ssm.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D] +"strict_shader_math"=dword:${arg} + +_EOF_ + w_try_regedit "${W_TMP}"/set-ssm.reg +} + +#---------------------------------------------------------------- + +w_metadata renderer=gdi settings \ + title_uk="Встановити renderer на gdi" \ + title="Set renderer to gdi" +w_metadata renderer=gl settings \ + title_uk="Встановити renderer на gl" \ + title="Set renderer to gl" +w_metadata renderer=no3d settings \ + title_uk="Встановити renderer на no3d" \ + title="Set renderer to no3d" +w_metadata renderer=vulkan settings \ + title_uk="Встановити renderer на vulkan" \ + title="Set renderer to vulkan" + +load_renderer() +{ + winetricks_set_wined3d_var renderer "$1" +} + +#----------------------------------------------------------------= + +w_metadata rtlm=auto settings \ + title_uk="Встановити RenderTargetLockMode на авто (за замовчуванням)" \ + title="Set RenderTargetLockMode to auto (default)" +w_metadata rtlm=disabled settings \ + title_uk="Вимкнути RenderTargetLockMode" \ + title="Set RenderTargetLockMode to disabled" +w_metadata rtlm=readdraw settings \ + title_uk="Встановити RenderTargetLockMode на readdraw" \ + title="Set RenderTargetLockMode to readdraw" +w_metadata rtlm=readtex settings \ + title_uk="Встановити RenderTargetLockMode на readtex" \ + title="Set RenderTargetLockMode to readtex" +w_metadata rtlm=texdraw settings \ + title_uk="Встановити RenderTargetLockMode на texdraw" \ + title="Set RenderTargetLockMode to texdraw" +w_metadata rtlm=textex settings \ + title_uk="Встановити RenderTargetLockMode на textex" \ + title="Set RenderTargetLockMode to textex" + +load_rtlm() +{ + winetricks_set_wined3d_var RenderTargetLockMode "$1" +} + +#---------------------------------------------------------------- + +w_metadata set_mididevice settings \ + title="Set MIDImap device to the value specified in the MIDI_DEVICE environment variable" + +load_set_mididevice() +{ + if [ -z "${MIDI_DEVICE}" ]; then + MIDI_DEVICE=$(w_question "Please specify MIDImap device: ") + [ -z "${MIDI_DEVICE}" ] && w_die "Please specify device in MIDI_DEVICE environment variable." + fi + + echo "Setting MIDI device to \"${MIDI_DEVICE}\"" + cat > "${W_TMP}"/set-mididevice.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Multimedia\MIDIMap] +"CurrentInstrument"="${MIDI_DEVICE}" +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-mididevice.reg +} + +#---------------------------------------------------------------- + +w_metadata videomemorysize=default settings \ + title_uk="Дати можливість Wine визначити розмір відеопам'яті" \ + title="Let Wine detect amount of video card memory" +w_metadata videomemorysize=512 settings \ + title_uk="Повідомити Wine про 512МБ відеопам'яті" \ + title="Tell Wine your video card has 512MB RAM" +w_metadata videomemorysize=1024 settings \ + title_uk="Повідомити Wine про 1024МБ відеопам'яті" \ + title="Tell Wine your video card has 1024MB RAM" +w_metadata videomemorysize=2048 settings \ + title_uk="Повідомити Wine про 2048МБ відеопам'яті" \ + title="Tell Wine your video card has 2048MB RAM" + +load_videomemorysize() +{ + size="$1" + echo "Setting video memory size to ${size}" + + case ${size} in + default) + + cat > "${W_TMP}"/set-video.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D] +"VideoMemorySize"=- + +_EOF_ + ;; + *) + cat > "${W_TMP}"/set-video.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D] +"VideoMemorySize"="${size}" + +_EOF_ + ;; + esac + w_try_regedit "${W_TMP_WIN}"\\set-video.reg +} + +#---------------------------------------------------------------- + +w_metadata vsm=0 settings \ + title_uk="Встановити MaxShaderModelVS на 0" \ + title="Set MaxShaderModelVS to 0" +w_metadata vsm=1 settings \ + title_uk="Встановити MaxShaderModelVS на 1" \ + title="Set MaxShaderModelVS to 1" +w_metadata vsm=2 settings \ + title_uk="Встановити MaxShaderModelVS на 2" \ + title="Set MaxShaderModelVS to 2" +w_metadata vsm=3 settings \ + title_uk="Встановити MaxShaderModelVS на 3" \ + title="Set MaxShaderModelVS to 3" + +load_vsm() +{ + winetricks_set_wined3d_var MaxShaderModelVS "$1" +} + +#### +# settings->debug + +#---------------------------------------------------------------- + +w_metadata autostart_winedbg=enabled settings \ + title="Automatically launch winedbg when an unhandled exception occurs (default)" +w_metadata autostart_winedbg=disabled settings \ + title="Prevent winedbg from launching when an unhandled exception occurs" + +load_autostart_winedbg() +{ + case "${arg}" in + # accidentally commited as enable/disable, so accept that, but prefer enabled/disabled + enable|enabled) _W_debugger_value="winedbg --auto %ld %ld";; + disable|disabled) _W_debugger_value="false";; + *) w_die "Unexpected argument '${arg}'. Should be enable/disable";; + esac + + echo "Setting HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\Debugger to '${arg}'" + cat > "${W_TMP}"/autostart_winedbg.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug] +"Debugger"="${_W_debugger_value}" +_EOF_ + + w_try_regedit "${W_TMP_WIN}"\\autostart_winedbg.reg + w_backup_reg_file "${W_TMP}"/autostart_winedbg.reg + + unset _W_debugger_value +} + +#---------------------------------------------------------------- + +w_metadata heapcheck settings \ + title_uk="Увімкнути накопичувальну перевірку GlobalFlag" \ + title="Enable heap checking with GlobalFlag" + +load_heapcheck() +{ + cat > "${W_TMP}"/heapcheck.reg <<_EOF_ +REGEDIT4 + +[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager] +"GlobalFlag"=dword:00200030 + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\heapcheck.reg +} + +#---------------------------------------------------------------- + +w_metadata nocrashdialog settings \ + title_uk="Вимкнути діалог про помилку" \ + title="Disable crash dialog" + +load_nocrashdialog() +{ + echo "Disabling graphical crash dialog" + cat > "${W_TMP}"/crashdialog.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\WineDbg] +"ShowCrashDialog"=dword:00000000 + +_EOF_ + w_try_cd "${W_TMP}" + w_try_regedit crashdialog.reg +} + +w_metadata set_userpath settings \ + title_uk="" \ + title="set user PATH variable in wine prefix specified by native and/or wine paths in WINEPATH environment variable with ';' as path separator" + +load_set_userpath() +{ + wineuserpath=$(winepath -w "${WINEPATH}" | sed 's,\\,\\\\,g') + cat > "${W_TMP}"/setuserpath.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Environment] +"PATH"="${wineuserpath}" + +_EOF_ + w_try_cd "${W_TMP}" + w_try_regedit setuserpath.reg +} + +#### +# settings->misc + +w_metadata alldlls=default settings \ + title_uk="Видалити всі перевизначення DLL" \ + title="Remove all DLL overrides" +w_metadata alldlls=builtin settings \ + title_uk="Перевизначити найбільш поширені DLL на вбудовані" \ + title="Override most common DLLs to builtin" + +load_alldlls() +{ + case "$1" in + default) w_override_no_dlls ;; + builtin) w_override_all_dlls ;; + esac +} + +#---------------------------------------------------------------- + +w_metadata bad settings \ + title="Fake verb that always returns false" + +load_bad() +{ + w_die "${W_PACKAGE} failed!" +} + +#---------------------------------------------------------------- + +w_metadata forcemono settings \ + title_uk="Примусове використання mono замість .NET (для налагодження)" \ + title="Force using Mono instead of .NET (for debugging)" + +load_forcemono() +{ + w_override_dlls native mscoree + w_override_dlls disabled mscorsvw.exe +} + +#---------------------------------------------------------------- + +w_metadata good settings \ + title="Fake verb that always returns true" + +load_good() +{ + w_info "${W_PACKAGE} succeeded!" +} + +#---------------------------------------------------------------- + +w_metadata hidewineexports=enable settings \ + title="Enable hiding Wine exports from applications (wine-staging)" +w_metadata hidewineexports=disable settings \ + title="Disable hiding Wine exports from applications (wine-staging)" + +load_hidewineexports() +{ + # Wine exports some functions allowing apps to query the Wine version and + # information about the host environment. Using these functions, some apps + # will intentionally terminate if they can detect that they are running in + # a Wine environment. + # + # Hiding these Wine exports is only available in wine-staging. + # See https://bugs.winehq.org/show_bug.cgi?id=38656 + case ${arg} in + enable) + _W_registry_value="\"Y\"" + ;; + disable) + _W_registry_value="-" + ;; + *) w_die "Unexpected argument, ${arg}";; + esac + + cat > "${W_TMP}"/set-wineexports.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine] +"HideWineExports"=${_W_registry_value} + +_EOF_ + w_try_regedit "${W_TMP}"/set-wineexports.reg +} + +#---------------------------------------------------------------- + +w_metadata hosts settings \ + title_uk="Додати порожні файли у C:\\windows\\system32\\drivers\\etc\\{hosts,services}" \ + title="Add empty C:\\windows\\system32\\drivers\\etc\\{hosts,services} files" + +load_hosts() +{ + # Create fake system32\drivers\etc\hosts and system32\drivers\etc\services files. + # The hosts file is used to map network names to IP addresses without DNS. + # The services file is used map service names to network ports. + # Some apps depend on these files, but they're not implemented in Wine. + # Fortunately, empty files in the correct location satisfy those apps. + # See https://bugs.winehq.org/show_bug.cgi?id=12076 + + # It's in system32 for both win32/win64 + mkdir -p "${W_WINDIR_UNIX}"/system32/drivers/etc + touch "${W_WINDIR_UNIX}"/system32/drivers/etc/hosts + touch "${W_WINDIR_UNIX}"/system32/drivers/etc/services +} + +#---------------------------------------------------------------- + +w_metadata isolate_home settings \ + title_uk="Видалити посилання на вино преміум на \$HOME" \ + title="Remove wineprefix links to \$HOME" + +load_isolate_home() +{ + w_skip_windows isolate_home && return + + _olddir="$(pwd)" + w_try_cd "${WINEPREFIX}/drive_c/users/${USER}" + for x in *; do + if test -h "${x}" && test -d "${x}"; then + rm -f "${x}" + mkdir -p "${x}" + fi + done + w_try_cd "${_olddir}" + unset _olddir + + # Workaround for: + # https://bugs.winehq.org/show_bug.cgi?id=22450 (sandbox verb) + # https://bugs.winehq.org/show_bug.cgi?id=22974 (isolate_home, sandbox verbs) + echo disable > "${WINEPREFIX}/.update-timestamp" +} + +#---------------------------------------------------------------- + +w_metadata native_mdac settings \ + title_uk="Перевизначити odbc32, odbccp32 та oledb32" \ + title="Override odbc32, odbccp32 and oledb32" + +load_native_mdac() +{ + # Set those overrides globally so user programs get MDAC's ODBC + # instead of Wine's unixodbc + + # https://github.com/Winetricks/winetricks/issues/1447 + if w_wine_version_in 4.22, ; then + w_override_dlls native,builtin msado15 + fi + + # https://github.com/Winetricks/winetricks/issues/1448 + if w_wine_version_in ,4.22 ; then + w_override_dlls native,builtin odbccp32 + fi + + w_override_dlls native,builtin mtxdm odbc32 oledb32 +} + +#---------------------------------------------------------------- + +w_metadata native_oleaut32 settings \ + title_uk="Перевизначити oleaut32" \ + title="Override oleaut32" + +load_native_oleaut32() +{ + w_override_dlls native,builtin oleaut32 +} + +#---------------------------------------------------------------- + +w_metadata remove_mono settings \ + title_uk="Видалити вбудоване wine-mono" \ + title="Remove builtin wine-mono" + +load_remove_mono() +{ + # Wine before 4.6 installs 'Wine Mono' + # Beginning in 4.6, if using a shared install (i.e., a distro mono package or a tarball manually + # extracted to /usr/share/wine/mono, or equivalent), only 'Wine Mono Windows Support' will be installed. + # If using the old .msi installer, *both* tarballs are installed. + # + # So, we uninstall anything that has 'Wine Mono' in the name to handle both cases. + # If wine uninstaller can't find the application it will return 0 anyway. + mono_uuid="$("${WINE_ARCH}" uninstaller --list | grep 'Wine Mono' | cut -f1 -d\|)" + if test "${mono_uuid}"; then + for uuid in ${mono_uuid}; do + "${WINE_ARCH}" uninstaller --remove "${uuid}" + done + else + # Bail out if mono isn't installed, so we don't break .Net setups + w_warn "Mono does not appear to be installed." + return + fi + + # FIXME: verify on pristine Windows XP: + if w_workaround_wine_bug 34803; then + "${WINE_ARCH}" reg delete 'HKLM\\Software\\Microsoft\\.NETFramework\\v2.0.50727\\SBSDisabled' /f + fi + + "${WINE_ARCH}" reg delete "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v3.5" /f || true + "${WINE_ARCH}" reg delete "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4" /f || true + + w_try rm -f "${W_WINDIR_UNIX}/system32/mscoree.dll" + if [ "${W_ARCH}" = "win64" ]; then + w_try rm -f "${W_WINDIR_UNIX}/syswow64/mscoree.dll" + fi +} + + +#---------------------------------------------------------------- + +w_metadata sandbox settings \ + title_uk="Пісочниця wineprefix - видалити посилання до HOME" \ + title="Sandbox the wineprefix - remove links to \$HOME" + +load_sandbox() +{ + w_skip_windows sandbox && return + + # Unmap drive Z + w_try rm -f "${WINEPREFIX}/dosdevices/z:" + + # Disable unixfs + # Unfortunately, when you run with a different version of Wine, Wine will recreate this key. + # See https://bugs.winehq.org/show_bug.cgi?id=22450 + w_try_regedit /D "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace\\{9D20AAE8-0625-44B0-9CA7-71889C2254D9}" + + w_call isolate_home +} + +#### +# settings->sound + +#---------------------------------------------------------------- + +w_metadata sound=alsa settings \ + title_uk="Встановити звуковий драйвер ALSA" \ + title="Set sound driver to ALSA" +w_metadata sound=coreaudio settings \ + title_uk="Встановити звуковий драйвер Mac CoreAudio" \ + title="Set sound driver to Mac CoreAudio" +w_metadata sound=disabled settings \ + title_uk="Вимкнути звуковий драйвер" \ + title="Set sound driver to disabled" +w_metadata sound=oss settings \ + title_uk="Встановити звуковий драйвер OSS" \ + title="Set sound driver to OSS" +w_metadata sound=pulse settings \ + title_uk="Встановити звуковий драйвер PulseAudio" \ + title="Set sound driver to PulseAudio" + +load_sound() +{ + echo "Setting sound driver to $1" + cat > "${W_TMP}"/set-sound.reg <<_EOF_ +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\Drivers] +"Audio"="$1" + +_EOF_ + w_try_regedit "${W_TMP_WIN}"\\set-sound.reg +} + +# settings->winversions +#---------------------------------------------------------------- + +w_metadata nt351 settings \ + title_uk="Встановити версію Windows NT 3.51" \ + title="Set Windows version to Windows NT 3.51" + +load_nt351() +{ + w_package_unsupported_win64 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=41559" "" "5.7" + w_set_winver nt351 +} + +#---------------------------------------------------------------- + +w_metadata nt40 settings \ + title_uk="Встановити версію Windows NT 4.0" \ + title="Set Windows version to Windows NT 4.0" + +load_nt40() +{ + w_package_unsupported_win64 + w_set_winver nt40 +} + +#---------------------------------------------------------------- + +w_metadata vista settings \ + title_uk="Встановити версію Windows Vista" \ + title="Set Windows version to Windows Vista" + +load_vista() +{ + w_set_winver vista +} + +#---------------------------------------------------------------- + +w_metadata win20 settings \ + title_uk="Встановити версію Windows 2.0" \ + title="Set Windows version to Windows 2.0" + +load_win20() +{ + w_package_unsupported_win64 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=41559" "" "5.7" + w_set_winver win20 +} + +#---------------------------------------------------------------- + +w_metadata win2k settings \ + title_uk="Встановити версію Windows 2000" \ + title="Set Windows version to Windows 2000" + +load_win2k() +{ + w_package_unsupported_win64 + w_set_winver win2k +} + +#---------------------------------------------------------------- + +w_metadata win2k3 settings \ + title_uk="Встановити версію Windows 2003" \ + title="Set Windows version to Windows 2003" + +load_win2k3() +{ + w_set_winver win2k3 +} + +#---------------------------------------------------------------- + +w_metadata win2k8 settings \ + title_uk="Встановити версію Windows 2008" \ + title="Set Windows version to Windows 2008" + +load_win2k8() +{ + w_set_winver win2k8 +} + +#---------------------------------------------------------------- + +w_metadata win2k8r2 settings \ + title_uk="Встановити версію Windows 2008 R2" \ + title="Set Windows version to Windows 2008 R2" + +load_win2k8r2() +{ + w_set_winver win2k8r2 +} + +#---------------------------------------------------------------- + +w_metadata win30 settings \ + title_uk="Встановити версію Windows 3.0" \ + title="Set Windows version to Windows 3.0" + +load_win30() +{ + w_package_unsupported_win64 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=41559" "" "5.7" + w_set_winver win30 +} + +#---------------------------------------------------------------- + +w_metadata win31 settings \ + title_uk="Встановити версію Windows 3.1" \ + title="Set Windows version to Windows 3.1" + +load_win31() +{ + w_package_unsupported_win64 + w_set_winver win31 +} + +#---------------------------------------------------------------- + +w_metadata win7 settings \ + title_uk="Встановити версію Windows 7" \ + title="Set Windows version to Windows 7" + +load_win7() +{ + w_set_winver win7 +} + +#---------------------------------------------------------------- + +w_metadata win8 settings \ + title_uk="Встановити версію Windows 8" \ + title="Set Windows version to Windows 8" + +load_win8() +{ + w_set_winver win8 +} + +#---------------------------------------------------------------- + +w_metadata win81 settings \ + title_uk="Встановити версію Windows 8.1" \ + title="Set Windows version to Windows 8.1" + +load_win81() +{ + w_set_winver win81 +} + +#---------------------------------------------------------------- + +w_metadata win10 settings \ + title_uk="Встановити версію Windows 10" \ + title="Set Windows version to Windows 10" + +load_win10() +{ + w_set_winver win10 +} + +#---------------------------------------------------------------- + +w_metadata win95 settings \ + title_uk="Встановити версію Windows 95" \ + title="Set Windows version to Windows 95" + +load_win95() +{ + w_package_unsupported_win64 + w_set_winver win95 +} + +#---------------------------------------------------------------- + +w_metadata win98 settings \ + title_uk="Встановити версію Windows 98" \ + title="Set Windows version to Windows 98" + +load_win98() +{ + w_package_unsupported_win64 + w_set_winver win98 +} + +#---------------------------------------------------------------- + +w_metadata winme settings \ + title_uk="Встановити версію Windows ME" \ + title="Set Windows version to Windows ME" + +load_winme() +{ + w_package_unsupported_win64 + w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=41559" "" "5.7" + w_set_winver winme +} + +#---------------------------------------------------------------- + +# Really, we should support other values, since winetricks did +w_metadata winver= settings \ + title_uk="Встановити версію Windows за замовчуванням (Windows 7)" \ + title="Set Windows version to default (win7)" + +load_winver() +{ + w_set_winver win7 +} + +#---------------------------------------------------------------- + +w_metadata winxp settings \ + title_uk="Встановити версію Windows XP" \ + title="Set Windows version to Windows XP" + +load_winxp() +{ + w_set_winver winxp +} + +#---- Main Program ---- + +winetricks_stats_save() +{ + # Save opt-in status + if test "${WINETRICKS_STATS_REPORT}"; then + if test ! -d "${W_CACHE}"; then + mkdir -p "${W_CACHE}" + fi + echo "${WINETRICKS_STATS_REPORT}" > "${W_CACHE}"/track_usage + fi +} + +winetricks_stats_init() +{ + # Load opt-in status if not already set by a command-line option + if test ! "${WINETRICKS_STATS_REPORT}" && test -f "${W_CACHE}"/track_usage; then + WINETRICKS_STATS_REPORT=$(cat "${W_CACHE}"/track_usage) + fi + + if test ! "${WINETRICKS_STATS_REPORT}"; then + # No opt-in status found. If GUI active, ask user whether they would like to opt in. + case ${WINETRICKS_GUI} in + zenity) + case ${LANG} in + de*) + title="Einmalige Frage zur Hilfe an der Winetricks Entwicklung" + question="Möchten Sie die Winetricks Entwicklung unterstützen indem Sie Winetricks Statistiken übermitteln lassen? Sie können die Übermittlung jederzeit mit 'winetricks --optout' ausschalten" + thanks="Danke! Sie bekommen diese Frage nicht mehr gestellt. Sie können die Übermittlung jederzeit mit 'winetricks --optout' wieder ausschalten" + declined="OK, Winetricks wird *keine* Statistiken übermitteln. Sie bekommen diese Frage nicht mehr gestellt." + ;; + pl*) + title="Jednorazowe pytanie dotyczące pomocy w rozwoju Winetricks" + question="Czy chcesz pomóc w rozwoju Winetricks pozwalając na wysyłanie statystyk przez program? Możesz wyłączyć tą opcję w każdej chwili z użyciem komendy 'winetricks --optout'." + thanks="Dziękujemy! Nie otrzymasz już tego pytania. Pamiętaj, ze możesz wyłączyć tą opcję komendą 'winetricks --optout'" + declined="OK, Winetricks *nie* będzie wysyłać statystyk. Nie otrzymasz już tego pytania." + ;; + pt*) + title="Pergunta única sobre ajudar no desenvolvimento do Winetricks" + question="Você gostaria de ajudar no desenvolvimento do winetricks, permitindo que o winetricks relate estatísticas? Você pode desativar o relatório a qualquer momento com o comando 'winetricks --optout'" + thanks="Obrigado! Esta pergunta não será feita novamente. Lembre-se, você pode desativar o relatório a qualquer momento com o comando 'winetricks --optout'" + declined="OK, winetricks *não* reportará estatísticas. Esta pergunta não será feita novamente." + ;; + ru*) + title="Помощь в разработке Winetricks" + question="Вы хотите помочь разработке winetricks, отправляя статистику? Вы можете отключить отправку статистики в любое время с помощью команды 'winetricks --optout'" + thanks="Спасибо! Этот вопрос больше не появится. Помните: вы можете отключить отправку статистики в любое время с помощью команды 'winetricks --optout'" + declined="OK, winetricks НЕ будет отправлять статистику. Этот вопрос больше не появится." + ;; + uk*) + title="Допомога в розробці Winetricks" + question="Ви хочете допомогти в розробці Winetricks дозволивши звітувати статистику?\\nВи можете в будь-який час вимкнути цю опцію за допомогою команди 'winetricks --optout'" + thanks="Дякуємо! Ви більше не отримуватиме це питання знову. Пам'ятайте, що ви можете будь-коли вимкнути звітність за допомогою команди 'winetricks --optout'" + declined="Надсилання звітності Winetricks вимкнено. Ви більше не отримуватиме це питання знову." + ;; + *) + title="One-time question about helping Winetricks development" + question="Would you like to help winetricks development by letting winetricks report statistics? You can turn reporting off at any time with the command 'winetricks --optout'" + thanks="Thanks! You won't be asked this question again. Remember, you can turn reporting off at any time with the command 'winetricks --optout'" + declined="OK, winetricks will *not* report statistics. You won't be asked this question again." + ;; + esac + if ${WINETRICKS_GUI} --question --text "${question}" --title "${title}"; then + ${WINETRICKS_GUI} --info --text "${thanks}" + WINETRICKS_STATS_REPORT=1 + else + ${WINETRICKS_GUI} --info --text "${declined}" + WINETRICKS_STATS_REPORT=0 + fi + winetricks_stats_save + ;; + esac + fi +} + +# Retrieve a short string with the operating system name and version +winetricks_os_description() +{ + ( + case "${W_PLATFORM}" in + windows_cmd) echo "windows" ;; + *) echo "${WINETRICKS_WINE_VERSION}" ;; + esac + ) | tr '\012' ' ' +} + +winetricks_stats_report() +{ + winetricks_download_setup + + # If user has opted in to usage tracking, report what he used (if anything) + case "${WINETRICKS_STATS_REPORT}" in + 1) ;; + *) return;; + esac + + BREADCRUMBS_FILE="${WINETRICKS_WORKDIR}"/breadcrumbs + if test -f "${BREADCRUMBS_FILE}"; then + WINETRICKS_STATS_BREADCRUMBS=$(tr '\012' ' ' < "${BREADCRUMBS_FILE}") + echo "You opted in, so reporting '${WINETRICKS_STATS_BREADCRUMBS}' to the winetricks maintainer so he knows which winetricks verbs get used and which don't. Use --optout to disable future reports." + + report="os=$(winetricks_os_description)&winetricks=${WINETRICKS_VERSION}&breadcrumbs=${WINETRICKS_STATS_BREADCRUMBS}" + report="$(echo "${report}" | sed 's/ /%20/g')" + + # Just do a HEAD request with the raw command line. + # Yes, this can be fooled by caches. That's ok. + + # Note: these downloads are expected to fail (the resource won't exist), so don't use w_try and use '|| true' to ignore the expected errors + if [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then + ${torify} wget --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --tries "${WINETRICKS_DOWNLOADER_RETRIES}" \ + --spider "http://kegel.com/data/winetricks-usage?${report}" > /dev/null 2>&1 || true + elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then + ${torify} curl --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --retry "${WINETRICKS_DOWNLOADER_RETRIES}" \ + -I "http://kegel.com/data/winetricks-usage?${report}" > /dev/null 2>&1 || true + elif [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then + ${torify} aria2c \ + ${aria2c_torify_opts:+"${aria2c_torify_opts}"} \ + --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \ + --daemon=false \ + --enable-rpc=false \ + --input-file='' \ + --max-tries="${WINETRICKS_DOWNLOADER_RETRIES}" \ + --save-session='' \ + "http://kegel.com/data/winetricks-usage?${report}" > /dev/null 2>&1 || true + else + w_die "Here be dragons" + fi + fi +} + +winetricks_stats_log_command() +{ + # log what we execute for possible later statistics reporting + echo "$*" >> "${WINETRICKS_WORKDIR}"/breadcrumbs + + # and for the user's own reference later, when figuring out what he did + case "${W_PLATFORM}" in + windows_cmd) _W_LOGDIR="${W_WINDIR_UNIX}"/Temp ;; + *) _W_LOGDIR="${WINEPREFIX}" ;; + esac + + mkdir -p "${_W_LOGDIR}" + echo "$*" >> "${_W_LOGDIR}"/winetricks.log + unset _W_LOGDIR +} + +# Launch a new terminal window if in GUI, or +# spawn a shell in the current window if command line. +# New shell contains proper WINEPREFIX and WINE environment variables. +# May be useful when debugging verbs. +winetricks_shell() +{ + ( + w_try_cd "${W_DRIVE_C}" + export WINE + + case ${WINETRICKS_GUI} in + none) + ${SHELL} + ;; + *) + for term in gnome-terminal konsole Terminal xterm; do + if test "$(command -v ${term} 2>/dev/null)"; then + ${term} + break + fi + done + ;; + esac + ) +} + +# Usage: execute_command verb[=argument] +execute_command() +{ + case "$1" in + *=*) arg=$(echo "$1" | sed 's/.*=//'); cmd=$(echo "$1" | sed 's/=.*//');; + *) cmd="$1"; arg="" ;; + esac + + case "$1" in + # FIXME: avoid duplicated code + apps|benchmarks|dlls|fonts|games|prefix|settings) + WINETRICKS_CURMENU="$1" + ;; + + # Late options + -*) + if ! winetricks_handle_option "$1"; then + winetricks_usage + exit 1 + fi + ;; + + # Hard-coded verbs + main) WINETRICKS_CURMENU=main ;; + help) w_open_webpage https://github.com/Winetricks/winetricks/wiki ;; + list) winetricks_list_all ;; + list-cached) winetricks_list_cached ;; + list-download) winetricks_list_download ;; + list-manual-download) winetricks_list_manual_download ;; + list-installed) winetricks_list_installed ;; + list-all) + old_menu="${WINETRICKS_CURMENU}" + for WINETRICKS_CURMENU in apps benchmarks dlls fonts games prefix settings; do + echo "===== ${WINETRICKS_CURMENU} =====" + winetricks_list_all + done + WINETRICKS_CURMENU="${old_menu}" + ;; + unattended) winetricks_set_unattended 1 ;; + attended) winetricks_set_unattended 0 ;; + arch=*) winetricks_set_winearch "${arg}" ;; + prefix=*) winetricks_set_wineprefix "${arg}" ;; + annihilate) winetricks_annihilate_wineprefix ;; + folder) w_open_folder "${WINEPREFIX}" ;; + winecfg) "${WINE}" winecfg ;; + regedit) "${WINE}" regedit ;; + taskmgr) "${WINE}" taskmgr & ;; + explorer) "${WINE}" explorer & ;; + uninstaller) "${WINE}" uninstaller ;; + shell) winetricks_shell ;; + + # These have to come before *=disabled to avoid looking like DLLs + cfc=disable*) w_call cfc=disabled ;; + fontsmooth=disable*) w_call fontsmooth=disable ;; + mwo=disable*) w_call mwo=disable ;; # FIXME: relax matching so we can handle these spelling differences in verb instead of here + rtlm=disable*) w_call rtlm=disabled ;; + sound=disable*) w_call sound=disabled ;; + ssm=disable*) w_call ssm=disabled ;; + + # Hacks for backwards compatibility + # 2017/03/22: add deprecation notices + cc580) w_warn "Calling cc580 is deprecated, please use comctl32 instead" ; w_call comctl32 ;; + comdlg32.ocx) w_warn "Calling comdlg32.ocx is deprecated, please use comdlg32ocx instead" ; w_call comdlg32ocx ;; + dotnet1) w_warn "Calling dotnet1 is deprecated, please use dotnet11 instead" ; w_call dotnet11 ;; + dotnet2) w_warn "Calling dotnet2 is deprecated, please use dotnet20 instead" ; w_call dotnet20 ;; + ddr=gdi) w_warn "Calling ddr=gdi is deprecated, please use renderer=gdi or renderer=no3d instead" ; w_call renderer=gdi ;; + ddr=opengl) w_warn "Calling ddr=opengl is deprecated, please use renderer=gl instead" ; w_call renderer=gl ;; + dxvk054|dxvk54) w_warn "Calling $1 is deprecated, please use dxvk0054 instead" ; w_call dxvk0054 ;; + dxvk060|dxvk60) w_warn "Calling $1 is deprecated, please use dxvk0060 instead" ; w_call dxvk0060 ;; + dxvk061|dxvk61) w_warn "Calling $1 is deprecated, please use dxvk0061 instead" ; w_call dxvk0061 ;; + dxvk062|dxvk62) w_warn "Calling $1 is deprecated, please use dxvk0062 instead" ; w_call dxvk0062 ;; + dxvk063|dxvk63) w_warn "Calling $1 is deprecated, please use dxvk0063 instead" ; w_call dxvk0063 ;; + dxvk064|dxvk64) w_warn "Calling $1 is deprecated, please use dxvk0064 instead" ; w_call dxvk0064 ;; + dxvk065|dxvk65) w_warn "Calling $1 is deprecated, please use dxvk0065 instead" ; w_call dxvk0065 ;; + dxvk070|dxvk70) w_warn "Calling $1 is deprecated, please use dxvk0070 instead" ; w_call dxvk0070 ;; + dxvk071|dxvk71) w_warn "Calling $1 is deprecated, please use dxvk0071 instead" ; w_call dxvk0071 ;; + dxvk072|dxvk72) w_warn "Calling $1 is deprecated, please use dxvk0072 instead" ; w_call dxvk0072 ;; + dxvk080|dxvk80) w_warn "Calling $1 is deprecated, please use dxvk0080 instead" ; w_call dxvk0080 ;; + dxvk081|dxvk81) w_warn "Calling $1 is deprecated, please use dxvk0081 instead" ; w_call dxvk0081 ;; + dxvk090|dxvk90) w_warn "Calling $1 is deprecated, please use dxvk0090 instead" ; w_call dxvk0090 ;; + dxvk091|dxvk91) w_warn "Calling $1 is deprecated, please use dxvk0091 instead" ; w_call dxvk0091 ;; + dxvk092|dxvk92) w_warn "Calling $1 is deprecated, please use dxvk0092 instead" ; w_call dxvk0092 ;; + dxvk093|dxvk93) w_warn "Calling $1 is deprecated, please use dxvk0093 instead" ; w_call dxvk0093 ;; + dxvk094|dxvk94) w_warn "Calling $1 is deprecated, please use dxvk0094 instead" ; w_call dxvk0094 ;; + dxvk095|dxvk95) w_warn "Calling $1 is deprecated, please use dxvk0095 instead" ; w_call dxvk0095 ;; + dxvk096|dxvk96) w_warn "Calling $1 is deprecated, please use dxvk0096 instead" ; w_call dxvk0096 ;; + dxvk100) w_warn "Calling dxvk100 is deprecated, please use dxvk1000 instead" ; w_call dxvk1000 ;; + dxvk101) w_warn "Calling dxvk101 is deprecated, please use dxvk1001 instead" ; w_call dxvk1001 ;; + dxvk102) w_warn "Calling dxvk102 is deprecated, please use dxvk1002 instead" ; w_call dxvk1002 ;; + dxvk103) w_warn "Calling dxvk103 is deprecated, please use dxvk1003 instead" ; w_call dxvk1003 ;; + dxvk111) w_warn "Calling dxvk111 is deprecated, please use dxvk1011 instead" ; w_call dxvk1011 ;; + dxvk120) w_warn "Calling dxvk120 is deprecated, please use dxvk1020 instead" ; w_call dxvk1020 ;; + dxvk121) w_warn "Calling dxvk121 is deprecated, please use dxvk1021 instead" ; w_call dxvk1021 ;; + dxvk122) w_warn "Calling dxvk122 is deprecated, please use dxvk1022 instead" ; w_call dxvk1022 ;; + dxvk123) w_warn "Calling dxvk123 is deprecated, please use dxvk1023 instead" ; w_call dxvk1023 ;; + dxvk130) w_warn "Calling dxvk130 is deprecated, please use dxvk1030 instead" ; w_call dxvk1030 ;; + dxvk131) w_warn "Calling dxvk131 is deprecated, please use dxvk1031 instead" ; w_call dxvk1031 ;; + dxvk132) w_warn "Calling dxvk132 is deprecated, please use dxvk1032 instead" ; w_call dxvk1032 ;; + dxvk133) w_warn "Calling dxvk133 is deprecated, please use dxvk1033 instead" ; w_call dxvk1033 ;; + dxvk134) w_warn "Calling dxvk134 is deprecated, please use dxvk1034 instead" ; w_call dxvk1034 ;; + dxvk140) w_warn "Calling dxvk140 is deprecated, please use dxvk1040 instead" ; w_call dxvk1040 ;; + dxvk141) w_warn "Calling dxvk141 is deprecated, please use dxvk1041 instead" ; w_call dxvk1041 ;; + dxvk142) w_warn "Calling dxvk142 is deprecated, please use dxvk1042 instead" ; w_call dxvk1042 ;; + dxvk143) w_warn "Calling dxvk143 is deprecated, please use dxvk1043 instead" ; w_call dxvk1043 ;; + dxvk144) w_warn "Calling dxvk144 is deprecated, please use dxvk1044 instead" ; w_call dxvk1044 ;; + dxvk145) w_warn "Calling dxvk145 is deprecated, please use dxvk1045 instead" ; w_call dxvk1045 ;; + dxvk146) w_warn "Calling dxvk146 is deprecated, please use dxvk1046 instead" ; w_call dxvk1046 ;; + dxvk150) w_warn "Calling dxvk150 is deprecated, please use dxvk1050 instead" ; w_call dxvk1050 ;; + dxvk151) w_warn "Calling dxvk151 is deprecated, please use dxvk1051 instead" ; w_call dxvk1051 ;; + dxvk152) w_warn "Calling dxvk152 is deprecated, please use dxvk1052 instead" ; w_call dxvk1052 ;; + dxvk153) w_warn "Calling dxvk153 is deprecated, please use dxvk1053 instead" ; w_call dxvk1053 ;; + dxvk154) w_warn "Calling dxvk154 is deprecated, please use dxvk1054 instead" ; w_call dxvk1054 ;; + dxvk155) w_warn "Calling dxvk155 is deprecated, please use dxvk1055 instead" ; w_call dxvk1055 ;; + dxvk160) w_warn "Calling dxvk160 is deprecated, please use dxvk1060 instead" ; w_call dxvk1060 ;; + dxvk161) w_warn "Calling dxvk161 is deprecated, please use dxvk1061 instead" ; w_call dxvk1061 ;; + dxvk170) w_warn "Calling dxvk170 is deprecated, please use dxvk1070 instead" ; w_call dxvk1070 ;; + dxvk171) w_warn "Calling dxvk171 is deprecated, please use dxvk1071 instead" ; w_call dxvk1071 ;; + dxvk172) w_warn "Calling dxvk172 is deprecated, please use dxvk1072 instead" ; w_call dxvk1072 ;; + dxvk173) w_warn "Calling dxvk173 is deprecated, please use dxvk1073 instead" ; w_call dxvk1073 ;; + dxvk180) w_warn "Calling dxvk180 is deprecated, please use dxvk1080 instead" ; w_call dxvk1080 ;; + dxvk181) w_warn "Calling dxvk181 is deprecated, please use dxvk1081 instead" ; w_call dxvk1081 ;; + dxvk190) w_warn "Calling dxvk190 is deprecated, please use dxvk1090 instead" ; w_call dxvk1090 ;; + dxvk191) w_warn "Calling dxvk191 is deprecated, please use dxvk1091 instead" ; w_call dxvk1091 ;; + dxvk192) w_warn "Calling dxvk192 is deprecated, please use dxvk1092 instead" ; w_call dxvk1092 ;; + dxvk193) w_warn "Calling dxvk193 is deprecated, please use dxvk1093 instead" ; w_call dxvk1093 ;; + dxvk194) w_warn "Calling dxvk194 is deprecated, please use dxvk1094 instead" ; w_call dxvk1094 ;; + + # art2kmin also comes with fm20.dll + fm20) w_warn "Calling fm20 is deprecated, please use controlpad instead" ; w_call controlpad ;; + fontsmooth-bgr) w_warn "Calling fontsmooth-bgr is deprecated, please use fontsmooth=bgr instead" ; w_call fontsmooth=bgr ;; + fontsmooth-disable) w_warn "Calling fontsmooth-disable is deprecated, please use fontsmooth=disable instead" ; w_call fontsmooth=disable ;; + fontsmooth-gray) w_warn "Calling fontsmooth-gray is deprecated, please use fontsmooth=gray instead" ; w_call fontsmooth=gray ;; + fontsmooth-rgb) w_warn "Calling fontsmooth-rgb is deprecated, please use fontsmooth=rgb instead" ; w_call fontsmooth=rgb ;; + glsl=enabled) w_warn "Calling glsl=enabled is deprecated, please use shader_backend=glsl instead" ; w_call shader_backend=glsl ;; + glsl=disabled) w_warn "Calling glsl=disabled is deprecated, please use shader_backend=arb instead" ; w_call shader_backend=arb ;; + glsl-disable) w_warn "Calling glsl-disable is deprecated, please use glsl=disabled instead" ; w_call glsl=disabled ;; + glsl-enable) w_warn "Calling glsl-enable is deprecated, please use glsl=enabled instead" ; w_call glsl=enabled ;; + ie6_full) w_warn "Calling ie6_full is deprecated, please use ie6 instead" ; w_call ie6 ;; + # FIXME: use wsh57 instead? + jscript) w_warn "Calling jscript is deprecated, please use wsh57 instead" ; w_call wsh57 ;; + npm-repack) w_warn "Calling npm-repack is deprecated, please use npm=repack instead" ; w_call npm=repack ;; + oss) w_warn "Calling oss is deprecated, please use sound=oss instead" ; w_call sound=oss ;; + psdkwin7) w_warn "psdkwin7 has been removed, use psdkwin71 instead"; w_call psdkwin71 ;; + python) w_warn "Calling python is deprecated, please use python26 instead" ; w_call python26 ;; + strictdrawordering=enabled) w_warn "Calling strictdrawordering=enabled is deprecated, please use csmt=enabled instead" ; w_call csmt=enabled ;; + strictdrawordering=disabled) w_warn "Calling strictdrawordering=disabled is deprecated, please use csmt=disabled instead" ; w_call csmt=disabled ;; + vbrun60) w_warn "Calling vbrun60 is deprecated, please use vb6run instead" ; w_call vb6run ;; + vcrun2005sp1) w_warn "Calling vcrun2005sp1 is deprecated, please use vcrun2005 instead" ; w_call vcrun2005 ;; + vcrun2008sp1) w_warn "Calling vcrun2008sp1 is deprecated, please use vcrun2008 instead" ; w_call vcrun2008 ;; + wsh56|wsh56js|wsh56vb) w_warn "Calling wsh56 is deprecated, please use wsh57 instead" ; w_call wsh57 ;; + # See https://github.com/Winetricks/winetricks/issues/747 + xact_jun2010) w_warn "Calling xact_jun2010 is deprecated, please use xact instead" ; w_call xact ;; + xlive) w_warn "Calling xlive is deprecated, please use gfw instead" ; w_call gfw ;; + + # Use winecfg if you want a GUI for plain old DLL overrides + alldlls=*) w_call "$1" ;; + *=native) w_do_call native "${cmd}";; + *=builtin) w_do_call builtin "${cmd}";; + *=default) w_do_call default "${cmd}";; + *=disabled) w_do_call disabled "${cmd}";; + vd=*) w_do_call "${cmd}";; + + # Normal verbs, with metadata and load_ functions + *) + if winetricks_metadata_exists "$1"; then + w_call "$1" + else + echo "Unknown arg $1" + winetricks_usage + exit 1 + fi + ;; + esac +} + +if ! test "${WINETRICKS_LIB}"; then + # If user opted out, save that preference now. + winetricks_stats_save + + # If user specifies menu on command line, execute that command, but don't commit to command-line mode + # FIXME: this code is duplicated several times; unify it + if echo "${WINETRICKS_CATEGORIES}" | grep -w "$1" > /dev/null; then + WINETRICKS_CURMENU=$1 + shift + fi + + case "$1" in + die) w_die "we who are about to die salute you." ;; + volnameof=*) + # Debug code. Remove later? + # Since Linux's volname command can't handle DVDs, winetricks has its own, + # implemented using dd, old gum, and some string I had laying around. + # You can try it like this: + # winetricks volnameof=/dev/sr0 + # or + # winetricks volnameof=foo.iso + # This will read the volname from the given image and put it to stdout. + winetricks_volname "${1#volnameof=}" + ;; + "") + if [ -z "${DISPLAY}" ]; then + if [ "$(uname -s)" = "Darwin" ]; then + echo "Running on OSX, but DISPLAY is not set...probably using Mac Driver." + else + echo "DISPLAY not set, not defaulting to gui" + winetricks_usage + exit 0 + fi + fi + + # GUI case + # No non-option arguments given, so read them from GUI, and loop until user quits + if [ ${WINETRICKS_GUI} = "none" ]; then + winetricks_detect_gui + fi + winetricks_detect_sudo + test -z "${WINETRICKS_ISO_MOUNT}" && winetricks_detect_iso_mount + while true; do + case ${WINETRICKS_CURMENU} in + main) verbs=$(winetricks_mainmenu) ;; + prefix) + verbs=$(winetricks_prefixmenu); + # Cheezy hack: choosing 'attended' or 'unattended' leaves you in same menu + case "${verbs}" in + attended) winetricks_set_unattended 0 ; continue;; + unattended) winetricks_set_unattended 1 ; continue;; + esac + ;; + mkprefix) verbs=$(winetricks_mkprefixmenu) ;; + settings) verbs=$(winetricks_settings_menu) ;; + *) verbs="$(winetricks_showmenu)" ;; + esac + + if test "${verbs}" = ""; then + # "user didn't pick anything, back up a level in the menu" + case "${WINETRICKS_CURMENU}-${WINETRICKS_OPT_SHAREDPREFIX}" in + apps-0|benchmarks-0|games-0|main-*) WINETRICKS_CURMENU=prefix ;; + prefix-*) break ;; + *) WINETRICKS_CURMENU=main ;; + esac + elif echo "${WINETRICKS_CATEGORIES}" | grep -w "${verbs}" > /dev/null; then + WINETRICKS_CURMENU=${verbs} + else + winetricks_stats_init + # Otherwise user picked one or more real verbs. + case "${verbs}" in + prefix=*|arch=*) + # prefix menu is special, it only returns one verb, and the + # verb can contain spaces. If a 32bit wineprefix is created via + # the GUI, this may have an "arch=* " prefix + _W_arch=$(echo "${verbs}" | grep -o 'arch=.*' | cut -d' ' -f1) + _W_prefix=$(echo "${verbs}" | grep -o 'prefix=.*') + _W_prefix_name="${_W_prefix#*=}" + if [ -n "${_W_arch}" ]; then + execute_command "${_W_arch}" + fi + execute_command "${_W_prefix}" + # after picking a prefix, want to land in main. + WINETRICKS_CURMENU=main ;; + *) + for verb in ${verbs}; do + execute_command "${verb}" + done + + case "${WINETRICKS_CURMENU}-${WINETRICKS_OPT_SHAREDPREFIX}" in + prefix-*|apps-0|benchmarks-0|games-0) + # After installing isolated app, return to prefix picker + WINETRICKS_CURMENU=prefix + ;; + *) + # Otherwise go to main menu. + WINETRICKS_CURMENU=main + ;; + esac + ;; + esac + fi + done + ;; + *) + winetricks_stats_init + # Command-line case + winetricks_detect_sudo + test -z "${WINETRICKS_ISO_MOUNT}" && winetricks_detect_iso_mount + # User gave command-line arguments, so just run those verbs and exit + for verb; do + case ${verb} in + *.verb) + # Load the verb file + # shellcheck disable=SC1090 + case ${verb} in + */*) . "${verb}" ;; + *) . ./"${verb}" ;; + esac + + # And forget that the verb comes from a file + verb="$(echo "${verb}" | sed 's,.*/,,;s,.verb,,')" + ;; + esac + execute_command "${verb}" + done + ;; + esac + + winetricks_stats_report +fi + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py b/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py new file mode 100644 index 0000000000..0f96db41b4 --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py @@ -0,0 +1,396 @@ +import wmi, sys, winreg, os, subprocess, json, re +from datetime import datetime, timedelta + + +## Define modules +modules=[] + +def print_module(module, print_flag=None): + """Returns module in XML format. Accepts only {dict}.\n + - Only works with one module at a time: otherwise iteration is needed. + - Module "value" field accepts str type or [list] for datalists. + - Use print_flag to show modules' XML in STDOUT. + """ + data = dict(module) + module_xml = ("\n" + "\t\n" + "\t" + str(data["type"]) + "\n" + ) + + if type(data["type"]) is not str and "string" not in data["type"]: #### Strip spaces if module not generic_data_string + data["value"] = data["value"].strip() + if isinstance(data["value"], list): # Checks if value is a list + module_xml += "\t\n" + for value in data["value"]: + if type(value) is dict and "value" in value: + module_xml += "\t\n" + module_xml += "\t\t\n" + if "timestamp" in value: + module_xml += "\t\t\n" + module_xml += "\t\n" + module_xml += "\t\n" + else: + module_xml += "\t\n" + if "desc" in data: + module_xml += "\t\n" + if "unit" in data: + module_xml += "\t\n" + if "interval" in data: + module_xml += "\t\n" + if "tags" in data: + module_xml += "\t" + str(data["tags"]) + "\n" + if "module_group" in data: + module_xml += "\t" + str(data["module_group"]) + "\n" + if "module_parent" in data: + module_xml += "\t" + str(data["module_parent"]) + "\n" + if "min_warning" in data: + module_xml += "\t\n" + if "min_warning_forced" in data: + module_xml += "\t\n" + if "max_warning" in data: + module_xml += "\t\n" + if "max_warning_forced" in data: + module_xml += "\t\n" + if "min_critical" in data: + module_xml += "\t\n" + if "min_critical_forced" in data: + module_xml += "\t\n" + if "max_critical" in data: + module_xml += "\t\n" + if "max_critical_forced" in data: + module_xml += "\t\n" + if "str_warning" in data: + module_xml += "\t\n" + if "str_warning_forced" in data: + module_xml += "\t\n" + if "str_critical" in data: + module_xml += "\t\n" + if "str_critical_forced" in data: + module_xml += "\t\n" + if "critical_inverse" in data: + module_xml += "\t\n" + if "warning_inverse" in data: + module_xml += "\t\n" + if "max" in data: + module_xml += "\t\n" + if "min" in data: + module_xml += "\t\n" + if "post_process" in data: + module_xml += "\t\n" + if "disabled" in data: + module_xml += "\t\n" + if "min_ff_event" in data: + module_xml += "\t\n" + if "status" in data: + module_xml += "\t\n" + if "timestamp" in data: + module_xml += "\t\n" + if "custom_id" in data: + module_xml += "\t\n" + if "critical_instructions" in data: + module_xml += "\t\n" + if "warning_instructions" in data: + module_xml += "\t\n" + if "unknown_instructions" in data: + module_xml += "\t\n" + if "quiet" in data: + module_xml += "\t\n" + if "module_ff_interval" in data: + module_xml += "\t\n" + if "crontab" in data: + module_xml += "\t\n" + if "min_ff_event_normal" in data: + module_xml += "\t\n" + if "min_ff_event_warning" in data: + module_xml += "\t\n" + if "min_ff_event_critical" in data: + module_xml += "\t\n" + if "ff_type" in data: + module_xml += "\t\n" + if "ff_timeout" in data: + module_xml += "\t\n" + if "each_ff" in data: + module_xml += "\t\n" + if "module_parent_unlink" in data: + module_xml += "\t\n" + if "global_alerts" in data: + for alert in data["alert"]: + module_xml += "\t\n" + module_xml += "\n" + + if print_flag: + print (module_xml) + + return (module_xml) + +def check_antivirus_status(): + try: + wmi_obj = wmi.WMI(namespace="root/SecurityCenter2") + antivirus_products = wmi_obj.query("SELECT * FROM AntivirusProduct") + + for product in antivirus_products: + display_name = product.displayName + product_state = product.productState + product_state_hex = hex(product_state) + last_update = product.timestamp + atv_status = int(product_state_hex[3:5]) + atv_uptodate = int(product_state_hex[5:7]) + atv_status = 1 if atv_status in [10, 11] else 0 + atv_uptodate = 1 if atv_uptodate in [00,] else 0 + + #print(f"{display_name}, product_state: {product_state}, product_state_hex: {product_state_hex}, last_update: {last_update}, status: {atv_status}, uptodate: {atv_uptodate}") + modules.append({ + "name" : f"{display_name} Antivirus status", + "type" : "generic_proc", + "value": atv_status, + "desc" : f"{display_name} state: {product_state}, last update: {last_update}", + }) + modules.append({ + "name" : f"{display_name} Antivirus up to date", + "type" : "generic_proc", + "value": atv_uptodate, + "desc" : f"{display_name} state: {product_state}, last update: {last_update}", + }) + + except Exception as e: + print(f"Error check antivirus: {e}", file=sys.stderr) + +def is_lock_screen_enabled(): + try: + # Open the registry key + key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" + with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path) as key: + # Query the value of the DisableLockScreen key + value_name = "DisableLockScreen" + value, _ = winreg.QueryValueEx(key, value_name) + + # Check if the lock screen is enabled (0 means enabled) + status = value == 0 + if status == False: return status + + except FileNotFoundError: + # If the registry key or value is not found, consider it as enabled + status = True + except Exception as e: + print(f"Error check lockscreen: {e}", file=sys.stderr) + status = False + + try: + # Define the registry key for the lock screen settings + reg_key_path = r"SOFTWARE\Policies\Microsoft\Windows\Personalization" + reg_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_key_path) + + # Query the "NoLockScreen" DWORD value + value_name = "NoLockScreen" + value, _ = winreg.QueryValueEx(reg_key, value_name) + + # Check if the "NoLockScreen" value is 0 (enabled) + status = value == 0 + if status == False: return status + + except FileNotFoundError: + # If the registry key or value is not found, consider it as enabled + status = True + except Exception as e: + print(f"Error check lockscreen: {e}", file=sys.stderr) + status = False + + return status + +def check_locksreen_enables(): + status = is_lock_screen_enabled() + value = 1 if status == True else 0 + + modules.append({ + "name" : "Lockscreen status", + "type" : "generic_proc", + "value": value, + "desc" : f"Check lockscreen enable", + }) + +def convert_to_human_readable_date(timestamp_str): + try: + # Parse the timestamp string without the time zone + timestamp = datetime.strptime(timestamp_str, '%Y%m%d%H%M%S') + + # Convert to a human-readable format + human_readable_date = timestamp.strftime('%Y-%m-%d %H:%M:%S %z') + + return human_readable_date.strip() + except Exception as e: + print(f"Error converting date: {e}", file=sys.stderr) + return None + +def check_time_difference(timestamp, timedays=10): + try: + # Convert the timestamp string to a datetime object + given_timestamp = datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S') + + # Get the current time + current_time = datetime.now() + + #Calculate the time difference + time_difference = current_time - given_timestamp + + # Check if the time difference is greater than one hour + if time_difference < timedelta(days=timedays): + return "1" + else: + return "0" + except Exception as e: + print(f"Error check time difference: {e}", file=sys.stderr) + return 0 + + + +def get_windows_update_info(limit=5): + try: + # Connect to the Win32_ReliabilityRecords class in the root/cimv2 namespace + wmi_conn = wmi.WMI() + + # Query the Win32_ReliabilityRecords class for Windows Update information + query = "SELECT * FROM Win32_ReliabilityRecords WHERE sourcename = 'Microsoft-Windows-WindowsUpdateClient'" + result = wmi_conn.query(query) + + # Extract relevant information and format output + update_info = [ + { + "date": convert_to_human_readable_date(record.timegenerated.split('.')[0]), + "update": record.message + } + for record in result[:limit] + ] + + last_update_date=update_info[0]['date'] + value=check_time_difference(last_update_date) + + modules.append({ + "name" : "Microsoft Update system status", + "type" : "generic_proc", + "value": value, + "desc" : f"Check if system was updated in the last 10 days. last update: {last_update_date}", + }) + return True + except Exception as e: + print(f"Error windows update check: {e}", file=sys.stderr) + return False + +def is_firewall_enabled(): + try: + # Run PowerShell command to check if the Windows Firewall is enabled + result = subprocess.run( + ['powershell', 'Get-NetFirewallProfile |Select-Object profile, enabled | ConvertTo-Json'], + capture_output=True, + text=True + ) + + result_json= json.loads(result.stdout) + for profile in result_json: + modules.append({ + "name" : f"Firewall profile: {profile['Profile']} status", + "type" : "generic_proc", + "value": profile["Enabled"], + "desc" : f"Check if firewall profile {profile['Profile']} is enabled", + }) + return True + except Exception as e: + print(f"Error firewall check: {e}", file=sys.stderr) + return False + +def check_password_enforcement(): + enforce_pass = 1 + counter = 0 + try: + # Connect to the WMI service + wmi_service = wmi.WMI() + + # Query for user accounts + users = wmi_service.Win32_UserAccount() + + # Check if each user enforces password + for user in users: + # username = user.Name + # password_required = user.PasswordRequired + if user.PasswordRequired == False : + enforce_pass = 0 + counter += 1 + #print(f"User: {username}, Password Required: {password_required}") + + modules.append({ + "name" : "All users enforced password", + "type" : "generic_proc", + "value": enforce_pass, + "desc" : f"Check if all users has enforced password, not secure users = {counter}", + }) + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + print("Failed to check password enforcement for users.", file=sys.stderr) + + +def check_login_audit_policy(): + try: + # Run the auditpol command to check the audit policy for Logon/Logoff + cmd_command = "auditpol /get /subcategory:Logon" + result = subprocess.run(cmd_command, shell=True, capture_output=True, text=True, check=True) + last_line = result.stdout.strip().split('\n')[-1] + cleaned_line = re.sub(' +', ' ', last_line) + + # Interpret the result + if "Success and Failure" in result.stdout: + result = 1 + elif "No Auditing" in result.stdout: + result = 0 + else: + print("Unable to determine audit policy for Logon/Logoff events.", file=sys.stderr) + result = 0 + return + modules.append({ + "name" : "Check logon event audited", + "type" : "generic_proc", + "value": result, + "desc" : f"Check if the logon events audit log is enables, status:{cleaned_line}", + }) + + except subprocess.CalledProcessError as e: + print(f"Error: {e}") + print("Failed to check audit policy using auditpol command.", file=sys.stderr) + return + + +if __name__ == "__main__": + check_antivirus_status() + check_locksreen_enables() + get_windows_update_info() + is_firewall_enabled() + check_password_enforcement() + check_login_audit_policy() + + for module in modules: + print_module(module, True) + + +# Windows Defender status values: +# 0: No action needed +# 266240: Antivirus is up to date +# 266256: Antivirus is out of date +# 266304: Antivirus is not monitoring +# 393216 (0x60000): No action needed. +# 393232 (0x60010): Antivirus is up to date. +# 393240 (0x60018): Antivirus is out of date. +# 393216 (0x60030): Antivirus is not monitoring. +# 397312 (0x61000): Antivirus is disabled. + +# AVG Internet Security 2012 (from antivirusproduct WMI) +# 262144 (040000) = disabled and up to date +# 266240 (041000) = enabled and up to date +# AVG Internet Security 2012 (from firewallproduct WMI) +# 266256 (041010) = firewall enabled - (last two blocks not relevant it seems for firewall) +# 262160 (040010) = firewall disabled - (last two blocks not relevant it seems for firewall) + +# Windows Defender +# 393472 (060100) = disabled and up to date +# 397584 (061110) = enabled and out of date +# 397568 (061100) = enabled and up to date +# Microsoft Security Essentials +# 397312 (061000) = enabled and up to date +# 393216 (060000) = disabled and up to date diff --git a/pandora_agents/plugins/windows/pandora_security_win/src/requirements.txt b/pandora_agents/plugins/windows/pandora_security_win/src/requirements.txt new file mode 100644 index 0000000000..ebc010c452 --- /dev/null +++ b/pandora_agents/plugins/windows/pandora_security_win/src/requirements.txt @@ -0,0 +1 @@ +WMI==1.5.1 \ No newline at end of file diff --git a/pandora_agents/win32/bin/pandora_agent.conf b/pandora_agents/win32/bin/pandora_agent.conf index c0a1560b38..4e77e220c5 100644 --- a/pandora_agents/win32/bin/pandora_agent.conf +++ b/pandora_agents/win32/bin/pandora_agent.conf @@ -538,3 +538,8 @@ module_plugin "%PROGRAMFILES%\Pandora_Agent\util\autodiscover.exe" --default #module_regexp C:\server\logs\xserver.log #module_pattern .* #module_end + +# Pandora basic security check plugin for windows. +#module_begin +#module_plugin "%PROGRAMFILES%\Pandora_Agent\util\pandora_security_win.exe" +#module_end diff --git a/pandora_agents/win32/bin/util/pandora_security_win.exe b/pandora_agents/win32/bin/util/pandora_security_win.exe new file mode 100755 index 0000000000..eab7b2bb08 --- /dev/null +++ b/pandora_agents/win32/bin/util/pandora_security_win.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e847614a6e013999949ae465e0a29df2922e858664d253f89f58540f0e27e320 +size 7829206 From f01160915d692a4ae6b0917493e728a92f376c0e Mon Sep 17 00:00:00 2001 From: rafael Date: Wed, 13 Dec 2023 12:20:39 +0100 Subject: [PATCH 146/157] 12531 adding support for logon spanish --- .../pandora_security_win/src/pandora_security_win.py | 12 +++++++++++- .../win32/bin/util/pandora_security_win.exe | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py b/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py index 0f96db41b4..d9ac15f978 100644 --- a/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py +++ b/pandora_agents/plugins/windows/pandora_security_win/src/pandora_security_win.py @@ -143,12 +143,14 @@ def check_antivirus_status(): "name" : f"{display_name} Antivirus status", "type" : "generic_proc", "value": atv_status, + "module_group": "security", "desc" : f"{display_name} state: {product_state}, last update: {last_update}", }) modules.append({ "name" : f"{display_name} Antivirus up to date", "type" : "generic_proc", "value": atv_uptodate, + "module_group": "security", "desc" : f"{display_name} state: {product_state}, last update: {last_update}", }) @@ -205,6 +207,7 @@ def check_locksreen_enables(): "name" : "Lockscreen status", "type" : "generic_proc", "value": value, + "module_group": "security", "desc" : f"Check lockscreen enable", }) @@ -268,6 +271,7 @@ def get_windows_update_info(limit=5): "name" : "Microsoft Update system status", "type" : "generic_proc", "value": value, + "module_group": "security", "desc" : f"Check if system was updated in the last 10 days. last update: {last_update_date}", }) return True @@ -290,6 +294,7 @@ def is_firewall_enabled(): "name" : f"Firewall profile: {profile['Profile']} status", "type" : "generic_proc", "value": profile["Enabled"], + "module_group": "security", "desc" : f"Check if firewall profile {profile['Profile']} is enabled", }) return True @@ -320,6 +325,7 @@ def check_password_enforcement(): "name" : "All users enforced password", "type" : "generic_proc", "value": enforce_pass, + "module_group": "security", "desc" : f"Check if all users has enforced password, not secure users = {counter}", }) except Exception as e: @@ -338,16 +344,20 @@ def check_login_audit_policy(): # Interpret the result if "Success and Failure" in result.stdout: result = 1 + elif "Aciertos y errores" in result.stdout: + result = 1 elif "No Auditing" in result.stdout: result = 0 + elif "Sin auditoría" in result.stdout: + result = 0 else: print("Unable to determine audit policy for Logon/Logoff events.", file=sys.stderr) result = 0 - return modules.append({ "name" : "Check logon event audited", "type" : "generic_proc", "value": result, + "module_group": "security", "desc" : f"Check if the logon events audit log is enables, status:{cleaned_line}", }) diff --git a/pandora_agents/win32/bin/util/pandora_security_win.exe b/pandora_agents/win32/bin/util/pandora_security_win.exe index eab7b2bb08..a21f40faf6 100755 --- a/pandora_agents/win32/bin/util/pandora_security_win.exe +++ b/pandora_agents/win32/bin/util/pandora_security_win.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e847614a6e013999949ae465e0a29df2922e858664d253f89f58540f0e27e320 -size 7829206 +oid sha256:c58891fbd16bf80f288e0ff4751801aa02dbf4e6c914625b4d49a364c7e0b511 +size 7829249 From fed0d92805f0dc73e064aac9b84468bb9d77d3b3 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Wed, 13 Dec 2023 19:53:14 +0100 Subject: [PATCH 147/157] #12566 fixed colums module_custom_id and event_custom_id length_ --- pandora_console/include/styles/events.css | 8 ++++ pandora_console/operation/events/events.php | 41 ++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/styles/events.css b/pandora_console/include/styles/events.css index 24d64ce05d..78286c79f9 100644 --- a/pandora_console/include/styles/events.css +++ b/pandora_console/include/styles/events.css @@ -116,6 +116,14 @@ td > input[id^="checkbox-multi"] { line-height: 2em; } +.info_table.events tr > td span:not(.invisible) { + display: block; + overflow: hidden; + text-overflow: ellipsis; + max-height: 6em; + line-height: 1.5em; +} + th.column-estado { padding: 0px 0px 0px 12px !important; max-width: fit-content; diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index eaf3066e4d..66a33e6a0e 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -547,6 +547,45 @@ if (is_ajax() === true) { ); } + if (empty($tmp->tags) === false) { + $tmp->tags = ui_print_truncate_text( + $tmp->tags, + 30, + false, + true, + false, + '…', + true, + true, + ); + } + + if (empty($tmp->event_custom_id) === false) { + $tmp->event_custom_id = ui_print_truncate_text( + $tmp->event_custom_id, + 30, + false, + true, + false, + '…', + true, + true, + ); + } + + if (empty($tmp->module_custom_id) === false) { + $tmp->module_custom_id = ui_print_truncate_text( + $tmp->module_custom_id, + 30, + false, + true, + false, + '…', + true, + true, + ); + } + if (empty($tmp->comments) === false) { $tmp->comments = ui_print_comments($tmp->comments, 20); } @@ -2614,7 +2653,7 @@ try { [ [ 'text' => 'options', - 'class' => 'table_action_buttons mw120px', + 'class' => 'table_action_buttons mw100px', ], [ 'text' => 'm', From dffdbff8b152c42f7eee7e09adbc33ab0b3a19d1 Mon Sep 17 00:00:00 2001 From: artica Date: Thu, 14 Dec 2023 01:00:28 +0100 Subject: [PATCH 148/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index f8b810d817..aa4a2d744c 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231213 +Version: 7.0NG.774-231214 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index fe934f5bb2..5230283cd9 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231213" +pandora_version="7.0NG.774-231214" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 263b12b006..eea0bef2e7 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231213'; +use constant AGENT_BUILD => '231214'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index c8b79b5432..77dd456483 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231213 +%define release 231214 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index e15c66a2b0..d6170ca2e8 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231213 +%define release 231214 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index c8b9c5bab9..81de81c240 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231213 +%define release 231214 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 54311de34a..7e3809eec3 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231213 +%define release 231214 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index bfeb6b46be..6babe4a929 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231213 +%define release 231214 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index ccd8e1bbe9..6635b0c2e4 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231213" +PI_BUILD="231214" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index af055f92d2..2849d5842a 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231213} +{231214} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 0c717e94de..d5c47e9441 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231213") +#define PANDORA_VERSION ("7.0NG.774 Build 231214") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index d0c4b12420..a7398b0f13 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231213))" + VALUE "ProductVersion", "(7.0NG.774(Build 231214))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 3db8b82868..03471ff471 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231213 +Version: 7.0NG.774-231214 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index ed5bacf153..92a964b48a 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231213" +pandora_version="7.0NG.774-231214" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index a06a174ade..9ad1aa52da 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231213'; +$build_version = 'PC231214'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 91de00f8a8..1864d06ed2 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 3d44ddc426..08a0661437 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231213 +%define release 231214 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 0bad40c2b6..cee1e6c579 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231213 +%define release 231214 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 8dcdf85db0..aed560fe90 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231213" +PI_BUILD="231214" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 0b74326632..c08803df7c 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231213"; +my $version = "7.0NG.774 Build 231214"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index afcf8b9199..02a9532ce0 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231213"; +my $version = "7.0NG.774 Build 231214"; # save program name for logging my $progname = basename($0); From 036425dddab54e7170b3f962cae6b01faf3d7a2f Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 14 Dec 2023 11:40:26 +0100 Subject: [PATCH 149/157] Fix opensearch total documents automonitorization --- .../include/lib/TacticalView/elements/LogStorage.php | 2 +- pandora_console/views/tacticalView/view.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/lib/TacticalView/elements/LogStorage.php b/pandora_console/include/lib/TacticalView/elements/LogStorage.php index 427b3c93c6..6ff1276394 100644 --- a/pandora_console/include/lib/TacticalView/elements/LogStorage.php +++ b/pandora_console/include/lib/TacticalView/elements/LogStorage.php @@ -170,7 +170,7 @@ class LogStorage extends Element public function getStoredData():string { if ($this->isEnabled() === true) { - $data = $this->valueMonitoring('Total lines of data'); + $data = $this->valueMonitoring('Total documents'); $value = format_numeric($data[0]['datos']); } else { $value = __('N/A'); diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index 29b1c923fc..ae3eb3cc86 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -193,7 +193,7 @@
getStoredData(); ?> - +
From f78c7495e5c3958b1f20b988e9647adc969f1cf5 Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 14 Dec 2023 13:18:53 +0100 Subject: [PATCH 150/157] fixed modal close click button execute twice function close pandora_enterprise#12447 --- pandora_console/include/javascript/pandora_ui.js | 1 - 1 file changed, 1 deletion(-) diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index 45ca47e92b..0ab678893d 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -583,7 +583,6 @@ function confirmDialog(settings, idDialog = uniqId()) { $(this).dialog("close"); $(this).remove(); } - if (typeof settings.onDeny == "function") settings.onDeny(); } }, { From 4c115958993b7ea6fcaebd9389cc90eb4f952c6a Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 14 Dec 2023 16:48:10 +0100 Subject: [PATCH 151/157] fix name token easter eggs pandora_enterprise#12201 --- pandora_console/godmode/setup/setup_general.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 879bc99b72..bb1617d001 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -765,7 +765,7 @@ $table->data[$i++][] = html_print_label_input_block( ); $table->data[$i][] = html_print_label_input_block( - __('Eastern eggs disabled'), + __('Easter eggs'), html_print_checkbox_switch( 'eastern_eggs_disabled', 1, From 67ffe8627bede2543e66dd9130183b640d1b991c Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Thu, 14 Dec 2023 19:08:34 +0100 Subject: [PATCH 152/157] #12647 fixed line break in event list --- pandora_console/include/styles/events.css | 10 +------- pandora_console/operation/events/events.php | 28 +++++++++++---------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/pandora_console/include/styles/events.css b/pandora_console/include/styles/events.css index 78286c79f9..8bcdd7187f 100644 --- a/pandora_console/include/styles/events.css +++ b/pandora_console/include/styles/events.css @@ -109,21 +109,13 @@ td > input[id^="checkbox-multi"] { } .info_table.events tr > td span:not(.invisible) { - display: block; + display: inline-block; overflow: hidden; text-overflow: ellipsis; max-height: 6em; line-height: 2em; } -.info_table.events tr > td span:not(.invisible) { - display: block; - overflow: hidden; - text-overflow: ellipsis; - max-height: 6em; - line-height: 1.5em; -} - th.column-estado { padding: 0px 0px 0px 12px !important; max-width: fit-content; diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 6d969481a3..4365ff6594 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -523,17 +523,6 @@ if (is_ajax() === true) { $tmp->b64 = base64_encode(json_encode($tmp)); $tmp->evento = $output_event_name; - $tmp->evento = ui_print_truncate_text( - $tmp->evento, - (empty($compact_name_event) === true) ? 'description' : GENERIC_SIZE_TEXT, - false, - true, - false, - '…', - true, - true, - ); - if (empty($tmp->module_name) === false) { $tmp->module_name = ui_print_truncate_text( $tmp->module_name, @@ -771,18 +760,31 @@ if (is_ajax() === true) { $evn = ''; } + $number = ''; // Grouped events. if ((int) $filter['group_rep'] === EVENT_GROUP_REP_EXTRAIDS) { $counter_extra_id = event_get_counter_extraId($item, $filter); if (empty($counter_extra_id) === false && $counter_extra_id > 1) { - $evn .= '('.$counter_extra_id.') '; + $number = '('.$counter_extra_id.') '; } } else { if (isset($tmp->event_rep) === true && $tmp->event_rep > 1) { - $evn .= '('.$tmp->event_rep.') '; + $number = '('.$tmp->event_rep.') '; } } + $tmp->evento = $number.$tmp->evento; + $tmp->evento = ui_print_truncate_text( + $tmp->evento, + (empty($compact_name_event) === true) ? 'description' : GENERIC_SIZE_TEXT, + false, + true, + false, + '…', + true, + true, + ); + $evn .= $tmp->evento.''; // Add event severity format to itself. From d81805d2c2400819d7150578736096ea2607ef17 Mon Sep 17 00:00:00 2001 From: artica Date: Fri, 15 Dec 2023 01:00:29 +0100 Subject: [PATCH 153/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index aa4a2d744c..bbca6968aa 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231214 +Version: 7.0NG.774-231215 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 5230283cd9..c954d505ef 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231214" +pandora_version="7.0NG.774-231215" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index eea0bef2e7..359e76ee0a 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231214'; +use constant AGENT_BUILD => '231215'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 77dd456483..c9549e3c9b 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231214 +%define release 231215 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index d6170ca2e8..0925353598 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231214 +%define release 231215 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index 81de81c240..e1c50546ee 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231214 +%define release 231215 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 7e3809eec3..4e7907ea9d 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231214 +%define release 231215 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 6babe4a929..85ce06d693 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231214 +%define release 231215 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 6635b0c2e4..2001864650 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231214" +PI_BUILD="231215" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 2849d5842a..38d741d818 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231214} +{231215} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index d5c47e9441..d827c111a9 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231214") +#define PANDORA_VERSION ("7.0NG.774 Build 231215") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index a7398b0f13..8eee99167d 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231214))" + VALUE "ProductVersion", "(7.0NG.774(Build 231215))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 03471ff471..6fbf3cd46e 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231214 +Version: 7.0NG.774-231215 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 92a964b48a..c5fbbd0727 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231214" +pandora_version="7.0NG.774-231215" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 9ad1aa52da..1a8f8f6cd9 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231214'; +$build_version = 'PC231215'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 1864d06ed2..6ff3a4eb0b 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 08a0661437..3109a043df 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231214 +%define release 231215 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index cee1e6c579..aab88dca68 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231214 +%define release 231215 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index aed560fe90..b537662939 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231214" +PI_BUILD="231215" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index c08803df7c..42040bba40 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231214"; +my $version = "7.0NG.774 Build 231215"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index b59337f42d..ae0081273f 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231214"; +my $version = "7.0NG.774 Build 231215"; # save program name for logging my $progname = basename($0); From 971db37147cc38a90427a43e535921610fd49a71 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Fri, 15 Dec 2023 10:19:52 +0100 Subject: [PATCH 154/157] #12649 remove trace --- pandora_console/operation/agentes/status_monitor.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index 42b2c9308a..4ceb7681fe 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -1381,8 +1381,6 @@ $sql = 'SELECT ORDER BY '.$order['field'].' '.$order['order'].' LIMIT '.$limit_sql.' OFFSET '.$offset; - hd($sql); - // We do not show the modules until the user searches with the filter. if ($autosearch) { if (is_metaconsole() === false) { From 9037819ceb85d964207d1421df62f980828f6306 Mon Sep 17 00:00:00 2001 From: artica Date: Sat, 16 Dec 2023 01:00:26 +0100 Subject: [PATCH 155/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index bbca6968aa..897450e479 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231215 +Version: 7.0NG.774-231216 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index c954d505ef..fc1f66b2e1 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231215" +pandora_version="7.0NG.774-231216" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 359e76ee0a..fdd57bdc92 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231215'; +use constant AGENT_BUILD => '231216'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index c9549e3c9b..618c192e3e 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231215 +%define release 231216 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index 0925353598..7f1a1f543e 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231215 +%define release 231216 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index e1c50546ee..e99bbf7bfb 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231215 +%define release 231216 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 4e7907ea9d..8eee0c86e8 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231215 +%define release 231216 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 85ce06d693..5e59914098 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231215 +%define release 231216 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 2001864650..947437f05c 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231215" +PI_BUILD="231216" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 38d741d818..b6757e523f 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231215} +{231216} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index d827c111a9..5e9feaf3cc 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231215") +#define PANDORA_VERSION ("7.0NG.774 Build 231216") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 8eee99167d..0bbb978c77 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231215))" + VALUE "ProductVersion", "(7.0NG.774(Build 231216))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 6fbf3cd46e..9c542f626a 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231215 +Version: 7.0NG.774-231216 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index c5fbbd0727..112100559e 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231215" +pandora_version="7.0NG.774-231216" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 1a8f8f6cd9..332bb72283 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231215'; +$build_version = 'PC231216'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 6ff3a4eb0b..47779e35cb 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 3109a043df..ae14cf3951 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231215 +%define release 231216 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index aab88dca68..2466ee97a9 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231215 +%define release 231216 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index b537662939..48e15809b7 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231215" +PI_BUILD="231216" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 42040bba40..31778c01ae 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231215"; +my $version = "7.0NG.774 Build 231216"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index ae0081273f..616b126284 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231215"; +my $version = "7.0NG.774 Build 231216"; # save program name for logging my $progname = basename($0); From 2d379f67006a4924948a9ff6654b17e504f8b3dc Mon Sep 17 00:00:00 2001 From: artica Date: Sun, 17 Dec 2023 01:00:20 +0100 Subject: [PATCH 156/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 897450e479..4ea15349ef 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231216 +Version: 7.0NG.774-231217 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index fc1f66b2e1..e1a4d01a79 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231216" +pandora_version="7.0NG.774-231217" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index fdd57bdc92..b7e382694d 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231216'; +use constant AGENT_BUILD => '231217'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 618c192e3e..2c02ab2fb1 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231216 +%define release 231217 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index 7f1a1f543e..3da11c67ee 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231216 +%define release 231217 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index e99bbf7bfb..224387e493 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231216 +%define release 231217 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 8eee0c86e8..73d3152660 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231216 +%define release 231217 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 5e59914098..7ff6d11db8 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231216 +%define release 231217 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 947437f05c..e1bdafac09 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231216" +PI_BUILD="231217" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index b6757e523f..961f89dfaf 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231216} +{231217} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 5e9feaf3cc..1d04a0cc10 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231216") +#define PANDORA_VERSION ("7.0NG.774 Build 231217") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 0bbb978c77..2b9aa39667 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231216))" + VALUE "ProductVersion", "(7.0NG.774(Build 231217))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 9c542f626a..48f283e61f 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231216 +Version: 7.0NG.774-231217 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 112100559e..e1b25d6b91 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231216" +pandora_version="7.0NG.774-231217" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 332bb72283..363b09cce7 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231216'; +$build_version = 'PC231217'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 47779e35cb..0264480999 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index ae14cf3951..327f2f5d45 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231216 +%define release 231217 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 2466ee97a9..19b9974bbc 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231216 +%define release 231217 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 48e15809b7..15924eca33 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231216" +PI_BUILD="231217" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 31778c01ae..4a8a50c8ca 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231216"; +my $version = "7.0NG.774 Build 231217"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 616b126284..2a517ed9e0 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231216"; +my $version = "7.0NG.774 Build 231217"; # save program name for logging my $progname = basename($0); From 0336f87b24f759c826b3938435a18bd2604c829e Mon Sep 17 00:00:00 2001 From: artica Date: Mon, 18 Dec 2023 01:00:22 +0100 Subject: [PATCH 157/157] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el8.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.el9.spec | 2 +- pandora_agents/unix/pandora_agent.redhat_bin.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 4ea15349ef..be8094b102 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.774-231217 +Version: 7.0NG.774-231218 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index e1a4d01a79..9d6c0e8719 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231217" +pandora_version="7.0NG.774-231218" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index b7e382694d..a98710e073 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1039,7 +1039,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.774'; -use constant AGENT_BUILD => '231217'; +use constant AGENT_BUILD => '231218'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 2c02ab2fb1..b1471d3140 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231217 +%define release 231218 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec index 3da11c67ee..a95fff30d3 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el8.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231217 +%define release 231218 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec index 224387e493..5b94d94fe3 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.el9.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231217 +%define release 231218 %define debug_package %{nil} Summary: Pandora FMS Linux agent, binary version diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index 73d3152660..5c77447573 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231217 +%define release 231218 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 7ff6d11db8..d90a5079b3 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.774 -%define release 231217 +%define release 231218 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index e1bdafac09..477c0449e0 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231217" +PI_BUILD="231218" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 961f89dfaf..889112a68a 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{231217} +{231218} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 1d04a0cc10..14af1b14ff 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.774 Build 231217") +#define PANDORA_VERSION ("7.0NG.774 Build 231218") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 2b9aa39667..d2723120d4 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.774(Build 231217))" + VALUE "ProductVersion", "(7.0NG.774(Build 231218))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 48f283e61f..bd02826e00 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.774-231217 +Version: 7.0NG.774-231218 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index e1b25d6b91..8392569d90 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.774-231217" +pandora_version="7.0NG.774-231218" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 363b09cce7..a204114cde 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC231217'; +$build_version = 'PC231218'; $pandora_version = 'v7.0NG.774'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 0264480999..9a0df5bbbf 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 327f2f5d45..8370a229c1 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -7,7 +7,7 @@ %define debug_package %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231217 +%define release 231218 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 19b9974bbc..d505b3d685 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.774 -%define release 231217 +%define release 231218 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 15924eca33..6a4020f1db 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.774" -PI_BUILD="231217" +PI_BUILD="231218" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 4a8a50c8ca..fec820a29a 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -38,7 +38,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.774 Build 231217"; +my $version = "7.0NG.774 Build 231218"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 2a517ed9e0..3ea6c61070 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.774 Build 231217"; +my $version = "7.0NG.774 Build 231218"; # save program name for logging my $progname = basename($0);