use Win32::TieRegistry; $PSTGuidLocation = "01023d00"; $MasterConfig = "01023d0e"; $PSTCheckFile = "00033009"; $PSTFile = "001f6700"; $keyMaster = "9207f3e0a3b11019908b08002b2a56c2"; $ProfilesRoot = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles"; $DefaultOutlookProfile = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles"; $DefaultProfileString = "DefaultProfile"; $defaultProfile = $Registry->{"CUser\\$ProfilesRoot\\$DefaultProfileString"}; print "\nDefault Profile: $defaultProfile\n\n"; $profileName = $Registry->{"CUser\\$ProfilesRoot\\$defaultProfile\\"}; $" = "\n"; @thePSTList = GetPSTsForProfile(); print "@thePSTList"; sub GetPSTsForProfile{ #This will fetch the $MasterConfig key where the location of pstfiles is stored. my @valueNames = $Registry->{"CUser\\$ProfilesRoot\\$defaultProfile\\$keyMaster"}->GetValue($MasterConfig); #get the data out of the list the above line returned. $strValue = @valueNames[0]; #this line of code does a lot -> # 1. The call to unpack use's the H* Template to turn everything in $strValue into a large Hex String. # 2. The call to split breaks it up into an array of 3 strings, but leaves some entries that are just # white space. # 3. The call to grep prunes out the whitespace and anything that isn't 16 binary digits # by matching array elements that are 32 characters long (since each character is a # binary digit. # 4. All done, we now have the contents of the '01023d0e' registry value in a convient List my @hex = grep ( /.{32}?/, split(/(.{32,}?)/, unpack('H*', "$strValue") ) ); foreach $pstLocString (@hex) { #If IsAPST(r_ProfilesRoot & "\" & p_profileName & "\" & strPSTGuid) Then #if it's not a PST, skip it. if ( !IsAPST($ProfilesRoot . "\\" . "$defaultProfile" . "\\" . $pstLocString) ){ next; }#end if. $curPSTLocation = PSTLocation("$ProfilesRoot\\$defaultProfile\\$pstLocString"); push(@pstPathList, PSTFileName("$ProfilesRoot\\$defaultProfile\\$curPSTLocation") ); }#end foreach return @pstPathList; }#end sub GetPSTsForProfile. sub IsAPST { #copy the function parameter into a scalar for readability. $PSTGuid = $_[0]; #Get the key from the registry that indicates whether this is a pst or not. my @valueNames = $Registry->{"CUser\\$PSTGuid"}->GetValue($PSTCheckFile); # Just like before in the main GetPSTsForProfile function, this does a lot... # 1. The call to unpack use's the H* Template to turn everything in $strValue into a large Hex String. # 2. The call to split breaks everything up into binary digits # i.e. it makes a list with every two characters from the Hex String as an element. # 3. The call to grep discards any elements that are just blank space. @PSTGuildValue = grep ( /./, split( /(.{2,}?)/, unpack( 'H*', @valueNames[0] ) ) ); # Finally, if the first element of @PSTGuildValue equals 20, it's TRUE that this is a PST, otherwise it's false. # return accordingly. return @PSTGuildValue[0] == "20"; }#end sub IsAPST sub PSTLocation { #copy the function parameter into a scalar for readability. $PSTGuid = $_[0]; my @valueNames = $Registry->{"CUser\\$PSTGuid"}->GetValue($PSTGuidLocation); $PSTlocation = unpack( 'H*', @valueNames[0] ); return "$PSTlocation"; }#end sub PSTLocation sub PSTFileName { $pstLocationString = ""; #oReg.GetBinaryValue HKEY_CURRENT_USER,p_PSTGuid,r_PSTFile,P_PSTName #copy the function parameter into a scalar for readability. $PSTGuid = $_[0]; #This fetches the file name data out of the registry and stores it into @valueNames. my @valueNames = $Registry->{"CUser\\$PSTGuid"}->GetValue($PSTFile); # @valueNames[0] has the path, but there are extra spaces between every character that are added # into the registry. Ths splits the @valueNames string into the @pstChars list, so we now have # a list with every character of the path (and each of those extra spaces) as an element. @pstChars = split(//, @valueNames[0] ) ; #This for loop selects every other item in the @pstChars array, since every other item is a valid character # and the items in between are worthless spaces added into the registry. # each element is stored in $pstLocationString. for ($i = 0; $i < (@pstChars - 1); $i += 2){ $pstLocationString .= $pstChars[$i] }#end for loop #for the sake of completeness, removing any trailing spaces. $pstLocationString =~ s/\W+$//; return $pstLocationString; }#end sub PSTFileName #this is a debugging function, it prints the keys of a hash, and gets used for printing the hash returned by calls to # $Registry->... sub printRegKey{ foreach $myKey (keys %{ $_[0] } ){ print "$myKey\n"; }#end for Each. }#end sub printRegKey