More Outlook Resource Sites

Microsoft Developer Network (MSDN)

FAQs and other general resources

share code 18-Sep-2014 18:45

Looking for help with Outlook programming projects — VSTO, add-ins, VBA, custom Outlook forms, etc.? You′ve come to the right place!

NEW! >> Subscribe to this site via RSS. For more RSS options, see the complete list of feeds on our main news page.

Login Password
Remember me
Register | Send my password
Code level: advanced    Code area: Outlook Expert Techniques Printer Friendly Version
Title: Get PST file path string
Description: This GetStorePath procedure extracts the path to a Personal Folders .pst file (or store used for IMAP, HTTP or SharePoint data) from the information embedded in the StoreID.
Date: 16-Nov-2006  08:53
Code level: advanced
Code area: Outlook Expert Techniques
Posted by: Sue Mosher
This message is displayed as VB.NET
 Function GetStorePath(strStoreID As String)
    Dim intStart As Integer
    Dim intEnd As Integer
    Dim strProvider As String
    Dim strPathRaw As String
    intStart = InStr(9, strStoreID, "0000") + 4
    intEnd = InStr(intStart, strStoreID, "00")
    strProvider = _
      Mid(strStoreID, intStart, intEnd - intStart)
    strProvider = Hex2ToString(strProvider)
    Select Case LCase(strProvider)
        Case "mspst.dll", "pstprx.dll"
            intStart = InStrRev(strStoreID, "00000000") + 8
            strPathRaw = Mid(strStoreID, intStart)
            GetStorePath = Trim(Hex4ToString(strPathRaw))
        Case "msncon.dll"
            intStart = InStrRev(strStoreID, _
                                "00", Len(strStoreID) - 2) + 2
            strPathRaw = Mid(strStoreID, intStart)
            GetStorePath = Trim(Hex2ToString(strPathRaw))
        Case "emsmdb.dll"
            GetStorePath = "Exchange store"
        Case Else
            GetStorePath = "Unknown store path"
    End Select
End Function

Public Function Hex4ToString(Data As String) As String
    Dim strTemp As String
    Dim strAll As String
    Dim i As Integer
    For i = 1 To Len(Data) Step 4
        strTemp = Mid(Data, i, 4)
        strTemp = "&H" & Right(strTemp, 2) & Left(strTemp, 2)
        strAll = strAll & ChrW(CDec(strTemp))
    Next
    Hex4ToString = strAll
End Function

Public Function Hex2ToString(Data As String) As String
    Dim strTemp As String
    Dim strAll As String
    Dim i As Integer
    For i = 1 To Len(Data) Step 2
        strTemp = "&H" & Mid(Data, i, 2)
        strAll = strAll & ChrW(CDec(strTemp))
    Next
    Hex2ToString = strAll
End Function
All 44comments
Page [ 1 2 3 4 5 Next >>  
  16-Nov-2006  08:56   
Notes on the code:

1) To test the GetStorePath function, you can use this VBA procedure, which prints details of each store to the Immediate window:

Sub EnumStorePaths()
    Dim fld As Outlook.MAPIFolder
    Dim strPath As String
    On Error Resume Next
    For Each fld In Application.Session.Folders
        strPath = GetStorePath(fld.StoreID)
        Debug.Print fld.Name, strPath
    Next
End Sub

2) The Hex4ToString and Hex2ToString helper functions can be useful in other situations where you need to decode Unicode (Hex4ToString) or ASCII (Hex2ToString) string data that has been encoded as hex.
  22-Nov-2006  23:56   
Sue,

Respect for your code. I find it VERY useful at this time for the migration we are doing. Still I have a problem. Do you know what the identifier is for 97 compatible PST files? I have found that I can convert the path with the Hex2ToString function, but I don't know how to identify if a store is 97 compatible or 2003. I do see the amount of zeros between provider and the path, but is this the correct way to identify?

Please let me know if you do or don't know the answer. I need it pretty badly ;-)

Thanks again
  23-Nov-2006  08:40   
That information is *much* easier to access, because it's available from the PR_STORE_SUPPORT_MASK (0x340D0003) MAPI property, which is a bitmask property; see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mapi/html/1068bfa6-94a4-4720-b187-f5aec75a0ebc.asp . Once you return the value of that property with CDO 1.21 or Redemption, check it like this:

Const STORE_UNICODE_OK = 262144
If lngStoreSupportMask Or STORE_UNICODE_OK = STORE_UNICODE_OK Then
    MsgBox "It's Unicode!"
End IF
  23-Nov-2006  15:30   
I don't know too much about CDO or Redemption, but this should be installed first, correct? (I've tried to use CDO but I don't have MAPI.Session installed) So I rather not use it. Can't I identify 97 / 2003 by checking the StoreID?

I only need to know when it is 97, so that I can modify your GetStorePath function so it will display the paths for these PST types correctly.

Thanks for your help Sue
  23-Nov-2006  17:03   
