How to calculate the mailbox hash to construct URL path  
Author Message
GeorgeWangAtSomeCompany





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hello,

It seems WDS is using some hash number in MAPI url to locate items. For example, the text in red :

mapi://LocalHost/default/Mailbox - Wang, George ($d3f5)/

Is it possible to expose the hashing routine so that we can construct the URL from mailbox ENTRYID

Here is a doc about something similiar, http://www.hide-link.com/ , search for "ComputeStoreHash", not sure if they are related somehow

Thanks!



Windows Search Technologies5  
 
 
Paul Nystrom - MSFT





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hello George,

You can find out how to decode the entryid for 2.6.5 here:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=368894&SiteID=1

For 3.0 you will need to look here:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=444282&SiteID=1

Thanks,

Paul Nystrom - MSFT



 
 
David Ing





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hi Paul,

I really think the C++ algorithm examples won't really work for a lot of people. This is about the third request I've seen on this forum, so it's obviously really useful info.

For such an important field it would really help a lot to see some simple C#/VB.NET examples or at least psuedocode outlines

A lot of Office developers are going the way of VSTO/managed code and direct memory/pointers algorithms are not so common, or are a big hurdle for people to grok.

Even if that small example isn't possible info in the interim, hopefully the (upcoming ) SDK for 2.6 and 3.0 would have this sort of information in it Any news on that ship window

Hi GeorgeWang,

Please note that the hash ($d3f5) is an internal WDS value for the Outlook StoreID. You still need to take the preceeding folder name 'Mailbox - Wang, George ' and look up the ID yourself with some MAPI calls within Outlook. The rest of the URL past the last '/' is the item's EntryID, encoded as Paul says.



 
 
GeorgeWangAtSomeCompany





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hi, Paul & David,

Thanks a lot for your information. Actually the thing I'm after is not about ENTYRID encoding/decoding in the URL. I want to know how to get the value of ($d3f5) from the store ENTRYID, because the display name of MAPI store, (e.g., could be "Personal Folders"), is not unique, we need be sure that the correct store is opened.

We also want to config the pathes WDS will crawl via GPO. For that, we also need to build the hash based on a know store ENTRYID.

Thanks

George


 
 
Paul Nystrom - MSFT





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

David - I agree. I'm in the process of getting a c# sample up here.

Paul Nystrom - MSFT



 
 
Paul Nystrom - MSFT





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

David - here is a c# version of the 2.6.5 eid decoder.  We don't have one for 3.0 yet, but it is coming.  As always, I have to say that this code is not something to which Microsoft applies any warranties or support guarantees.  It is just a starting point

Paul Nystrom - MSFT

static string EIDFromEncodedString(string strEIDEncoded)

            {

                  bool fIsOldStyle = true;

 

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

                  {

                        if (!IsHexDecChar(strEIDEncodedIdea))

                        {

                              fIsOldStyle = false;

                              break;

                        }

                  }

 

                  if (fIsOldStyle)

                  {

                        return strEIDEncoded;

                  }

 

 

                  //----------- Decode with YEncode like algorythm -------

                  // decode using pseudo YENC encoding, everything is shifted up by 0x30 starting it at the '0' letter.

                  // Things that wrap have an escape '!' followed by a 0x60 to put it back up to '0' letter range

 

                  System.Diagnostics.Debug.Assert((strEIDEncoded != null) && (strEIDEncoded.Length > 0));

 

//                //LPCWSTR pszSrc = strEIDU;

             

                  // the first WORD is the length of the buffer

                 

//                m_cBytes = *pszSrc++ - 0x30;

           

                  int cBytes = (int) strEIDEncoded[0] - 0x30;

 

                  // add 2 to the size of the buffer since we assume an odd buffer size could lead to a byte being assigned after

                  // the size of the buffer. This is a side-effect of the way we are encoding the buffer

//                AllocateBuffer(m_cBytes+2);

 

                  StringBuilder sbEID = new StringBuilder(cBytes+2);

             

                  // for each WCHAR in unicode string

//                int Len = strEIDU.GetLength();

                  int Len = strEIDEncoded.Length;

 

                  for(int i=1; i < Len; i++)

                  {

                        ulong offset = 0x30;

             

                        // if it's an escaped char

//                      if (*pszSrc == '!')

                        if (strEIDEncodedIdea == '!')

                        {

                              // skip escape char

                              //pszSrc++;

                              i++;

             

                              // offset is now 60

                              offset = 0x60;

                        }

 

                        // restore current WCHAR

                        //*pszDest++ = (WCHAR)(((ULONG)*pszSrc + 0x10000) % 0x10000) - offset;

//                      ulong ulByte = (((ulong)strEIDEncodedIdea + 0x10000) % 0x10000) - offset;

                        ulong ulByte = (((ulong)strEIDEncodedIdea)&0xffff) - offset;

                        char ch = (char)(((ulong)strEIDEncodedIdea &0xffff)+offset);

                        sbEID.AppendFormat("{0:X2}{1:X2}",(ulByte&0x00ff), ulByte >> 8);

                       

                        // advance to next position

                        //pszSrc++;

             

                        //ATLASSERT((DWORD)((LPBYTE)pszDest - (LPBYTE)m_pEntryId) <= (DWORD)(m_cBytes+2));

                  }

 

                  return sbEID.ToString();

            }



 
 
