-
Under NTFS, the directory 'System Volume Information' is
always open and locked on an mounted filesystem.
Administrator privilege will not help. Mounting the NTFS
volume as read-only on a Linux box *might* allow you to read
it. Those monks not
getting the error are perhaps running FAT32 volumes. When
coding File::Find under Win32, I always start the
&wanted subroutine with this line:
$File::Find::prune = 1, return
if $File::Find::name =~ m{^.:/System Volume Information$};
-
You can get out of the Find loop quickly by setting a flag
when you want to stop, and then using the flag to set $prune
and return for all future files. It is not immediate, but
you only continue to check the files (not sub-directories) in the
current directory, and each of its parents. If you *must* have
an immediate exit (due to a slow NFS-mounted search,
perhaps), then you could use the dreaded goto. It
works just fine for this.
As an example, the code below finds the first file over
100MB in size, and then gets out quickly. On my NTFS volume
(19489 files), $extras was just 19. Uncomment
the line to test the goto version.
use File::Find;
my @drives = ( 'c:/', 'd:/' );
my $kill_find = 0;
my $extras = 0;
find( sub {
$extras++ if $kill_find;
$File::Find::prune = 1, return
if $File::Find::name =~ m{^.:/System Volume Information$};
$File::Find::prune = 1, return if $kill_find;
return if -d $_;
# print "$File::Find::name\n" and goto End_F if -s(_) > 100_000_000;
print "$File::Find::name\n" and $kill_find=1 if -s(_) > 100_000_000;
}, @drives );
End_F:
print "Extra files or directories checked by this method: $extras\n";
Meditation on skiping to the next dir using File::Find; may provide further enlightenment.
Lastly, GetVolumeInformation does not return 'Local Disk' unless that happens to be the volume name you gave your disk when you formatted it. FWIW, here is how I would write the code you posted:
#!/usr/bin/perl -w
use strict;
use warnings 'all';
use File::Find;
use Win32API::File qw( :Func :DRIVE_ );
my @drives = map { tr{\\}{/}s; $_ }
grep { GetDriveType($_) == DRIVE_FIXED }
getLogicalDrives();
find( sub {
$File::Find::prune = 1, return
if $File::Find::name =~ m{^.:/System Volume Information$};
return unless /^VCVARS32\.BAT$/i;
for ($File::Find::name) {
# s{\/}{};
# tr{/}{\\};
print "$_\n";
}
}, @drives );
|