How To : Using Win32::Packages with Perl 5

Win32::Registry

Checked with build 310

Last modification :
New design
OpenEx function
Flush function

8.98


This work is mostly based on discussions of the Perl for Win32 mailing list (Roger D. Knapp, R. Graessler, Robin S. Chatterjee, Robert Lefferts and the others). Thanks to Robert for is great RegPatch module

WARNING: Editing registry incorrectly can cause serious, system-wide problems that may require you to reinstall Windows (95 & NT) to correct them.

NT users must use 'Repair Disk' (rdisk.exe) utility to create an emergency disk, refer to Windows NT documentation for more information. To restore you will need the 3 startup disks or to boot on NT CD.

Open
Opens the specified registry key of the specified sub registry object.
Syntax
$object->Open($RegistryObj,$hKey);
$object A part of the registry. See table below.
$RegistryObj The key under the $object you want to explore.
$hKey Handle of the opened key.


$object
O/S Key Description
95 & NT $HKEY_LOCAL_MACHINE Informations about the local computer system, including hardware and OS.
$HKEY_USERS All actively loaded user profiles, including HKEY_CURRENT_USER, which always refers to a child of HKEY_USERS, and the default profile.
$HKEY_CURRENT_USER User profile for the user who is currently logged on, including environment variables, personal program groups, desktop settings, network connections, printers, and application preferences.
$HKEY_CLASSES_ROOT Object linking and embedding (OLE) and file-class association data.
$HKEY_CURRENT_CONFIG Points to the current system configuration in the collection of configurations stored in Hkey_Local_Machine\Config.
NT $HKEY_PERFORMANCE_DATA Handles used to collect performance data with RegQueryValueEx.
Note that the performance data are not stored in the Registry database. ReqQueryKeyEx will causes the system to collect the data.
$HKEY_PERFORMANCE_TEXT
$HKEY_PERFORMANCE_NLSTEXT
95 $HKEY_DYN_DATA Handle to informations from the devices currently installed and loaded, or that failed loading.
This is dynamic information, stored in volatile memory. Data are updated at startup and whenever the system configuration is modified. It also contains some performance data under under Hkey_Dyn_Data\PerfStats.

Example

use Win32::Registry;
my $Register = "Software\\MICROSOFT";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->Close();

Notes

  • This function is provided for compatibility with Windows version 3.x. You should use the RegOpenKeyEx function, see OpenEx.
  • The registry in Windows 95 contains two more hives : HKEY_DYN_DATA and HKEY_CURRENT_CONFIG that are not included, see below modifications of Registry.pm.
  • To open the registry of a remote computer you need to use RegConnectRegistry, for an example see below Connect.

Close
Releases the handle on the key.
Syntax
$hkey->Close();
$hkey Handle of a key.

Example

use Win32::Registry;
my $Register = "Software\\Netscape";
my ($hkey, @key_list, $key);

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->GetKeys(\@key_list);
print "$Register keys\n";
foreach $key (@key_list)
	{
	print "$key\n";
	}
$hkey->Close();

GetKeys

Returns an array with all the subkeys of a specified key. Each subkey can contain values entries or additional subkeys.

Syntax
$hkey->GetKeys(\@Key_list);
$hkey Pointer to a key of the registry.
@Key_list Array with all the subkeys.

Example

use Win32::Registry;
my $Register = "Software\\Netscape";
my ($hkey, @key_list, $key);

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->GetKeys(\@key_list);
print "$Register keys\n";
foreach $key (@key_list)
	{
	print "$key\n";
	}
$hkey->Close();

GetValues

Returns an array with all the values of a specified key.

Syntax
$hkey->GetValues(\%values);
$hkey Pointer to a key of the registry.
%values Hash (Name, Type, Value) for each value.


