Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re^2: Easy way to get the location of Outlook PSTs into my perl script?

by rsilvergun (Acolyte)
on Jun 10, 2007 at 00:53 UTC ( [id://620231]=note: print w/replies, xml ) Need Help??


in reply to Re: Easy way to get the location of Outlook PSTs into my perl script?
in thread Easy way to get the location of Outlook PSTs into my perl script?

Wow, thanks :). That's amazing that you could do that. Wish I'd checked back sooner, since I just re-wrote it myself too :) lol. I haven't written code in ages, so your version is much nicer (and probably less prone to exploading :) ). I know from the link NetWallah posted that different versions will do different things though (thanks, NetWallah, btw :) ). At anyrate, here's the ( pretty ugly ) I came up with:
use Win32::TieRegistry; $PSTGuidLocation = "01023d00"; $MasterConfig = "01023d0e"; $PSTCheckFile = "00033009"; $PSTFile = "001f6700"; $keyMaster = "9207f3e0a3b11019908b08002b2a56c2"; $ProfilesRoot = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Wind +ows 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 pstfi +les is stored. my @valueNames = $Registry->{"CUser\\$ProfilesRoot\\$defaultProfil +e\\$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 i +n $strValue into a large Hex String. # 2. The call to split breaks it up into an array of 3 strings, bu +t 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*', "$strVa +lue") ) ); foreach $pstLocString (@hex) { #If IsAPST(r_ProfilesRoot & "\" & p_profileName & "\" & strPST +Guid) 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 ps +t or not. my @valueNames = $Registry->{"CUser\\$PSTGuid"}->GetValue($PSTChec +kFile); # Just like before in the main GetPSTsForProfile function, this do +es a lot... # 1. The call to unpack use's the H* Template to turn everything i +n $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 S +tring as an element. # 3. The call to grep discards any elements that are just blank sp +ace. @PSTGuildValue = grep ( /./, split( /(.{2,}?)/, unpack( 'H*', @val +ueNames[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($PSTGuid +Location); $PSTlocation = unpack( 'H*', @valueNames[0] ); return "$PSTlocation"; }#end sub PSTLocation sub PSTFileName { $pstLocationString = ""; #oReg.GetBinaryValue HKEY_CURRENT_USER,p_PSTGuid,r_PSTFile,P_PSTNa +me #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 ex +tra spaces) as an element. @pstChars = split(//, @valueNames[0] ) ; #This for loop selects every other item in the @pstChars array, si +nce 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
  • Comment on Re^2: Easy way to get the location of Outlook PSTs into my perl script?
  • Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://620231]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-19 02:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found