Yes, CDO must be installed. In Outlook 2003, rerun Office setup.

Feel free to hack at the StoreID all you want on your own. I don't have time to fool around with it, given that there is a surefire method available.
  23-Nov-2006  17:17   
Thanks Sue,

Yes I did create the following hack. It seems valid enough (so far so good). Because I'm in a hurry I don't have time for a decent solution.
----------------------------------------------------------------------------------------------
Function GetStorePath(strStoreID As String)
    Dim intStart As Integer
    Dim intEnd As Integer
    Dim strProvider As String
    Dim strPathRaw As String
    intStart = InStr(9, strStoreID, "0000") + 4
    intEnd = InStr(intStart, strStoreID, "00")
    strProvider = _
      Mid(strStoreID, intStart, intEnd - intStart)
    strProvider = Hex2ToString(strProvider)
    Select Case LCase(strProvider)
        Case "mspst.dll", "pstprx.dll"
            If Right(strStoreID,6)="000000" Then
                '2003
                intStart = InStrRev(strStoreID, "00000000") + 8
                strPathRaw = Mid(strStoreID, intStart)
                GetStorePath = Trim(Hex4ToString(strPathRaw))
            Else
                '97
                intStart = InStrRev(strStoreID, "000000") + 6
                strPathRaw = Mid(strStoreID, intStart)
                GetStorePath = Trim(Hex2ToString(strPathRaw))
        Case "msncon.dll"
            intStart = InStrRev(strStoreID, _
                                "00", Len(strStoreID) - 2) + 2
            strPathRaw = Mid(strStoreID, intStart)
            GetStorePath = Trim(Hex2ToString(strPathRaw))
        Case "emsmdb.dll"
            GetStorePath = "Exchange store"
        Case Else
            GetStorePath = "Unknown store path"
    End Select
End Function

Public Function Hex4ToString(Data As String) As String
    Dim strTemp As String
    Dim strAll As String
    Dim i As Integer
    For i = 1 To Len(Data) Step 4
        strTemp = Mid(Data, i, 4)
        strTemp = "&H" & Right(strTemp, 2) & Left(strTemp, 2)
        strAll = strAll & ChrW(CDec(strTemp))
    Next
    Hex4ToString = strAll
End Function

Public Function Hex2ToString(Data As String) As String
    Dim strTemp As String
    Dim strAll As String
    Dim i As Integer
    For i = 1 To Len(Data) Step 2
        strTemp = "&H" & Mid(Data, i, 2)
        strAll = strAll & ChrW(CDec(strTemp))
    Next
    Hex2ToString = strAll
End Function
 
  15-Jan-2007  16:41   
Here's a C# version of the code if anyone needs it.



private static string GetStorePath( string storeID )
        {
            int iStart = storeID.IndexOf( "0000", 9 ) + 4;
            int iEnd = storeID.IndexOf( "00", iStart );
            string strPathRaw = string.Empty;
            string strProvider = storeID.Substring( iStart, iEnd - iStart );
            strProvider = HexToString( strProvider, 2 );

            switch ( strProvider.ToLower() )
            {
                case "mspst.dll":
                case "pstprx.dll":
                    iStart = storeID.LastIndexOf( "00000000" ) + 8;
                    strPathRaw = storeID.Substring( iStart );
                    strPathRaw = HexToString( strPathRaw, 2 );
                    break;
                case "msncon.dll":
                    iStart = storeID.LastIndexOf( "00" ) + 2;
                    strPathRaw = storeID.Substring( iStart );
                    strPathRaw = HexToString( strPathRaw, 2 );
                    break;
                case "emsmdb.dll":
                    strPathRaw = "Exchange";
                    break;
                default:
                    strPathRaw = "Unknown";
                    break;
            }
            return strPathRaw;
        }

        private static string HexToString( string value, int step )
        {
            string retVal = string.Empty;
            for ( int i = 0; i < value.Length; i = ( i + step ) )
            {
                string tempRepStr = value.Substring( i, step );
                int tempRepDec = int.Parse( tempRepStr, System.Globalization.NumberStyles.HexNumber, null );
                if ( tempRepDec > 0 )
                {
                    char tempRecChr = Convert.ToChar( tempRepDec );
                    retVal += tempRecChr.ToString();
                }
            }
            return retVal;
        }
  15-Jan-2007  17:50   
Derik, I can just barely read C#, much less write it, so I really appreciate your posting a C# version!
  13-Feb-2007  18:06   
Sue, no problem at all. I love giving back to the community. I'm probably shooting myself in the foot but if you recieve requests for code translated into C# I'd be happy to help out with that.
  19-Feb-2007  15:52   
Using the script above, I'd like to replace "Debug.Print fld.Name, strPath" so that the information writes to a txt file instead -- what would the syntax be for example to save to C:\Data\%username%.txt -- "%username%" being the user logged into the system; we are using Active Directory.
Page [ 1 2 3 4 5 Next >>