Data Types for Registry Entries
Value Value Type Description
0 REG_NONE No value type.
1 REG_SZ A sequence of characters representing human readable text. Unicode null terminated string.
2 REG_EXPAND_SZ An expandable data string, which is text that contains a variable to be replaced when called by an application (ex : %windir%\system\wsock32.dll ). Unicode null terminated string.
3 REG_BINARY Raw binary data. Most hardware component information is stored as binary data, and can be displayed in hexadecimal format.
4 REG_DWORD 32 bits number.
REG_DWORD_LITTLE_ENDIAN Same as REG_DWORD.
5 REG_DWORD_BIG_ENDIAN 32 bits number but in big endian format.
Not commonly used.
6 REG_LINK A symbolic link (unicode).
7 REG_MULTI_SZ A multiple string. Values that contain lists or multiple values in human readable text are usually this type (unicode). Entries are separated by NULL characters.
8 REG_RESOURCE_LIST Ressource list in the ressource map.
9 REG_FULL_RESOURCE_DESCRIPTOR Resource list in the hardware description
10 REG_RESSOURCE_REQUIREMENT_MAP Resource list in the hardware description.

Example

use Win32::Registry;
my %RegType = (
			0 => 'REG_0',
			1 => 'REG_SZ',
			2 => 'REG_EXPAND_SZ',
			3 => 'REG_BINARY',
			4 => 'REG_DWORD',
			5 => 'REG_DWORD_BIG_ENDIAN',
			6 => 'REG_LINK',
			7 => 'REG_MULTI_SZ',
			8 => 'REG_RESOURCE_LIST',
			9 => 'REG_FULL_RESOURCE_DESCRIPTION',
			10 => 'REG_RESSOURCE_REQUIREMENT_MAP');

my $Register = "Software\\MICROSOFT\\Java VM";
my $RegType, $RegValue, $RegKey, $value;
my %values;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;

$hkey->GetValues(\%values);

foreach $value (keys(%values))
	{
	$RegType 	= $values{$value}->[1];
	$RegValue 	= $values{$value}->[2];
	$RegKey 	= $values{$value}->[0];
	next if ($RegType eq '');  #do not print default value if not assigned
	$RegKey 	= 'Default' if ($RegKey eq '');	#name the default key
	print "$RegKey";
	print " ($RegType{$RegType}) : ";

	SWITCH:
		{
		if ($RegType == 4)
			{printf "Ox%1x \n", unpack("L",$RegValue); last SWITCH; }
		if ($RegType == 5)
			{printf "Ox%1x", unpack("N",$RegValue); last SWITCH; }
 		if ($RegType < 8 )
			{printf "$RegValue\n"; last SWITCH; }
		print "\n";
		}
	}
$hkey->Close();

Create

Creates the specified key, if the key already exists the function opens it. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the NTRegCreateKeyEx function.

See below for bugs

Syntax
$hkey->Create($key,$subkey);
$hkey Pointer to a key of the registry.
$key Name of a key to open or to create.
$subkey Receives the handle of the opened or created key.

Example

use Win32::Registry;
my $Register = "Software";
my $hkey,$SubKey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->Create("FunStuff",$SubKey);
$hkey->Close();

DeleteKey

Deletes a specified key.

Syntax
$hkey->DeleteKey($subkey);
$hkey Pointer to a key of the registry.
$subkey Name of subkey to delete.

Example

use Win32::Registry;
my $Register = "Software";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->DeleteKey("FunStuff");
$hkey->Close();

Notes

  • 95 : deletes a key and all its descendents
  • NT : deletes only an empty key.

DeleteValue

Deletes a specified value in the open key.

Syntax
$hkey->DeleteValue($Name);
$hkey A currently open key.
$Name Name of value to delete.

Example

use Win32::Registry;
my $Register = "Software\\FunStuff";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->DeleteValue("MyValue");
$hkey->Close();

SetValue
Associates a default value with a specified key. If the key doesn't exist, the method creates it. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the SetValueEx method.
Syntax
$hkey->SetValue($subkey,$type,$value);
$hkey A currently open key.
$subkey Name of subkey to modify.
$type This parameter must be of REG_SZ type.
$value Name of the value.

Example

>use Win32::Registry;
my $Register = "Software";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->SetValue("FunStuff",REG_SZ,"Let me out !!!");
$hkey->Close();

SetValueEx
Stores data in the value field of a key, or set additional value and type information for the specified key.
Syntax
$hkey->SetValueEx($ValueNam,$Reserved,$Type,$Data);
$hkey A currently open key.
$ValueName Name of the value to set.
$Reserved Must be NULL (undef).
$Type Type of the value, see the table.
$Data The value or data.

Example