GeorgeWangAtSomeCompany





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hi, Paul,

Could you also give us a routine for calculating the hash code which is appended to the store display name Because the store display names for 2 PST files could be the same, we need to know which one the URL is pointing to..

For example, given the following two sample URLs, we cannot tell which store to open.

mapi://LocalHost/default/Personal Folders ($538e)/

mapi://LocalHost/default/Personal Folders ($48a6)/

Thanks

George


 
 
David Ing





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

It's great that you've done this Paul - good job, I think it will help a few people.

I noticed the forum render managed to mangle the code a little too (Idea for [ i ] ), so here's an update for future cut/paste'rs:

		/// 
		/// ----------- Decode with YEncode like algorythm -------
		/// decode using pseudo YENC encoding, everything is shifted up by 0x30 starting it at the '0' letter.
		/// Things that wrap have an escape '!' followed by a 0x60 to put it back up to '0' letter range
		/// 
		/// 
		/// 
		static string EIDFromEncodedString(string strEIDEncoded)
		{

			int cBytes = (int) strEIDEncoded[0] - 0x30; 

			// add 2 to the size of the buffer since we assume an odd buffer size could lead to a byte being assigned after
			// the size of the buffer. This is a side-effect of the way we are encoding the buffer
			StringBuilder sbEID = new StringBuilder(cBytes+2);

			int Len = strEIDEncoded.Length;

			for(int index=1; index < Len; index++)
			{
				ulong offset = 0x30;

				// if it's an escaped char
				if (strEIDEncoded[index] == '!')
				{
					// skip escape char
					index++;

					// offset is now 60
					offset = 0x60;
				}

				ulong ulByte = (((ulong)strEIDEncoded[index])&0xffff) - offset;

				sbEID.AppendFormat("{0:X2}{1:X2}",(ulByte&0x00ff), ulByte >> 8);			
			}

			return sbEID.ToString();
		}


 
 
Tussh





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Yes David, thanks a lot for c# version ....

I am not able to open an Outlook item using the construct URL ... it has hashed storeid in it. Can you pls give us the c# version of algorithm to calculate store hash which is available on http://blogs.msdn.com/stephen_griffin/archive/2006/05/10/594641.aspx in c++.

I have already posted for the same ... plsss check http://forums.microsoft.com/msdn/ShowPost.aspx postid=815379&isthread=false&siteid=1

Please help me !!!

Thanks in advance ...


 
 
David Ing





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Tussh,

Basically I don't decode the hash, I just ignore it. You can get a storeId by chopping out the bits of the path WDS gives you to get the store's Display Name.

With this you can enumerate through the local store names and bring back the StoreId with the matching full path.

With the StoreId and the decoded EntryId then you can make a MAPI call or use the Outlook Object Model and display/open the item.

While I'm here: Paul N [MSFT] - Is there a chance of getting that C# WDS 3.0 Release version EntryId decoding bit of code too (btw, congrats on the release)



 
 
soc_p





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Could you show a sample of how you went through the returned URL and were able to open it

