File Coverage

blib/lib/Win32/NetName.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Win32::NetName;
2            
3 1     1   790 use File::Spec;
  1         3  
  1         28  
4 1     1   2006 use Win32::API;
  0            
  0            
5             use Win32::Lanman;
6            
7             use Win32::VolumeInformation qw( GetVolumeInformation );
8            
9             use Exporter ();
10             our @ISA = qw( Exporter );
11             our @EXPORT_OK = qw( GetUniversalName GetLocalName );
12            
13             our $VERSION = 0.3;
14            
15             Win32::API->Import('kernel32', 'GetDriveType', ['P'], 'N')
16             or die "Win32::API->Import GetDriveType: $!";
17            
18             sub GetLocalName{
19             my $infile = $_[1];
20             $infile = File::Spec->rel2abs($infile);
21             $infile = File::Spec->canonpath($infile);
22             return 0 if $infile =~ /^\w/;
23             my($vol,$path,$file) = File::Spec->splitpath($infile);
24             $vol =~ s/(\w+)/\U$1/; # uc machine name - should File::Spec do this?
25             if( uc $1 eq Win32::NodeName() ){
26             if( GetLocalPath(my $p, $infile) ){
27             $_[0] = $p;
28             return 1;
29             }else{
30             return 0;
31             }
32             }
33             for my $disk ('A'..'Z'){
34             $disk .= ':';
35             my $share;
36             Win32::Lanman::WNetGetConnection($disk,\$share);
37             if( uc $vol eq uc $share ){
38             my $outfile = File::Spec->catdir($disk,$path,$file);
39             $_[0] = $outfile;
40             return 1;
41             }
42             }
43             return 0;
44             }
45            
46             sub GetLocalPath{
47             my $infile = $_[1];
48             $infile = File::Spec->rel2abs($infile);
49             $infile = File::Spec->canonpath($infile);
50             return 0 if $infile =~ /^\w/;
51             my($vol,$path,$file) = File::Spec->splitpath($infile);
52             $vol =~ s/(\w+)/\U$1/; # uc machine name - should File::Spec do this?
53             my $node = $_[2] || Win32::NodeName();;
54             return 0 unless GetDiskShares(my $n, $node);
55             for my $s (@$n){
56             if( uc "\\\\$node\\$s->{netname}" eq uc $vol ){
57             my $outfile = File::Spec->catdir($s->{path}, $path, $file );
58             $_[0] = $outfile;
59             return 1;
60             }
61             }
62             return 0;
63             }
64            
65             sub GetUniversalName{
66             my $infile = $_[1];
67             $infile = File::Spec->rel2abs($infile);
68             $infile = File::Spec->canonpath($infile);
69             return 0 unless $infile =~ /^\w/;
70             my($vol,$path,$file) = File::Spec->splitpath($infile);
71             if( GetDriveType($vol) == 4 ){ # remote share
72             my %info;
73             if( Win32::Lanman::WNetGetUniversalName($infile, \%info)){
74             $_[0] = $info{universalname};
75             return 1;
76             }else{
77             return 0;
78             }
79             }else{ # local share
80             if( GetUniversalPaths(my $p, $infile ) ){
81             if( @$p ){
82             $_[0] = $p->[0];
83             return 1;
84             }
85             }
86             }
87             return 0;
88             }
89            
90             sub GetUniversalPaths{
91             my $infile = $_[1];
92             my $node = $_[2] || Win32::NodeName();
93             my @names;
94             return 0 unless GetDiskShares(my $n, $node);
95            
96            
97             my $compare = sub{ $_[0] eq $_[1] };
98             my($vol,$path,$file) = File::Spec->splitpath($infile);
99             my %info;
100             if( GetVolumeInformation($vol,\%info) ){
101             unless( $info{FS_CASE_SENSITIVE} ){
102             $compare = sub{ uc $_[0] eq uc $_[1] };
103             }
104             }else{
105             return 0;
106             }
107            
108            
109             for my $s (@$n){
110             my $path = $s->{path};
111             if( $compare->($path,$infile) ){
112             push @names, "\\\\$node\\$s->{netname}";
113             }elsif( length $infile > length $path ){
114             my $test = substr($infile,0,length $path);
115             if( $compare->($test,$path) && substr($infile,length $path, 1) eq "\\" ){
116             my @infile = File::Spec->splitdir($infile);
117             my @test = File::Spec->splitdir($test);
118             splice @infile, 0, scalar @test;
119             my $dir = File::Spec->catdir("\\\\$node\\$s->{netname}",@infile);
120             push @names, $dir;
121             }
122             }
123             }
124             if(@names){
125             $_[0] = \@names;
126             return 1;
127             }
128             return 0;
129             }
130            
131             sub GetDiskShares{
132             my $node = $_[1] || Win32::NodeName();
133             my @stuff;
134             my @info;
135             if (Win32::Lanman::NetShareEnum("\\\\$node",\@stuff)) {
136             for my $share (@stuff){
137             if( $share->{type} == 0 ){
138             push @info, $share;
139             }
140             }
141             if(@info){
142             $_[0] = \@info;
143             return 1;
144             }
145             }
146             return 0;
147             }
148            
149             1;
150            
151             __END__