use Win32::Registry;
my $Register = "Software//FunStuff";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
undef $garbage;
$hkey->SetValueEx("MyValue",$garbage,REG_SZ,"Let me out !!!");
$hkey->Close();

QueryValue
The QueryValue function retrieves the value associated with the unnamed value for a specified key in the registry. This is provided for compatibility with Windows version 3.1. Win32-based applications should use the NTRegQueryValueEx function.
Syntax
$hkey->QueryValue($SubKey,$Value);
$hkey A currently open key.
$SubKey Name of subkey to query.
$Value Value of the unnamed value ...

Example

use Win32::Registry;
my $Register = "Software\\MICROSOFT\\Java VM";
my $hkey, $value;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->QueryValue($subkey,$value);
print "the unnamed value is : ";
if ($value eq '')
	{
	print "undefined\n";
	}
else
	{
	print "$value\n";
	}
$hkey->Close(); 

QueryKey
Returns the number of keys and values from the current key. See below for bugs.
Syntax
$hkey->QueryKey($SubKey,$Value);
$hkey A currently open key.
$SubKey Number of subkeys contained by the specified key. Can be NULL.
$Value Number of values associated with the key. Can be NULL.

Example

use Win32::Registry;
my $Register = "Software\\Netscape";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->QueryKey($subkeys,$values);
print "$subkeys keys, $values values\n";
$hkey->Close(); 

Save
Save registry from current location to a file.This will not save the entire registry, you need to save each main key. The caller of this function must possess the SeBackupPrivilege security privilege. It does not save volatile keys. A key is made volatile or nonvolatile at its creation.

Syntax

Syntax
$hkey->Save($Filename);
$hkey A currently open key.
$Filename File name ! This file cannot already exist.
If this filename includes an extension, it cannot be used on FAT file systems by the Load function. The file will have the System, Hidden and Read-Only attributes setted (before you began searching around ...)!

Example

use Win32::Registry;
my $Register = "Software\\Netscape";
my $hkey;

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
if (IsWin95())
	{
	$hkey->Save("c:\\just_in_case"); #no extension on FAT !
	}
else
	{
	$hkey->Save("c:\\just_in_case.reg"); #extension on NTFS !
	}
$hkey->Close();

Load
Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores registration information from a specified file into that subkey.
Syntax
$hkey->Load($SubKey,$Filename);
$hkey A currently open key.
$SubKey Name of the key to be created under hkey.
$Filename Filename.

Example

use Win32::Registry;
my $Register = "";
my $subkey = "MyHomeKey";

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->Load($subkey,"c:\\just_in_case.reg");
$hkey->Close(); 

Connect [Custom Function]
Connects to the registry of a distant computer.
Syntax
$object->Connect( $Node,$ObjRef );
$object A part of the registry. See table.
$Node UNC of a Windows computer, ex : \\\\LUKE.
$ObjRef Handle of the opened key.

Example

#Hack send by Frederick, Michael
#Connect: creates to a remote Registry object.
# usage: $RegObj->Connect( "SubKey",$SubKeyObj );
use Win32::Registry;
my ($node) = '\\\\MyComputer';
my ($hNode, $hKey, %values);

$HKEY_LOCAL_MACHINE->Connect ($node, $hNode) || die "Cannot connect to $node";
$hNode->Open ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", $hKey)
|| die "Cannot open registry !";
$hKey->GetValues (\%values);
$hKey->Close ();
$hNode->Close ();

foreach (keys (%values))
	{
  	print "Value $_, data = $values{$_}[2]\n";
	}

Code to add to /perl5/lib/Win32/Registry.pm

