#  MakeShares.pl
#  Example 4.2:
#  ----------------------------------------
#  From "Win32 Perl Scripting: Administrators Handbook" by Dave Roth
#  Published by New Riders Publishing.
#  ISBN # 1-57870-215-1
#
#  This script accepts a configuration file that describes details
#  to recreatign share directories.
#  Example_4_1.pl is used to generate the configuration file.
#
print "From the book 'Win32 Perl Scripting: The Administrator's Handbook' by Dave Roth\n\n";


use Win32::Lanman;
use Win32::Perms;
use Win32::API;

$DELIMITER = ";";
$File = shift( @ARGV ) || die "No config file specified\n";
$Machine = Win32::NodeName() unless( $Machine = shift( @ARGV ) );
( $Machine = "\\\\$Machine" ) =~ s/^\\{2,}/\\\\/;

%PERM_TYPE = (
    Allow   =>  ALLOW,
    Deny    =>  DENY,
);

Win32::Perms::LookupDC( 0 );

if( ProcessFile( $File, \%Config ) )
{
    foreach my $Share ( keys( %Config ) )
    {
        print "Creating $Machine\\$Config{$Share}->{netname}...";
        if( CreateShare( $Machine, $Config{$Share} ) )
        {
            print "Success";
        }
        else
        {
            print "failure: ";
            print Win32::FormatMessage( Win32::Lanman::GetLastError() );
        }
        print "\n";
    }
}


sub CreateShare
{
    my( $Machine, $Share ) = @_;
    my $Result = 0;

    if( $Share->{type} & &STYPE_SPECIAL )
    {
        print "  SPECIAL SHARE! Ignore this.\n";
        return( 0 );
    }
    if( scalar @{$Share->{perm}} )
    {
        $Perm = new Win32::Perms();
        foreach my $PermLine ( @{$Share->{perm}} )
        {
            my( $Account, $Type, $Flag, $Mask ) = split( $DELIMITER, $PermLine );
            $Perm->Add( $Account, eval( $Mask ), eval( $Type ), eval( $Flag ) );
        }
        $Share->{security_descriptor} = $Perm->GetSD( SD_RELATIVE );
    }
    if( STYPE_DISKTREE == $Share->{type} )
    {
        $Result = Win32::Lanman::NetShareAdd( $Machine, $Share );
    }
    elsif( STYPE_PRINTQ == $Share->{type} )
    {
        print "can't share a printer";
    }

    return( $Result );
}

sub ProcessFile
{
    my( $File, $ShareList ) = @_;
    my $iResult = 0;

    if( open( SHAREDATA, "<$File" ) )
    {
        $iResult = ParseShares( *SHAREDATA, $ShareList );
        close( SHAREDATA );
    }
    else
    {
        print "Unable to open '$File': $!\n";
    }
    return( $iResult );
}

sub ParseShares
{
    my( $FileHandle, $ShareList ) = @_;
    my $ShareName = "";
    my $iTotal = 0;

    while( $Line = <$FileHandle> )
    {
        my( $Name, $Value );

        next if( $Line =~ /^\s*[#;]/ );
        next if( $Line =~ /^\s*$/ );
        if( ( $Name ) = ( $Line =~ /^\s*\[\s*(.*?)\s*\]/ ) )
        {
            $ShareName = lc $Name;
            $iTotal++;
            next;
        }
        next if( "" eq $ShareName );

        ( $Name, $Value ) = ( $Line =~ /^\s*(.*?)=(.*)\s*$/ );
        if( "" ne $Name )
        {
            $Name = lc $Name;
            if( "perm" eq $Name )
            {
                push( @{$ShareList->{$ShareName}->{$Name}}, $Value );
            }
            else
            {
                $Value = eval( $Value ) if( "type" eq $Name );
                $ShareList->{$ShareName}->{$Name} = $Value;
            }
        }
    }
    return( $iTotal );
}

# For some reason Win32::Lanman forgot to export this constant
sub STYPE_SPECIAL
{
    return( 0x80000000 );
}
