Dear monks,
I am trying to do a simple thing: change the permissions on a directory tree under WinXP to a standard value. So I started with Win32::FileSecurity module, and the idea was simple: I'll read in the permissions from 2 files (for directories and files), and using File::Find, just traverse the tree and if the permissions don't match, just Set() them to the wanted ones. Easy, right? But no.....

The script is pasted below. Here's the weird thing. The hash %dhash contains key-value pairs, like these:

        BUILTIN\Administrators => 270467583
        NT AUTHORITY\SYSTEM => 270467583
        Everyone => 1245631
I copy these values into a separate hash, called %hash (sorry about the naming). After the call to Set, the keys in all of my hashes get changed from something like this "BUILTIN\Administrators" to "BUILTIN Administrators". Naturally, the Set() fails in the next iteration. But I am really confused as to why strings that are not even a part of the manipulation (keys in %dhash and %fhash) are being modified?

-- confused in win32land


Code is below. It isn't a shining beacon of good coding, but I've lost half of my hair today, so my head indeed is shining right now...
#! C:\Perl\bin\perl.exe -w use strict; use File::Find (); use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; use Win32::FileSecurity qw(Get Set MakeMask); sub wanted; my %dhash; my %fhash; die "Usage: $0 <path>\n" unless (@ARGV); die "Need dmask.txt file\n" unless (-r "C:\\dmask.txt"); die "Need fmask.txt file\n" unless (-r "C:\\fmask.txt"); open(IN,"<", 'c:\dmask.txt') || die "dmask.txt: $!\n"; while (<IN>) { chomp; my ($id,@mask) = split(/\t/); $dhash{$id} = MakeMask(@mask); } close(IN); open(IN,"<", 'c:\fmask.txt') || die "fmask.txt: $!\n"; while (<IN>) { chomp; my ($id,@mask) = split(/\t/); $fhash{$id} = MakeMask(@mask); } close(IN); # Traverse desired filesystems File::Find::find({wanted => \&wanted}, $ARGV[0]); exit; sub wanted { my %hash; if (-d $name) { if ( Get( $name, \%hash ) ) { my $fix = 0; foreach my $id (keys %dhash) { if ((! exists($hash{$id})) or ($hash{$ +id} != $dh ash{$id})) { $hash{$id} = $dhash{$id}; $fix = 1; } } if ($fix != 0) { Set( $name, \%hash); } } else { print( "Error #", int( $! ), ": $!" ) ; } } elsif (-f $name) { if ( Get( $name, \%hash ) ) { my $fix = 0; foreach my $id (keys %fhash) { if ((! exists($hash{$id})) or ($hash{$ +id} != $fh ash{$id})) { $hash{$id} = $fhash{$id}; $fix = 1; } } if ($fix != 0) { Set( $name, \%hash); } } else { print( "Error #", int( $! ), ": $!" ) ; } } }

In reply to Win32::FileSecurity weirdness by keymon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.