From 367a21eaabbb12cb70af551eb508f36929f3fb28 Mon Sep 17 00:00:00 2001 From: Valko Laszlo Date: Sat, 12 May 2018 05:53:42 +0200 Subject: [PATCH] Refactored default package removal function based on registry key UninstallString. --- pkgtool.pm | 99 +++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/pkgtool.pm b/pkgtool.pm index 87f4a8b..9aacd59 100644 --- a/pkgtool.pm +++ b/pkgtool.pm @@ -1543,14 +1543,61 @@ sub run_exe ($$$$$$$;$) return (undef, undef); } +sub remove_package_fallback ($$$$$$$$$$$) +{ + my ($channel, $vars, $paramlist, $inst, $condition, $dispname, $ver, $printver, $db, $counters, $removecontext) = @_; + + print_log($channel, DEBUG1, 'Removing package %s%s%s', $dispname, $printver, + defined $condition ? ' with true condition' : ''); + + my $uninst = $$inst{Uninstall}; + my $quninst = $$inst{QUninstall}; + return sprintf('Cannot remove package %s%s, no remove steps defined and no UninstallString registry entry found', + $dispname, $ver) unless defined $uninst || defined $quninst; + $uninst = $quninst if defined $quninst; + $uninst =~ s/(msiexec[^ ]* )\/i/$1\/X/io; + $uninst =~ s/(msiexec[^ ]* )/$1\/qb \/norestart \/passive /io; + print_log($channel, DEBUG2, 'Uninstall command: %s', $uninst); + if (! defined $$removecontext{exename}) { + $$removecontext{exename} = substitute_variables($vars, '%systemroot%/System32/cmd.exe', 1, undef, $channel); + my $params = ''; + if (defined $paramlist && scalar @$paramlist > 0) { + foreach my $param (@$paramlist) { + $param = substitute_variables($vars, $param, 0, undef, $channel) + if $param =~ /%[^%]*%/o; + $params .= ' '.$param; + } + } + $params = ' '.$params unless $params eq ''; + $$removecontext{params} = $params; + } + $uninst .= $$removecontext{params}; + my ($error, $exitcode) = run_exe($channel, $db, $vars, undef, $$removecontext{exename}, ['/C', $uninst], 0); + if (defined $error) { + if (defined $exitcode && $exitcode == 194) { + print_log($channel, INFO, 'Ignoring package %s%s removal exit code: %s', + $dispname, $printver, $exitcode); + $$counters{RebootFlag} = 1; + } + else { + push @{$$counters{FailList}}, $dispname; + $$counters{FailCount}++; + return $error; + } + } + push @{$$counters{RemovedList}}, $dispname; + $$counters{RemovedCount}++; + return undef; +} + sub remove_packages ($$$$$$$$$$) { my ($channel, $vars, $def, $paramlist, $list, $condition, $db, $basedir, $config, $counters) = @_; - my $params; - my $exename; + my $removecontext = {}; $list = sort_packages_to_remove($list); foreach my $inst (@$list) { + my $dispname = $$inst{DisplayName}; my $ver = extract_package_version($channel, $def, $inst, $basedir, $config); $ver = $$inst{DisplayVersion} unless defined $ver; my $printver = defined $ver ? ' ('.$ver.')' : ''; @@ -1561,56 +1608,18 @@ sub remove_packages ($$$$$$$$$$) my ($result, $error) = check_condition($channel, $vars, $condition); if (! defined $result) { print_log($channel, INFO, 'Ignoring package %s%s: %s', - $$inst{DisplayName}, $printver, $error); + $dispname, $printver, $error); next; } if (! $result) { print_log($channel, INFO, 'Ignoring package %s%s with false condition', - $$inst{DisplayName}, $printver); + $dispname, $printver); next; } } - - print_log($channel, DEBUG1, 'Removing package %s%s%s', $$inst{DisplayName}, $printver, - defined $condition ? ' with true condition' : ''); - - my $uninst = $$inst{Uninstall}; - my $quninst = $$inst{QUninstall}; - return sprintf('Cannot remove package %s%s, no UninstallString registry entry found', - $$inst{DisplayName}, $ver) unless defined $uninst || defined $quninst; - $uninst = $quninst if defined $quninst; - $uninst =~ s/(msiexec[^ ]* )\/i/$1\/X/io; - $uninst =~ s/(msiexec[^ ]* )/$1\/qb \/norestart \/passive /io; - print_log($channel, DEBUG2, 'Uninstall command: %s', $uninst); - $exename = substitute_variables($vars, '%systemroot%/System32/cmd.exe', 1, undef, 'pkg') - unless defined $exename; - if (! defined $params) { - $params = ''; - if (defined $paramlist && scalar @$paramlist > 0) { - foreach my $param (@$paramlist) { - $param = substitute_variables($vars, $param, 0, undef, $channel) - if $param =~ /%[^%]*%/o; - $params .= ' '.$param; - } - } - $params = ' '.$params unless $params eq ''; - } - $uninst .= $params; - my ($error, $exitcode) = run_exe($channel, $db, $vars, undef, $exename, ['/C', $uninst], 0); - if (defined $error) { - if (defined $exitcode && $exitcode == 194) { - print_log($channel, INFO, 'Ignoring package %s%s removal exit code: %s', - $$inst{DisplayName}, $printver, $exitcode); - $$counters{RebootFlag} = 1; - } - else { - push @{$$counters{FailList}}, $$inst{DisplayName}; - $$counters{FailCount}++; - return $error; - } - } - push @{$$counters{RemovedList}}, $$inst{DisplayName}; - $$counters{RemovedCount}++; + my $error = remove_package_fallback($channel, $vars, $paramlist, $inst, $condition, $dispname, + $ver, $printver, $db, $counters, $removecontext); + return $error if defined $error; } return undef; }