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