HOWTO: Determining the Owner of a Shared Folder

The Outlook 2003 Object Model does not have much support for shared folders outside the GetSharedDefaultFolder function. One common question we get asked is, "Given an OOM MAPIFolder object that represents a shared folder, how can I determine who's the owner of that folder?". This is a common question from Outlook COM AddIn developers who are working with Inspectors and need to know what calendar a user is making changes in.

Like I said before, OOM doesn't have much support for shared folders so we came up with a hack to answer the question. The StoreID of the folder actually will contain the owner's information if you decode the binary string. The following code sample will pull the owner name out of the StoreID of a MAPIFolder object...

public string GetFolderOwner(Outlook.MAPIFolder oFolder)

{

    if (oFolder == null) return "";

    string storeID = oFolder.StoreID;

    return ParseEntryID(storeID);

}

// Convert the EntryID to characters and parse out the

// owner name

private string ParseEntryID(string storeID)

{

    string s = HexReader.GetString(storeID);

    //TODO: These values might be different depending on

    what you have named your groups in ESM

    const string REG_EX = @"/o=First Organization/ou=First

        Administrative Group/cn=Recipients/cn=(\w+)";

    Match m = Regex.Match(s, REG_EX);

    return m.Value;

}

Here is the code for the HexReader class…

/// <summary>

/// Simple class for reading a string containing Hex numbers

/// </summary>

public class HexReader

{

    private HexReader()

    {

        // this class cannot be directly instantiated

    }

    // Given a string containing hex characters

    // this function will return the actual string

    // representation of that hex string

    public static string GetString(string hexString)

    {

        System.Text.StringBuilder sb = new StringBuilder();

        System.Text.StringBuilder sb2 = new StringBuilder();

        for (int i = 0; i < hexString.Length; i = i + 2)

        {

            string s = hexString.Substring(i, 2);

            try

            {

                int j = int.Parse(s, System.Globalization.NumberStyles.HexNumber);

                char c = ConvertToCharacter(j);

                sb.Append(c);

            }

            catch (System.Exception e)

    {

                System.Diagnostics.Debug.WriteLine(e.Message);

            }

        }

        return sb.ToString();

    }

    private static char ConvertToCharacter(int CharCode)

    {

        char ch1;

        if ((CharCode < -32768) || (CharCode > 0xffff))

        {

            // throw error

        }

        if ((CharCode >= 0) && (CharCode <= 0x7f))

        {

            return Convert.ToChar(CharCode);

        }

        try

        {

            int num1;

   // get the current encoding

            Encoding encoding1 = Encoding.GetEncoding(

              Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage);

            if ((encoding1.GetMaxByteCount(1) == 1) &&

              ((CharCode < 0) || (CharCode > 0xff)))

            {

                // throw error

            }

            char[] chArray1 = new char[2];

            byte[] buffer1 = new byte[2];

            Decoder decoder1 = encoding1.GetDecoder();

            if ((CharCode >= 0) && (CharCode <= 0xff))

            {

                buffer1[0] = (byte)(CharCode & 0xff);

                num1 = decoder1.GetChars(buffer1, 0, 1, chArray1, 0);

            }

            else

            {

                buffer1[0] = (byte)((CharCode & 0xff00) / 0x100);

                buffer1[1] = (byte)(CharCode & 0xff);

                num1 = decoder1.GetChars(buffer1, 0, 2, chArray1, 0);

            }

            ch1 = chArray1[0];

       }

        catch (Exception exception1)

        {

            throw exception1;

        }

        return ch1;

    }

}