File Coverage

blib/lib/Crypt/Random/Provider/Win32API.pm
Criterion Covered Total %
statement 15 46 32.6
branch 1 18 5.5
condition 0 11 0.0
subroutine 5 8 62.5
pod 0 3 0.0
total 21 86 24.4


line stmt bran cond sub pod time code
1             ##
2             ## Copyright (c) 1998-2025, Vipul Ved Prakash. All rights reserved.
3             ## This code is free software; you can redistribute it and/or modify
4             ## it under the same terms as Perl itself.
5             ## The WIN32API implementation below is based on code written by
6             ## Leon Timmermans (Leont) as implemented here by Timothy Legge (timlegge)
7              
8 3     3   19 use strict;
  3         7  
  3         117  
9 3     3   22 use warnings;
  3         6  
  3         231  
10             package Crypt::Random::Provider::Win32API;
11 3     3   13 use Math::Pari qw(pari2num);
  3         19  
  3         18  
12 3     3   1869 use Crypt::URandom qw/urandom/;
  3         13273  
  3         2059  
13              
14             our $VERSION = '1.57';
15              
16             sub new {
17              
18 0     0 0 0 my ($class, %params) = @_;
19 0         0 my $self = { Source => $params{Source} };
20 0         0 return bless $self, $class;
21              
22             }
23              
24             sub get_data {
25              
26 0     0 0 0 my ($self, %params) = @_;
27 0 0       0 $self = {} unless ref $self;
28              
29 0         0 my $size = $params{Size};
30 0   0     0 my $skip = $params{Skip} || $$self{Skip} || '';
31 0         0 my $q_skip = quotemeta($skip);
32              
33 0 0 0     0 if ($size && ref $size eq "Math::Pari") {
34 0         0 $size = pari2num($size);
35             }
36              
37 0   0     0 my $bytes = $params{Length} || (int($size / 8) + 1);
38 0         0 my $source;
39              
40 0 0       0 if (eval { require Win32::API }) {
  0         0  
41 0 0       0 my $genrand = Win32::API->new('advapi32', 'INT SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength)')
42             or Carp::croak("Could not import SystemFunction036: $^E");
43              
44             $source = sub {
45 0     0   0 my ($count) = @_;
46 0 0       0 return '' if $count == 0;
47 0 0 0     0 Carp::croak('The Length argument must be supplied and must be an integer') if not defined $bytes or $bytes =~ /\D/;
48 0         0 my $buffer = chr(0) x $count;
49 0 0       0 $genrand->Call($buffer, $count) or Carp::croak("Could not read random data");
50 0         0 return $buffer;
51 0         0 };
52             }
53             else {
54 0         0 Carp::croak('Win32::API is required');
55             }
56              
57 0         0 my($r, $read, $rt) = ('', 0);
58 0         0 while ($read < $bytes) {
59 0         0 $rt = &$source($bytes - $read);
60 0 0       0 $rt =~ s/[$q_skip]//g if $skip;
61 0         0 $r .= $rt;
62 0         0 $read = length $r;
63             }
64              
65 0         0 $r;
66             }
67              
68              
69             sub available {
70 5 50   5 0 12 if (eval { require Win32::API }) {
  5         693  
71 0         0 return 1;
72             } else {
73 5         65 return 0;
74             };
75             }
76              
77             1;