use Getopt::Long;
use Win32::API::Prototype;
use Win32::TieRegistry;
use Win32::Shortcut;
use Win32::AdminMisc;
use strict;
use vars qw( %HIVES %PATHS %Config $Value
    $EXECUTABLE_EXTENSIONS
 $CSIDL_STARTUP
 $CSIDL_COMMON_STARTUP
 $SHGFP_TYPE_CURRENT );
%HIVES = (
 CUser => «HKCU»,
 LMachine => «HKLM»,
 Drive => «Drive»,
);
Начало фрагмента A
ApiLink( «shell32», «HRESULT SHGetFolderPath(
 HWND hwndOwner,
 int nFolder,
 HANDLE hToken,
 DWORD dwFlags,
 LPTSTR pszPath )» ) || die;
$CSIDL_STARTUP = 0x0007; # Start MenuProgramsStartup — 
$CSIDL_COMMON_STARTUP = 0x0018; # UsersStartup
$SHGFP_TYPE_CURRENT = 1; # Current value (not default)
конец фрагмента A
Начало фрагмента B
BEGIN COMMENT LINE
# если переменная окружения PATHEXT отсутствует, создадим ее
END COMMENT LINE
$ENV{PATHEXT} = «.cmd;.com;.bat;.vbs;» unless( «» ne $ENV{PATHEXT} );
$EXECUTABLE_EXTENSIONS = join( «|», ( split( «;», $ENV{PATHEXT} . «;.pif;.lnk» ) ) );
конец фрагмента B
.
.
.
Начало фрагмента C
foreach my $Path ( @{$PATHS{registry}} )
{
 push( @RunValues, ProcessKey( $Path ) );
}
foreach my $Path ( @{$PATHS{file}} )
{
 push( @RunValues, ProcessDir( $Path ) );
}
конец фрагмента C
$~ = «DumpHeader»;
write;
$~ = «DumpData»;
Начало фрагмента D
if( scalar @{$Config{remove}} )
{
 foreach my $Index ( @{$Config{remove}} )
 {
 local $Value;
 $Value = $RunValues[ $Index ];
 $Value->{_index} = $Index;
 Remove( $Value );
BEGIN COMMENT LINE
 # Запись после вызова Remove(). Команда write может удалить
 # некоторые элементы хеша $Value
END COMMENT LINE
 write;
 }
}
else
{
 my $TotalIndex = scalar @RunValues;
 for( my $Index = 0; $Index < $TotalIndex; $Index++ )
 {
 local $Value;
 $Value = $RunValues[ $Index ];
 $Value->{_index} = $Index;
 write;
 }
}
конец фрагмента D
sub ProcessKey
{
 my( $Path ) = @_;
 my @ValueList = ();
Начало фрагмента E
 my( $Location ) = ( $Path =~ //([^/]+)// );
BEGIN COMMENT LINE
 # Открываем раздел реестра с правами доступа MAXIMUM_ALLOWED
END COMMENT LINE
 if( my $Key = $Registry->Open( $Path, {Access => 0x2000000} ))
 {
 foreach my $ValueName ( $Key->ValueNames() )
 {
 # предполагается, что все эти значения строкового типа....
 my $Data = $Key->{ «/$ValueName» };
 push( @ValueList, { _name => $ValueName, _path => $Path, _data => $Data, _location => $Location 
} );
 }
 }
 return( @ValueList );
конец фрагмента E
}
sub ProcessDir
{
 my( $Dir ) = @_;
 my @ValueList = ();
 my @DirList = ();
 if( opendir( STARTUP_DIR, $Dir ) )
 {
 while( my $File = readdir( STARTUP_DIR ) )
 {
 my $Path = «$Dir/$File»;
 next if( «.» eq $File || «..» eq $File );
 if( -d $Path )
 {
 push( @DirList, $Path );
 next;
 }
 if( $File =~ /.lnk$/i )
 { 
Начало фрагмента F
 # Process Shortcut...
 my $Shortcut = new Win32::Shortcut( $Path );
 my $Name = $Shortcut->{Description};
 if( «» eq $Name )
 {
 my %FileInfo;
 if( Win32::AdminMisc::GetFileInfo( $Shortcut->{Path}, \%FileInfo ) )
 {
 $Name = $FileInfo{FileDescription} || $File;
 }
 }
 push( @ValueList, { _name => $Name, _path => $Path, _data => «»$Shortcut->{Path}» $Shortcut-
>{Arguments}», _location => «Drive» } );
конец фрагмента F
 }
 elsif( $File =~ /($EXECUTABLE_EXTENSIONS)$/i )
 {
Начало фрагмента G
 # Process other files...
 my $Name = $File;
 my %FileInfo;
 if( Win32::AdminMisc::GetFileInfo( $Path, \%FileInfo ) )
 {
 $Name = $FileInfo{FileDescription} if( «» ne $FileInfo{FileDescription} );
 }
 push( @ValueList, { _name => $Name, _path => $Path, _data => $Path, _location => «Drive» } );
 }
конец фрагмента G
 }
 closedir( STARTUP_DIR );
 foreach my $Path ( @DirList )
 {
 push( @ValueList, ProcessDir( $Path ) );
 }
 }
 return( @ValueList );
}
.
.
.
Начало фрагмента H
 if( «drive» eq lc $Item->{_location} )
 {
 BEGIN COMMENT LINE
	# Это файл на диске
	END COMMENT LINE
 print «Deleting file: ?$Item->{_path}?
»;
 $Result = unlink( $Item->{_path} );
 }
 else
 {
BEGIN COMMENT LINE
 # Раздел реестра.
END COMMENT LINE
 my $Path = «$Item->{_path}/$Item->{_name}»;
 $Result = delete $Registry->{$Path};
 print «Deleting reg key value: ?$Path?
»;
 }
конец фрагмента H
 if( $Result )
 {
 print «REMOVED!
»;
 }
 else
 {
 print «FAILED to remove! Error: « . Win32::FormatMessage( Win32::GetLastError() );
 }
 }
 else
 {
 print « WILL NOT REMOVE $Item->{_name}!
»;
 }
}
Начало фрагмента I
sub GetSpecialDirectory
{
 my( $FolderType ) = @_;
 my $pszPath = NewString( 1024 );
 if( 0 == SHGetFolderPath( undef, $FolderType, undef, $SHGFP_TYPE_CURRENT, $pszPath ) )
 {
 $pszPath =~ s/x00//g;
 return( $pszPath );
 }
 return( undef );
}
конец фрагмента I