FusionInventory-Agent
view release on metacpan or search on metacpan
lib/FusionInventory/Agent/Tools/Win32.pm view on Meta::CPAN
$apiSetProcessWorkingSetSize->Call( $proc, -1, -1 );
};
}
my $worker ;
my $worker_semaphore;
my $worker_lasterror = [];
my $wmiService;
my $wmiLocator;
my $wmiRegistry;
my $wmiParams = {};
my @win32_ole_calls : shared;
sub start_Win32_OLE_Worker {
unless (defined($worker)) {
# Handle thread KILL signal
$SIG{KILL} = sub { threads->exit(); };
# Request a semaphore on which worker blocks immediatly
Thread::Semaphore->require();
$worker_semaphore = Thread::Semaphore->new(0);
# Start a worker thread
$worker = threads->create( \&_win32_ole_worker );
}
return $worker;
}
sub setupWorkerLogger {
my (%params) = @_;
# Just create a new Logger object in worker to update default module configuration
return defined(FusionInventory::Agent::Logger->new(%params))
unless (defined($worker));
return _call_win32_ole_dependent_api({
funct => 'setupWorkerLogger',
args => [ %params ]
});
}
sub getLastError {
return @{$worker_lasterror}
unless (defined($worker));
return _call_win32_ole_dependent_api({
funct => 'getLastError',
array => 1,
args => []
});
}
my %known_ole_errors = (
scalar(0x80041003) => "Access denied as the current or specified user name and password were not valid or authorized to make the connection.",
scalar(0x8004100E) => "Invalid namespace",
scalar(0x80041064) => "User credentials cannot be used for local connections",
scalar(0x80070005) => "Access denied",
scalar(0x800706BA) => "The RPC server is unavailable",
);
sub _keepOleLastError {
my $lasterror = Win32::OLE->LastError();
if ($lasterror) {
my $error = 0x80000000 | ($lasterror & 0x7fffffff);
# Don't report not accurate and not failure error
if ($error != 0x80004005) {
$worker_lasterror = [ $error, $known_ole_errors{$error} ];
my $logger = FusionInventory::Agent::Logger->new();
$logger->debug("Win32::OLE ERROR: ".($known_ole_errors{$error}||$lasterror));
}
} else {
$worker_lasterror = [];
}
}
sub _win32_ole_worker {
# Load Win32::OLE as late as possible in a dedicated worker
Win32::OLE->require() or return;
# We re-initialize Win32::OLE to later support Events (needed for remote WMI)
Win32::OLE->Uninitialize();
Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE());
Win32::OLE::Variant->require() or return;
Win32::OLE->Option(CP => Win32::OLE::CP_UTF8());
while (1) {
# Always block until semaphore is made available by main thread
$worker_semaphore->down();
my ($call, $result);
{
lock(@win32_ole_calls);
$call = shift @win32_ole_calls
if (@win32_ole_calls);
}
if (defined($call)) {
lock($call);
# Handle call expiration
setExpirationTime(%$call);
# Found requested private function and call it as expected
my $funct;
eval {
no strict 'refs'; ## no critic (ProhibitNoStrict)
$funct = \&{$call->{'funct'}};
};
if (exists($call->{'array'}) && $call->{'array'}) {
my @results = &{$funct}(@{$call->{'args'}});
$result = \@results;
} else {
$result = &{$funct}(@{$call->{'args'}});
}
# Keep Win32::OLE error for later reporting
( run in 0.539 second using v1.01-cache-2.11-cpan-39bf76dae61 )