Solved

reading windows regsitry with perl

Posted on 2009-07-09
16
345 Views
Last Modified: 2012-05-07
We have a simple program to read the windows registry:

eval 'use Win32::TieRegistry( Delimiter=>"/");';
 if ($@)
 {
        DEBUG("Could not perform the transaction. Reason is:\n$@\n");
}
$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";
DEBUG(" open ini entries from registry : $error \n");

This fails for any key in the registry with teh exception :
DEBUG:   open ini entries from registry : ERROR , The system cannot find the file specified

Who do i keep getting this?
Any help will be much appreaciated
0
Comment
Question by:ranadhir
  • 8
  • 4
  • 4
16 Comments
 
LVL 9

Expert Comment

by:Suhas .
ID: 24812262
Hi ranadhir,
the attached code worked fine for me...
please check at your end.

Cheers...
Suhas

use Win32::TieRegistry;

$Registry->Delimiter("/");
 

$odbc_content = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";

foreach my $odbc_data (keys(%{$odbc_content}))

    {
 

        $odbc_data=~s/^\/+//sg;

        print "$odbc_data\n";

    }

Open in new window

0
 

Author Comment

by:ranadhir
ID: 24812308
dont you need to declare the 'Registry' variable?
0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24812334
No that is called from the Win32::TierRegistry module...

For more details please refer http://search.cpan.org/~adamk/Win32-TieRegistry-0.26/lib/Win32/TieRegistry.pm

Cheers...
Suhas
0
 

Author Comment

by:ranadhir
ID: 24813393
Not using eval seems to open up the registry.
However for a sub-node if we again go to access  I get problem again.
How do i access the sub-node?

$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";
EMD_PERL_DEBUG(" open ini entries from registry : $error \n");
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
$odbcnode=$key->{$1};//This again gives the same problem
}
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24815323

#!/perl/bin/perl

use strict;

use warnings;

use Data::Dumper;

use Win32::TieRegistry;

$Registry->Delimiter('/');
 

my $key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"}

  or die "Could not get registry entry1: $^E\n";
 

my @members=keys %$key;

foreach (@members){

	print "$_\n";

	next unless /^(.*)\/$/;

	my $odbcnode=$key->{$1};

	print "    " . join("\n    ", keys %$odbcnode) . "\n";

}

Open in new window

0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24815806
since the registry contents are stored in the form of key valyue pairs...
you need to use hashes... to access any entry.
 
0
 

Author Comment

by:ranadhir
ID: 24817944
Bu the constraint here is that I need to use eval to load the win32 module dynamically.
This is part of a code that will be used in both  unix and windows.
Explicitly loading irrespective of platform causes the code to fail in unix - loading via 'eval' causes this particular piece to fail in windows.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24818281
You could load the module through require, which is similar to use but processed at runtime instead of compile time.
You probably would also be better using $^O to determine if you are on windows.

if($^O eq 'MSWin32') {

    require Win32::TieRegistry;

    #Do whatever here with registry

}

else {

    #Non windows, do whatever

}
 
 

#Or, if you want to use the success/failure of loading Win32::TieRegistry:

eval {

    require Win32::TieRegistry;

    #Do whatever here with registry

};

if($@) {

    #There was an error

}

Open in new window

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:ranadhir
ID: 24819935
I have tried usnig eval - please refer to code sample in the question.
And that is what is not working.

If I use 'use' to load at compile time - there are no issues;however it restricts my abilities on unix.

Will it be possible to make the same work with 'eval'?
I do not get any exception during load of win32::TieRegistry,however the registry hit fails with a 'System cannot find the file'
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24820164

The require would be more efficient than the eval with a string using 'use', but if this doesn't bother you, then the eval like you have is fine.

Does the code in post 24815323 work?  I tested it, and it worked on my windows computer fine.  What about if you don't remove the trailing slash from the key name?  Instead of this:
    foreach (@members){
        print "$_\n";
        next unless /^(.*)\/$/;
        my $odbcnode=$key->{$1};
        print "    " . join("\n    ", keys %$odbcnode) . "\n";
    }
Try this:
    foreach (@members){
        print "$_\n";
        next unless /^(.*)\/$/;
        my $odbcnode=$key->{$_};
        print "    " . join("\n    ", keys %$odbcnode) . "\n";
    }
0
 

Author Comment

by:ranadhir
ID: 24820214
No.none is working - they all give compilation/runtime errors

What I am trying now:
my $key="";

my regErr="";
$osType = get_osType();     # get the OS type
if($osType eq "WIN")
{
      require Win32::TieRegistry;
      import Win32::TieRegistry;
      $Registry->Delimiter("/");
      $key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $regErr="ERROR , $^E\n";
      DEBUG(" open odbc  registry  node: $regErr \n");
}

Then I used the 'key' within a sub.
sub getDBConnect()
{
....
.....
if($osType eq "WIN")
{
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
.....
.....
}
}
}

This never works - am yet to find what the problem is .
However,if I  do the following - everything works like a song
use Win32::TieRegsitry;
$Registry->Delimiter("/");

And then within my sub:
sub getDBConnect()
{
my key="";
....
.....
if($osType eq "WIN")
{
$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $regErr="ERROR , $^E\n";
DEBUG(" open odbc  registry  node: $regErr \n");
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
.....
.....
}
}
}

0
 

Author Comment

by:ranadhir
ID: 24820293
What i do find is that it gives
Global symbol '$Registry' requires explicit package name - in the case where i use 'require'.
0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24820328
can you try by placing the require Win32::TieRegistry; at first line of the program...
0
 

Author Comment

by:ranadhir
ID: 24820355
Its all the same - the moment i shift from use win32::TieRegistry to
if($osType eq "WIN")
{
      require Win32::TieRegistry;
      import Win32::TieRegistry;
      $Registry->Delimiter("/");
}
I get symbol resolution erros for $Registry
0
 

Accepted Solution

by:
ranadhir earned 0 total points
ID: 24820463
l will use the fully qualified name now -$Win32::TieRegistry::Registry
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24823938
Sorry, forgot to add that with require, you need to call the import to get the $Registry variable.
    require Win32::TieRegistry;
    Win32::TieRegistry->import();

0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

It is only natural that we all want our PCs to be in good working order, improved system performance, so that is exactly how programs are advertised to entice. They say things like:            •      PC crashes? Get registry cleaner to repair it!    …
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now