in reply to Two questions (two birds with one stone)

  1. 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$};
  2. 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 );