if you grab the entry id, and pass it through the example algorithim, you get a hex returned value. That doesn't give you the path though... any examples are appreciated. thanks.


 
 
David Ing





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Ok, it's goes something like this (apologies for rough format, but I hope it helps):

//
// We get back from WDS 2.6 this: url := ""mapi://localhost/default/my internet ($855f)/deleted items/H00         P"
//
// So we have the stores 'Display Name' as 'my internet', use that (assuming this index is for just one user/per outlook)
//
int endSliceIndex = url.IndexOf(" ($"); 
int startSliceIndex = url.IndexOf("default/") + "default/".Length ;
string storeIdName = url.Substring(startSliceIndex, endSliceIndex - startSliceIndex) ;
// Just do this once (not like here), i.e. store up the local store id's display names
storeIds = new ArrayList();for(int i=1; i < _app.Session.Folders.Count; i++ )
{
 storeIds.Add(_Outlookapp.Session.Folders[ i ].Name + ";" + _Outlookapp.Session.Folders[ i ].StoreID);
}
// Now get the storeId matchup from the URLstoreID = null;
foreach(string s in storeIds){ string [] bits = s.Split(';');
 if (bits[0] == storeIdName) {  storeID = bits[1];  break; }}
// The algorithm to decode the packed entryId bits is above in the thread...
string encodedBits = url.Substring(url.LastIndexOf('/') + 1) ;
entryID = EIDFromEncodedString(encodedBits);
// Get the outlook object with our Id's
object item = _Outlookapp.Session.GetItemFromID(entryID, storeId) ;
// Bring up the Outlook inspector window for this thing...
Utils.OLLateBoundMethodHelper(item, "Display", null); // Um, Utils is a latebound Outlook .Display() call...


 
 
sgibson





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Hi, Paul,

Could you also give us a routine for calculating the hash code which is appended to the store display name Because the store display names for 2 PST files could be the same, we need to know which one the URL is pointing to..

For example, given the following two sample URLs, we cannot tell which store to open.

mapi://LocalHost/default/Personal Folders ($538e)/

mapi://LocalHost/default/Personal Folders ($48a6)/

Thanks

George

I second George's request. While it may be possible to iterate through 10 message stores all named "Personal Folders" until you hit on the one containing the full path to the message EntryID specified in the URL, it's an ugly solution. For instance, I will have a tree-view (already populated) with the folder hierarchy of the message stores in a given outlook profile, and it would be nice to be able to drill directly down into the correct path using the hash value specified in the WDS URL.

So (please!) would it be possible to provide some example C# code that calculates this hash value

Thanks!

-Steve


 
 
sgibson





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

David,

That methodology doesn't work when you have 6 PSTs loaded into a profile that all have the display name of "Personal Folders". For instance, say you have URLs in your WDS hit results that look like:

mapi://LocalHost/Default/Personal Folders ($86d4)/Development/H00 匿 倰? b

mapi://LocalHost/Default/Personal Folders ($11c1)/Development/H00 匿 倰? b

mapi://LocalHost/Default/Personal Folders ($4391)/Development/H00 匿 倰? b

mapi://LocalHost/Default/Personal Folders ($7966)/Development/H00 匿 倰? b

mapi://LocalHost/Default/Personal Folders ($1e64)/Development/H00 匿 倰? b

mapi://LocalHost/Default/Personal Folders ($4522)/Development/H00 匿 倰? b

If you simply chop out the display name of each store and stick it in an array, you end up with an array containing duplicate values. Then you assume that because you've found "mapi://LocalHost/Default/Personal Folders" that you are in the right store when, in fact, there are several other stores that have this exact same path. To differentiate between stores with the same display name we need to be able to calculate the hash value that is provided in the URL so that we can be certain that we are diving into the proper store.

-Steve


 
 
David Ing





PostPosted: Windows Desktop Search Development, How to calculate the mailbox hash to construct URL path Top

Steve,

You're correct - for my solution I was lucky enough not to have multiple profiles, but I do see your point.

Given that a MAPI storeID is so long, I can't see how a 4 byte ($FD13) type value could be an encoded hash.

My best guess is that it's an index lookup and some aliases must be stored 'somewhere'.

Sysinternals FileMon/RegMon time