#Hack send by Frederick, Michael
#Cut & Paste this sub in /perl5/lib/win32/registry.pm
#--------------------%<---------%<----------------------------
sub Connect
{
	my $self = shift;

	if( $#_ != 1 )
		{
		die 'usage: Connect( $Node, $ObjRef )';
		}

	local ($Node) = @_;
	local ($Result,$SubHandle);

	$Result = RegConnectRegistry ($Node, $self->{'handle'}, $SubHandle);
	$_[1] = _new( $SubHandle );

	return 0 if (!$_[1] );

	($! = Win32::GetLastError()) if(!$Result);

	# return a boolean value
	return($Result);
}

Remarks

  • Access to HKEY_CLASSES_ROOT and HKEY_CURRENT_USER are not allowed thru RegConnectRegistry.
  • Consciencious administrator may have taken time to restrict or disable remote access to the registry (cf. Q143474).

OpenEx [Custom Function]
Opens the specified key.
Syntax
$object->OpenEx($SubKey,$Filename,$hKey);
$object A part of the registry. See table.
$Sam Security Access Mask. See table.
$hKey Handle of the opened key.

$Sam
KEY_ALL_ACCESS Full access (read, write, delete)
KEY_READ Read-only access
KEY_WRITE Write-only access

Example

use Win32::Registry;
my $Register = "Software\\Netscape";
my $hkey, @key_list, $key;

$HKEY_LOCAL_MACHINE->OpenEx($Register, KEY_ALL_ACCESS ,$hkey)|| die "can't open registry";
$hkey->GetKeys(\@key_list);
print "$Register keys\n";
foreach $key (@key_list)
	{
	print "$key\n";
	}
$hkey->Close();

Code to add to /perl5/lib/Win32/Registry.pm

#Cut & Paste this sub in /perl5/lib/win32/registry.pm
#--------------------%<---------%<----------------------------
sub OpenEx
{
	my $self = shift;

	if( $#_ != 2 ){
		die 'usage: OpenEx( $SubKey, $Sam, $ObjRef )';
	}

	local ($SubKey,$Sam) = @_;
	local ($Result,$SubHandle,$Garbage);
	undef $Garbage;

	$Result = Win32::RegOpenKeyEx($self->{'handle'},$SubKey,$Garbage,$Sam,$SubHandle);
	$_[2] = _new( $SubHandle );

	if (!$_[2] ){
		return 0;
	}

 ($! = Win32::GetLastError()) if(!$Result);

	# return a boolean value
	return($Result);
}

Flush [Custom Function]
Writes all the attributes of the specified open key into the registry.
Syntax
$hkey->Flush( );
$hkey An opened key.

Example

use Win32::Registry;
my $Register = "Software";
my $hkey,$SubKey;

$HKEY_LOCAL_MACHINE->OpenEx($Register,KEY_WRITE,$hkey)|| die "can't open registry";
$hkey->Create("FunStuff",$SubKey);
$hkey->Flush();
$hkey->Close();

Code to add to /perl5/lib/Win32/Registry.pm

#Cut & Paste this sub in /perl5/lib/win32/registry.pm
#--------------------%<---------%<----------------------------
sub Flush
{
	my $self = shift;

	if( $#_ != -1 ){
		die 'usage: Flush( )';
	}

	$Result = Win32::RegFlushKey($self->{'handle'});

 	($! = Win32::GetLastError()) if(!$Result);

	# return a boolean value
	return($Result);
}

Hacks

Extracting subkeys and values of an item in the registry

#Hack send by Roger D. Knapp
#Modified by Philippe Le Berre
#version 1a, 16/7/97

use Win32::Registry;

my ( $Register, $hkey, $key_list, $key, %RegType );

%RegType = (
			0 => 'REG_0',
			1 => 'REG_SZ',
			2 => 'REG_EXPAND_SZ',
			3 => 'REG_BINARY',
			4 => 'REG_DWORD',
			5 => 'REG_DWORD_BIG_ENDIAN',
			6 => 'REG_LINK',
			7 => 'REG_MULTI_SZ',
			8 => 'REG_RESOURCE_LIST',
			9 => 'REG_FULL_RESOURCE_DESCRIPTION',
			10 => 'REG_RESSOURCE_REQUIREMENT_MAP');

$Register = "System\\CurrentControlSet\\Control"; #Where do we start from ?
$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die "$!";
print "$Register\n";
#Loop thru all the keys
&extract_keys($hkey, 2);

#---------------------------------------
#Print spaces
#---------------------------------------

sub print_spaces {
	my($spaces) = $_[0];
	print " " while ($spaces--);
}

#---------------------------------------
#Extract the subkeys of a specified key
#---------------------------------------

sub extract_keys {
	my ($hkey, $spaces) = @_;
	my ($newkey,@key_list,$key);

	&extract_values($hkey,$name,$spaces+2);	#get the values of the current key
	$hkey->GetKeys(\@key_list);   #key the list of its subkeys
	&print_spaces(0);
	foreach $key (@key_list) {	   #loop thru the list
		if ($key ne "") {
			&print_spaces($spaces);
			print " $key\n";
			if ( $hkey->Open($key, $newkey)) #open the subkey
				{
				&extract_keys($newkey, $spaces+2);	#recurse
				}
		}
	}
	$hkey->Close();	   #Clean work !
}

#---------------------------------------
#Extract the values of a specified key
#---------------------------------------
sub extract_values {
	my ($hkey,$key,$spaces) = @_;
	my ($vkey,%value,$RegType,$RegData,$RegValue);

	$hkey->GetValues(\%values);	 #Get hash with the values

	foreach $value (%values) {	 #loop thru the hash
		$RegType 	= $values{$value}->[1];		#Type of the value
		$RegData	= $values{$value}->[2];		#Value
		$RegValue 	= $values{$value}->[0];		#Name of the value

		next if ($RegType eq '');  #do not print default value
		$RegValue = 'Default' if ($RegValue eq '');	#name the default key
		&print_spaces($spaces+2);
		print "$RegValue ($RegType{$RegType})\t:\t";

		SWITCH: {
			($RegType == 3)	&& do {
				@_ = unpack("N*",$RegData);
				foreach $_ (@_) {
					printf "0x%1lx ",$_;
				}
				print "\n";
		 		last SWITCH;
				};

			($RegType == 4)	&& do {
				printf "Ox%1lx (%2ld)\n", unpack("L",$RegData),unpack("L",$RegData);
				last SWITCH;
				};

			($RegType == 5)	&& do {
				printf "Ox%1x", unpack("N",$RegData);
				last SWITCH;
			};
			( $RegType  < 8 ) && do {
				print "$RegData\n";
				last SWITCH;
				};
		 print "\n";
		}
	}
	undef %values;
} 

Searching the registry for a key

#From a hack taken on Robin's pages
#Modified by Philippe Le Berre
#version 0.1, 8/1/96
use Win32::Registry;

print("HKEY_LOCAL_MACHINE ROOT\n");
local($hkey);
$HKEY_LOCAL_MACHINE->Open($objekt, $hkey) || die"Can't open Root $!";
&SearchKey($hkey, '','CentralProcessor','');	  #Example !!! Replace CentralProcessor by whatever you want
$HKEY_LOCAL_MACHINE->Close;

#---------------------------------
#Search for a specific key in the
#Registry, and print it when found
#---------------------------------
sub SearchKey
{
 local($Instanc, $object, $target,$path) = @_;
 local($hkey);
 local(@savedkeys,$Key,$result);

 $Instanc->Open($object, $hkey) || die "can t open $object $!";	#Open the key
 $keys = [];			#Creating a reference to an empty array
 $hkey->GetKeys(\@savedkeys)||die "Can't get keys for $object $!";   #Put the key in the array
 $result = $path.'//'.$object;

 foreach $Key (@savedkeys)   #Recursing thru the key
 	{
  	last if (!defined $Key);

  	if ($Key =~ /$target/)
		{
		print "$result//$Key\n";
		exit;
  		}

  	&SearchKey($hkey,$Key,$target,$result);
  	$result .= '//'.$Key;
 	}
 $hkey->Close;
} 

Dumping the contents of a registry key

#D U M P R E G . P L
#-------------------
#This script will dump the contents of a registry key
#(its #subkeys and values) into a text file that can be read by
#the utility REGINI.EXE.
#
#plb	cosmetic ... close the first key
#roth   	970326	Fixed a problem with reporting the REG_BINARY value.
#roth    	970519
use Win32::Registry;
use Win32;

$Indent = "    ";

$Node 	= Win32::NodeName();				#Retrieve the computer name
$File 	= "Hive.key" unless $File = $ARGV[0];
$Key 	= $ARGV[1] || exit Syntax();

($Computer, $Root, $Key) = ($Key =~ /(\\\\.*?\\){0,1}(HKEY_[^\\]*){0,1}(.*)/i);	 #explode the key
$Computer =~ s/\\$//;															 #retrieve the computer name
($Path, $Key) = ($Key =~ /^\\?(.*)\\(.*?)$/);

if (!$Root)
	{
	$Root = "HKEY_LOCAL_MACHINE";	  #default to the HKEY_LOCAL_MACHINE
	}

print "Dumping:\n\t\"$Root\\$Path\\$Key\"\n";
print "\tfrom machine $Computer...\n" if ($Computer);

$RootKey = $$Root;

if ($Computer)
	{
	if (! $RootKey->RemoteConnect($Computer, $RootKey))	#Try to open the registry of a remote computer
		{
		print "Could not connect to $Computer.\n";
		exit;
		}
	}

$Temp = $RootKey->Open( "$Path\\$Key" , $TheKey); #Open the key
if (!$Temp)
	{
	print "failure.\nCan not open \"$Path\" -- $!\n";
	exit;
	}

if ((open(FILE, ">$File")))
	{
	print FILE "\\Registry\\Machine\\$Path\n";
	$KeyName = ProcessKey($TheKey,  1, $Key);
	$RootKey->Close();
	close(FILE);
	}
else
	{
	print "failure.\nCan not create file : $File -- $!\n";
	}

#---------------------------------------
#Recurse thru each key
#---------------------------------------
sub ProcessKey
{
	my($SubKey, $iLevel, $Key) = @_;
	my(@SubKeys, %Values);
	my($NewKey, $Temp);

	$iTotal++;
	printf( "%03d)%s%s\n", $iTotal, $Indent x $iLevel, $Key);
	print FILE $Indent x $iLevel, "$Key\n";

	if ($iLevel)
		{
		if ($SubKey->GetValues(\%Values)) #Retrieve values of the key
			{		#Dump values
			$iLevel++;
			foreach $Temp (keys(%Values))
				{
				my($PreString) = $Indent x $iLevel . "$Values{$Temp}[0] = "; 	#identation
				($Type, @Data) = ProcessString($Values{$Temp}[1], $Values{$Temp}[2], $iLevel); #Format value
				print FILE "\n$PreString$Type", join( "\\\n" . " " x (length($PreString)
							+ length($Type)), @Data) . "\n";		   #Print out value
				}
			$iLevel--;
			print FILE "\n";
			}
	}

	undef %Values;		#Clear the hash

	if ($SubKey->GetKeys(\@SubKeys)) #Recurse thru sub-keys
		{
		foreach $Temp (@SubKeys)
			{
			if ($SubKey->Open($Temp, $NewKey))
				{
				ProcessKey($NewKey, $iLevel + 1, $Temp);
				}
			}
		$SubKey->Close();
		}

}

#---------------------------------------
#Print a value
#---------------------------------------
sub ProcessString
{
	my($Type, $Data, $iLevel) = @_;
	my(@Data, $Temp, $iTemp, $iLength);

	SWITCH:
		{
		($Type == 0) && do
			{
			last SWITCH;
			};
		($Type == 1) && do
			{
			$Type = "REG_SZ";
			@Data = ($Data);
			last SWITCH;
			};
		($Type == 2) && do
			{
			$Type = "REG_EXPAND_SZ";
			@Data = ($Data);
			last SWITCH;
			};
		($Type == 3)&& do
			{
			$Type = "REG_BINARY";
			$iLength = length($Data);
			push(@Data, sprintf("%x", $iLength));

			$iTemp = int($iLength/4) + (($iLength%4)? 1:0);

			push(@Data, unpack("H8" x $iTemp, $Data));
			for ($Temp = 0; $Temp <= $#Data ; $Temp++)
				{
				$Data[$Temp] = sprintf("0x%08x ", hex($Data[$Temp]));
				}
			last SWITCH;
			};
		($Type == 4) && do
			{
			$Type = "REG_DWORD";
			$Data = sprintf("0x%x", unpack("l", $Data));
			@Data = ($Data);
			last SWITCH;
			};
		($Type == 7) && do
			{
			$Type = "REG_MULTI_SZ";
			@Data = split(/\x00/, $Data);
			for ($Temp = 0; $Temp <= $#Data; $Temp++)
				{
				$Data[$Temp] = "\"$Data[$Temp]\"";
				}
			last SWITCH;
			};
		}

	return ("$Type ", @Data);
}

#---------------------------------------
#Print the syntax
#---------------------------------------
sub Syntax{
print <<EOT;

Syntax: $0 <File> <Key>

	<Key>...........Registry key to be saved.
	<File>..........Path to a file to be created (default to hive.key).

Key can be of the following format:
	[Computer\[Hive]\]Subkey
		Computer....Name of remote computer.
		Hive........Name of Hive (default to HKEY_LOCAL_MACHINE).
		Subkey......Subkey path.

example:
	$0 hive.txt "SOFTWARE\\McAfee"
	$0 hive.txt "HKEY_LOCAL_MACHINE\\SOFTWARE\\McAfee"
	$0 hive.txt "\\\\mich_nt1\\HKEY_LOCAL_MACHINE\\SOFTWARE\\McAfee"

EOT

}

Modification of Registry.pm

The two 95's special HKEY are not mapped by the Registry.pm, here is the the modified code :
@EXPORT = qw(
	HKEY_DYN_DATA
	HKEY_CURRENT_CONFIG
	HKEY_CLASSES_ROOT
	HKEY_CURRENT_USER
# (added)
	HKEY_CURRENT_CONFIG
 	HKEY_DYN_DATA

 .../...

$main::HKEY_CLASSES_ROOT = _new(0x80000000);
$main::HKEY_CURRENT_USER = _new(0x80000001);
$main::HKEY_LOCAL_MACHINE = _new(0x80000002);
$main::HKEY_USERS = _new(0x80000003);
#NT
$main::HKEY_PERFORMANCE_DATA = _new(0x80000004 );
$main::HKEY_PERFORMANCE_TEXT =_new(0x80000050 );
$main::HKEY_PERFORMANCE_NLSTEXT =_new(0x80000060 );
#95
$main::HKEY_CURRENT_CONFIG =_new(0x80000005);
$main::HKEY_DYN_DATA = _new(0x80000006);

Bugs in Registry.pm
The QueryKey methods is bugged, replace them with the following code :
#Modified by Philippe Le Berre, 10/12/96
sub QueryKey
{
	my $self = shift;
	if($#_ != 1 )
		{
		die 'usage: QueryKey( $numberofSubkeys, $numberofVals )';
		}

	local ($Result);
	local ($garbage);
	undef $garbage;

	$Result = RegQueryInfoKey( $self->{'handle'},$garbage,$garbage,$garbage,
				   $_[0],$garbage,$garbage ,
				   ,$_[1] ,$garbage , $garbage,$garbage,$garbage );

 	if(!$Result)
		{
		$! = Win32::GetLastError();
		}
	return($Result);
}

Functions from the Registry API not implemented in Perl for Win32
  • RegQueryMultipleValues


Functions from the Registry API implemented in Perl for Win32
All this function are implemented. But some are not in the Registry.pm, nevertheless you can called them in your script without 'requiring' Win32::Registry but Win32, and by prefixing them with Win32:: (ex: Win32::RegCreateKey, arguments are the sames as in the original API). For a good example look at the install.bat file in the perl directory...BTW you will also find a file called "nt.ph", this file defined all the constants needed when using the registry !
  • RegEnumKeyEx (not in Registry.pm)
  • RegGetKeySecurity (not in Registry.pm)
  • RegSetKeySecurity (not in Registry.pm)
  • RegUnLoadKey (not in Registry.pm)
  • RegRestoreKey (not in Registry.pm)
  • RegReplaceKey (not in Registry.pm)
  • ReqQueryInfoKey (not in Registry.pm)
  • RegNotifyChangeKeyValue (not in Registry.pm)
  • RegEnumValue (not in Registry.pm)
  • RegEnumKey (not in Registry.pm)
  • RegCreateKeyEx (not in Registry.pm)
  • RegQueryValueEx (not in Registry.pm)
  • RegOpenKeyEx (not in standard Registry.pm, see OpenEx)
  • RegConnectRegistry (not in standard Registry.pm, see Connect)
  • RegFlushKey (not in standard Registry.pm, see Flush)
  • RegOpenKey
  • RegCloseKey
  • RegSetValue
  • RegSetValueEx
  • RegCreateKey
  • RegQueryValue
  • RegDeleteKey
  • RegDeleteValue
  • RegLoadKey
  • RegSaveKey
Books

In all these books you will find Perl scripts :

Copyright ©1997-1998 Philippe Le Berre
Any rights not expressly granted herein are reserved.
philippe@le-berre.com