# 
# $Header: winRegistry.pl 19-aug-2005.09:35:58 jstone Exp $
#
# winRegistry.pl
# 
# Copyright (c) 2004, 2005, Oracle. All rights reserved.  
#
#    NAME
#      winRegistry.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    jstone      08/11/05 - fix variable declaration 
#    jstone      06/02/05 - adds use strict 
#    dkapoor     02/19/04 - include asm win instance 
#    dkapoor     02/18/04 - dkapoor_bug-3441409_main 
#    dkapoor     02/16/04 - Creation
# 
use strict;

require "$ENV{EMDROOT}/sysman/admin/scripts/semd_common.pl";
require "$ENV{EMDROOT}/sysman/admin/scripts/emd_common.pl";
if(get_osType() eq 'WIN')
{
  use Win32API::Registry qw( :ALL ); 
  use Win32::TieRegistry;
  $Registry->Delimiter("/");
}

#Discovery LOG CATEGORY
my $LOG_CATEGORY = "DB_LISTENER_DISCOVERY: ";

sub getValue
{
 my ($root,$keyString,$valeString) = @_; 
 my $type;
 my $data;
 my $key;
 if(RegOpenKeyEx( $root, $keyString, 0, KEY_READ, $key ))
 {
  RegQueryValueEx( $key, $valeString,  [], $type, $data, [] );
  RegCloseKey( $key );
 }
 return $data;
}

sub enumerateKeys
{
 my ($root,$keyString) = @_; 
 my $key;
 my @keys;
 if(!RegOpenKeyEx( $root, $keyString, 0, KEY_READ, $key ))
 {
        EMD_PERL_WARN("$LOG_CATEGORY cannot open $root\\$keyString =".regLastError()."\n");
	return @keys;
 }

 my $iIndex = 0;
 my $sName;
 my $lastFound = 0;
 do
 {
	if(!RegEnumKeyEx( $key, $iIndex, $sName, [], [], [], [], [] ))
	{
	 $lastFound = 1;
	}
	else
	{
		$iIndex ++;
		push(@keys,$sName);
	}
 }while(!$lastFound);
 return @keys;
}

#Get Sids and associated Oracle Homes for NT
#Returns Sids and associated Oracle Homesreferences
#SidRef---> Hash of SID and its Home like 
#     { 
#         "orcl817" =>"d:\\oracle817",
#         "orcl92" =>"d:\\oracle92"
#     }  
# THIS IS AN OS DEPENDENT Function.
sub getServicesEntriesNT
{
  my %sids;
  my $servicesKeyName = "LMachine/SYSTEM/CurrentControlSet/Services";
  my @servicesKeys= enumerateKeys(HKEY_LOCAL_MACHINE, 
			"SYSTEM\\CurrentControlSet\\Services");
  if(defined @servicesKeys)
  {
    foreach my $k (@servicesKeys) 
    {
      if($k =~ /^OracleService(.+)/i || $k =~ /^OracleASMService(.+)/i)
      {
        my $sid = $1;
        my $oracleHome= $Registry->{"$servicesKeyName/$k/ImagePath"}
      	    or  EMD_PERL_WARN("$LOG_CATEGORY Can't find the Image path for sid \"$sid\": $'\n");
        my $quotedSid = quotemeta($sid);
        EMD_PERL_WARN("$LOG_CATEGORY Check is oh=[$oracleHome] is valid for sid [$sid]\n");  
        if( 
	   defined $oracleHome 
	   && $oracleHome =~  /(.+)\\.*\\.*\s+$quotedSid/i
	   )
        {
          $oracleHome = $1;
	  if( -d $oracleHome)
	  {	
	          $sids{uc ($sid)} = $oracleHome;
		  EMD_PERL_DEBUG("$LOG_CATEGORY Found sid=$sid for OH=$oracleHome");
	  }
	  else
	  {
		  EMD_PERL_DEBUG("$LOG_CATEGORY OH=$oracleHome for sid=$sid DOES not exists");
	  }	
        }
      }
    }
  }
  return %sids;
}

sub getOracleHomesNT
{ 
  my @oracleHomes;
  my $oracleKeyName = "LMachine/Software/Oracle";
  my @oracleKeys= enumerateKeys(HKEY_LOCAL_MACHINE, 
			"Software\\Oracle");
  if(defined @oracleKeys)
  {
    foreach my $k (@oracleKeys) 
    {
      my $oHomeKey;
      if($k =~ /^KEY_(.+)/i || $k =~ /^HOME(.+)/i)
      {
        $oHomeKey = $k; #10g Onwards or #pre 10g
      }
      if(defined $oHomeKey)
      {
        my $oracleHome= $Registry->{"$oracleKeyName/$oHomeKey/ORACLE_HOME"}
        	  or  EMD_PERL_WARN("$LOG_CATEGORY Can't find the oracle home for $oracleKeyName/$oHomeKey/ORACLE_HOME: $^E\n");
        if(defined $oracleHome && (-d $oracleHome) )
        {
          EMD_PERL_DEBUG("$LOG_CATEGORY registry value [$oracleKeyName/$oHomeKey/ORACLE_HOME]= $oracleHome");
          my $addHome = 1; 	
          foreach my $oHome (@oracleHomes)
          {
       	    if($oHome eq $oracleHome)
       	    {
  	      $addHome = 0;			
	      last;
	    }
          }
          if($addHome)
          {		
  	    push(@oracleHomes,$oracleHome);	
	    EMD_PERL_DEBUG("$LOG_CATEGORY Found OH=$oracleHome");
          }
        }
      }
    }
  }
  return @oracleHomes;
}

1;
