?? tieregistry.pm
字號:
my $dlen;
my $sam;
my $subPath;
if( @_ < 1 || 2 < @_
|| 2 == @_ && "HASH" ne ref($opts) ) {
croak "Usage: \$obj= ${PACK}->new( \$subKey, { OPT=>VAL,... } );\n",
" options: @new_Opts\nCalled";
}
if( defined($opts) ) {
my @err= grep( ! $new_Opts{$_}, keys(%$opts) );
@err and die "${PACK}->new: Invalid options (@err)";
}
$delim= "$opts->{Delimiter}" if defined($opts->{Delimiter});
$delim= $this->Delimiter if "" eq $delim;
$dlen= length($delim);
$sam= defined($opts->{Access}) ? $opts->{Access} : $this->Access;
$sam= Win32API::Registry::constant($sam,0) if $sam =~ /^KEY_/;
if( "ARRAY" eq ref($subKey) ) {
$subPath= $subKey;
if( "NONE" eq $this->Handle && @$subPath ) {
( $this, $subPath )= $this->_rootKey( $subPath );
}
} elsif( $delim x 2 eq substr($subKey,0,2*$dlen) ) {
my $path= $this->_split( substr($subKey,2*$dlen), $delim );
my $mach= shift(@$path);
if( ! @$path ) {
return $this->_newVirtual( $path, $Registry,
{MACHINE=>$mach,DELIM=>$delim,ACCESS=>$sam} );
}
( $this, $subPath )= $this->_connect( $mach, $path );
return wantarray ? () : undef if ! defined($this);
if( 0 == @$subPath ) {
$this->Delimiter( $delim );
return $this;
}
} elsif( $delim eq substr($subKey,0,$dlen) ) {
( $this, $subPath )= $this->_rootKey( substr($subKey,$dlen), $delim );
} elsif( "NONE" eq $this->Handle && "" ne $subKey ) {
my( $mach )= $this->Machine;
if( $mach ) {
( $this, $subPath )= $this->_connect( $mach, $subKey );
} else {
( $this, $subPath )= $this->_rootKey( $subKey, $delim );
}
} else {
$subPath= $this->_split( $subKey, $delim );
}
return wantarray ? () : undef unless defined($this);
if( 0 == @$subPath && "NONE" eq $this->Handle ) {
return $this->_newVirtual( $this->_Path, $this,
{ DELIM=>$delim, ACCESS=>$sam } );
}
my $self= $this->_open( $subPath, $sam );
return wantarray ? () : undef unless defined($self);
$self->Delimiter( $delim );
return $self;
}
sub Open
{
my $self= shift(@_);
my $tied= ref($self) && tied(%$self);
$self= tied(%$self) if $tied;
$self= $self->new( @_ );
$self= $self->TiedRef if defined($self) && $tied;
return $self;
}
sub Clone
{
my $self= shift( @_ );
my $new= $self->Open("");
return $new;
}
{ my @flush;
sub Flush
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
my( $flush )= @_;
@_ and croak "Usage: \$key->Flush( \$bFlush );";
return 0 if "NONE" eq $self->Handle;
@flush= qw( VALUES SUBKEYS SUBCLASSES SUBTIMES MEMBERS Class
CntSubKeys CntValues MaxSubKeyLen MaxSubClassLen
MaxValNameLen MaxValDataLen SecurityLen LastWrite PREVIDX )
unless @flush;
delete( @$self{@flush} );
if( defined($flush) && $flush ) {
return $self->RegFlushKey();
} else {
return 1;
}
}
}
sub _DualVal
{
my( $hRef, $num )= @_;
if( $_SetDualVar && $$hRef{$num} ) {
&SetDualVar( $num, "$$hRef{$num}", 0+$num );
}
$num;
}
use vars qw( @_RegDataTypes %_RegDataTypes );
@_RegDataTypes= qw( REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY
REG_DWORD_LITTLE_ENDIAN REG_DWORD_BIG_ENDIAN
REG_DWORD REG_LINK REG_MULTI_SZ REG_RESOURCE_LIST
REG_FULL_RESOURCE_DESCRIPTOR
REG_RESOURCE_REQUIREMENTS_LIST );
# Make sure REG_DWORD appears _after_ other REG_DWORD_* items above.
foreach( @_RegDataTypes ) {
$_RegDataTypes{Win32API::Registry::constant($_,0)}= $_;
}
sub GetValue
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
1 == @_ or croak "Usage: (\$data,\$type)= \$key->GetValue('ValName');";
my( $valName )= @_;
my( $valType, $valData, $dLen )= (0,"",0);
return wantarray ? () : undef if "NONE" eq $self->Handle;
$self->RegQueryValueEx( $valName, [], $valType, $valData,
$dLen= ( defined($self->{MaxValDataLen}) ? $self->{MaxValDataLen} : 0 )
) or return wantarray ? () : undef;
if( REG_DWORD == $valType ) {
my $val= unpack("L",$valData);
$valData= sprintf "0x%08.8lX", $val if $self->DWordsToHex;
&SetDualVar( $valData, $valData, $val ) if $self->DualBinVals
} elsif( REG_BINARY == $valType && length($valData) <= 4 ) {
&SetDualVar( $valData, $valData, hex reverse unpack("h*",$valData) )
if $self->DualBinVals;
} elsif( ( REG_SZ == $valType || REG_EXPAND_SZ == $valType )
&& $self->FixSzNulls ) {
substr($valData,-1)= "" if "\0" eq substr($valData,-1);
} elsif( REG_MULTI_SZ == $valType && $self->SplitMultis ) {
## $valData =~ s/\0\0$//; # Why does this often fail??
substr($valData,-2)= "" if "\0\0" eq substr($valData,-2);
$valData= [ split( /\0/, $valData, -1 ) ]
}
if( ! wantarray ) {
return $valData;
} elsif( ! $self->DualTypes ) {
return( $valData, $valType );
} else {
return( $valData, _DualVal( \%_RegDataTypes, $valType ) );
}
}
sub _ErrNum
{
# return $^E;
return Win32::GetLastError();
}
sub _ErrMsg
{
# return $^E;
return Win32::FormatMessage( Win32::GetLastError() );
}
sub _Err
{
my $err;
# return $^E;
return _ErrMsg if ! $_SetDualVar;
return &SetDualVar( $err, _ErrMsg, _ErrNum );
}
sub _NoMoreItems
{
$_NoMoreItems =~ /^\d/
? _ErrNum == $_NoMoreItems
: _ErrMsg =~ /$_NoMoreItems/io;
}
sub _FileNotFound
{
$_FileNotFound =~ /^\d/
? _ErrNum == $_FileNotFound
: _ErrMsg =~ /$_FileNotFound/io;
}
sub _TooSmall
{
$_TooSmall =~ /^\d/
? _ErrNum == $_TooSmall
: _ErrMsg =~ /$_TooSmall/io;
}
sub _MoreData
{
$_MoreData =~ /^\d/
? _ErrNum == $_MoreData
: _ErrMsg =~ /$_MoreData/io;
}
sub _enumValues
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
my( @names )= ();
my $pos= 0;
my $name= "";
my $nlen= 1+$self->Information("MaxValNameLen");
while( $self->RegEnumValue($pos++,$name,$nlen,[],[],[],[]) ) {
push( @names, $name );
}
if( ! _NoMoreItems() ) {
return wantarray ? () : undef;
}
$self->{VALUES}= \@names;
1;
}
sub ValueNames
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \@names= \$key->ValueNames;";
$self->_enumValues unless $self->{VALUES};
return @{$self->{VALUES}};
}
sub _enumSubKeys
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
my( @subkeys, @classes, @times )= ();
my $pos= 0;
my( $subkey, $class, $time )= ("","","");
my( $namSiz, $clsSiz )= $self->Information(
qw( MaxSubKeyLen MaxSubClassLen ));
$namSiz++; $clsSiz++;
while( $self->RegEnumKeyEx(
$pos++, $subkey, $namSiz, [], $class, $clsSiz, $time ) ) {
push( @subkeys, $subkey );
push( @classes, $class );
push( @times, $time );
}
if( ! _NoMoreItems() ) {
return wantarray ? () : undef;
}
$self->{SUBKEYS}= \@subkeys;
$self->{SUBCLASSES}= \@classes;
$self->{SUBTIMES}= \@times;
1;
}
sub SubKeyNames
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \@names= \$key->SubKeyNames;";
$self->_enumSubKeys unless $self->{SUBKEYS};
return @{$self->{SUBKEYS}};
}
sub SubKeyClasses
{
my $self= shift(@_);
@_ and croak "Usage: \@classes= \$key->SubKeyClasses;";
$self->_enumSubKeys unless $self->{SUBCLASSES};
return @{$self->{SUBCLASSES}};
}
sub SubKeyTimes
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \@times= \$key->SubKeyTimes;";
$self->_enumSubKeys unless $self->{SUBTIMES};
return @{$self->{SUBTIMES}};
}
sub _MemberNames
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \$arrayRef= \$key->_MemberNames;";
if( ! $self->{MEMBERS} ) {
$self->_enumValues unless $self->{VALUES};
$self->_enumSubKeys unless $self->{SUBKEYS};
my( @members )= ( map( $_.$self->{DELIM}, @{$self->{SUBKEYS}} ),
map( $self->{DELIM}.$_, @{$self->{VALUES}} ) );
$self->{MEMBERS}= \@members;
}
return $self->{MEMBERS};
}
sub _MembersHash
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \$hashRef= \$key->_MembersHash;";
if( ! $self->{MEMBHASH} ) {
my $aRef= $self->_MemberNames;
$self->{MEMBHASH}= {};
@{$self->{MEMBHASH}}{@$aRef}= (1) x @$aRef;
}
return $self->{MEMBHASH};
}
sub MemberNames
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \@members= \$key->MemberNames;";
return @{$self->_MemberNames};
}
sub Information
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
my( $time, $nkeys, $nvals, $xsec, $xkey, $xcls, $xname, $xdata )=
("",0,0,0,0,0,0,0);
my $clen= 8;
if( ! $self->RegQueryInfoKey( [], [], $nkeys, $xkey, $xcls,
$nvals, $xname, $xdata, $xsec, $time ) ) {
return wantarray ? () : undef;
}
if( defined($self->{Class}) ) {
$clen= length($self->{Class});
} else {
$self->{Class}= "";
}
while( ! $self->RegQueryInfoKey( $self->{Class}, $clen,
[],[],[],[],[],[],[],[],[])
&& _MoreData ) {
$clen *= 2;
}
my( %info );
@info{ qw( LastWrite CntSubKeys CntValues SecurityLen
MaxValDataLen MaxSubKeyLen MaxSubClassLen MaxValNameLen )
}= ( $time, $nkeys, $nvals, $xsec,
$xdata, $xkey, $xcls, $xname );
if( @_ ) {
my( %check );
@check{keys(%info)}= keys(%info);
my( @err )= grep( ! $check{$_}, @_ );
if( @err ) {
croak "${PACK}::Information- Invalid info requested (@err)";
}
return @info{@_};
} else {
return %info;
}
}
sub Delimiter
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
$self= $RegObj unless ref($self);
my( $oldDelim )= $self->{DELIM};
if( 1 == @_ && "" ne "$_[0]" ) {
delete $self->{MEMBERS};
delete $self->{MEMBHASH};
$self->{DELIM}= "$_[0]";
} elsif( 0 != @_ ) {
croak "Usage: \$oldDelim= \$key->Delimiter(\$newDelim);";
}
$oldDelim;
}
sub Handle
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \$handle= \$key->Handle;";
$self= $RegObj unless ref($self);
$self->{HANDLE};
}
sub Path
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \$path= \$key->Path;";
my $delim= $self->{DELIM};
$self= $RegObj unless ref($self);
if( "" eq $self->{MACHINE} ) {
$delim . join( $delim, @{$self->{PATH}} ) . $delim;
} else {
$delim x 2
. join( $delim, $self->{MACHINE}, @{$self->{PATH}} )
. $delim;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -