Click here to Skip to main content
15,867,308 members
Articles / Web Development / XHTML
Article

Internet Explorer Favorites, deconstructed

Rate me:
Please Sign up or sign in to vote.
4.83/5 (19 votes)
24 Dec 2007CPOL6 min read 140K   746   62   23
Description of the binary format used to store internet explorer favorites, includes Favorites-to-XBEL example project.

Download Favorites2XBEL.zip - visual studio 2008 solution - 20 KB

Download Favorites2XBELvs2005.zip - visual studio 2005 solution - 20 KB

Introduction

This article contains the information I have gathered on how and where Internet Explorer stores its bookmarks, or 'Favorites' in Microsoft terms.

Background

In my quest to write the ultimate bookmark synchronizer I ran into a problem: Microsoft doesn't offer an API to access the explorer bookmarks structure. While a large part of the bookmark information is available in easy to read formats, the order in which the bookmarks appear in the favorites menu is stored in a binary format in the registry. A search on the internet reveals a few people that have decoded (part of) this structure, and I wanted to add my findings here.

How to start

IE favorites are stored in a directory structure below the 'favorites' folder. This folder can be found by reading the 'Favorites' value in the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders. Alternatively, in .NET you can call Environment.GetFolderPath(Environment.SpecialFolder.Favorites) to retrieve the path. The favorites folder contains '.URL' files, optionally arranged in a directory structure that reflects the menu structure of your IE favorites.

URL files

URL files (extension: .url) are good old .INI files that contain the target address of a favorite. The name of the url file without the extension is how the bookmark appears in the favorites menu. Here is the content of a bookmark to the codeproject site:
[DEFAULT]
BASEURL=http://www.codeproject.com/
[InternetShortcut]
URL=http://www.codeproject.com/
IDList=
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2

As you can see, the codeproject address is stored twice in this URL. However, only the second one is used when visiting a favorite site. The first one (key BASEURL, section DEFAULT) merely stores the original address of the page when it was added as a favorite. Any subsequent edits of the favorite will only modify the key URL, section InternetShortCut.

Ordering

Now for the tricky part: IE stores the menu order of the URLs and folders in a totally different way, namely the registry. This adventure starts at the registry-key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites. This key contains a binary type (REG_BINARY) value 'Order', which is a kind of table that contains ordered records that point to URL files or folders. For every favorites sub-folder on the filesystem there's also a corresponding registry key below the "..\MenuOrder\Favorites" key, each of which contains another 'Order' table. The following screenshots clearly demonstrate the mirroring of the favorites' filesystem structure and the registry structure.

favorites filesystem structure

favorites registry structure

Order table format

An order table is a binary format table. Its basic structure is as follows:
MenuOrderTable = MenuOrderTableHeader,  { MenuOrderRecord }
MenuOrderRecord = MenuOrderRecordHeader, SubRecord0, Filler
SubRecord0 = SubRecord0Header, "short folder or url filename and various other information", SubRecord1
SubRecord1 = SubRecord1Header, "long folder or url filename and various other information"
(note that {..} means: repeat zero or more times)
The exact binary format is given in the following tables:

MenuOrderTable
Field lengthField typeValueDescription
4UInt320x00000008Header ID, always 8
4UInt320x00000002Header ID, always 2
4UInt32xTotal length of the payload that follows, including the 4 bytes of this field
4UInt320x00000001Unknown, always 1
4UInt32NumberOfRecordsThe number of MenuOrder records that follow
NumberOfRecords * nMenuOrderRecordSee below'NumberOfRecords' times the MenuOrderRecord structure

MenuOrderRecord
Field lengthField typeValueDescription
4UInt32xTotal length of this record upto and including the filler bytes. Also includes the 4 bytes of this field
4Int32ordernumberNumber that determines the display order of this entry, or -5 when the entry is unordered
variableSubRecord0See belowSubRecord that contains the type, length, name of the menuorder entry
6byte[6]0filler, all zero

SubRecord0
Field lengthField typeValueDescription
2UInt16xTotal length of this record, including the 2 bytes of this field
2UInt16Flags:
Bit 0 : 1 => it's a folder, 0 otherwise
Bit 1 : 1 => it's an URL, 0 otherwise
Bit 2 : 1 => short 8.3 filename is stored in unicode format, 0 => short name is stored using ASCII
4UInt32?Unknown
4UInt32?Might be the 'last visited' date, is updated everytime you visit this link. Unknown encoding.
2UInt160x20, 0x10 or 0x11Flags:
Bit 0 : 1 => the long filename in SubRecord1 is followed by a string that points to a resource string
Bit 4 : 1 => it's a folder, 0 otherwise
Bit 5 : 1 => it's an URL, 0 otherwise
variable (even number)zero-terminated ascii or unicode string, depending on the FlagsZero-terminated 8.3 style folder name or url name. This field is padded with zeros to contain an even number of bytes.
variableSubRecord1See belowSubRecord that contains the long unicode name of this menuorder entry

SubRecord1
Field lengthField typeValueDescription
2UInt16xTotal length of this record, including the 2 bytes of this field
36 on vista
18 on XP/2003
byte[]?Unknown purpose
variablezero-terminated unicode stringvariablelong name of the folder or URL
variablezero-terminated unicode stringvariableoptional field: examine bit 0 of the second 'flags' field in SubRecord0 to see if this field is present or not.
This string points to a resource string located in a DLL, and is formatted like this: @shell32.dll,-12693
2UInt16variablelocation (byte-index) of SubRecord1 within SubRecord0

How to use

When reading the above information, you are probably only interested in the following bits of information:

  • is it a folder or URL
  • the ordering number
  • the long filename

Caveat

Please note that this information is the result of reverse engineering.. I have only verified these structures on XP and Vista. You should also be aware of the structure differences between Vista and XP: on Vista, the 'unknown' byte array in SubRecord1 has a different size than on XP.

The code

I have condensed the information above into a class called FavoritesNode that allows you to load and examine the internet favorites of the current user. FavoritesNode implements IList<FavoritesNode>, so it's actually a tree of sorts. Every node in this tree is either a 'folder' or 'url'.

How to use

The following example shows how you would load the favorites and print the top-level bookmarks:

C#
...
using CodeProject.IEFavDecon;
...
FavoritesNode node = FavoritesNode.LoadRoot();

foreach(FavoritesNode child in node)
{
    if(child.NodeType == FavoritesNodeType.Url)
    {
        Console.WriteLine("Name: {0}, Url: {0}", child.DisplayName, child.Url);
    }
}

XBEL: XML Bookmark Exchange Language

The project in the attached zip does something slightly more useful: it loads your favorites and writes them to an XBEL formatted XML file (which is the bookmark format that Microsoft should have been using by now). Once you have your bookmarks in XML format its easy to transform them into webpages, import or export them, merge, sort, etcetera.
As an example, the main program file contains a commented-out section that shows how you can apply a stylesheet to transform the generated XML bookmarks into a nice indented HTML file.

Other resources

The following links contain bits and pieces on this subject that were very helpful during my research:

History

  • Dec 19, 2007 : Initial release
  • Dec 22, 2007 : Added sample code, updated text & resource links
  • Dec 24, 2007 : Added vs2005 version of the solution

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Boris Gjenero9-Dec-15 11:27
Boris Gjenero9-Dec-15 11:27 
BugProblems I had Pin
Boris Gjenero9-Dec-15 11:26
Boris Gjenero9-Dec-15 11:26 
GeneralRe: Problems I had Pin
jpmik6-Jan-16 13:15
jpmik6-Jan-16 13:15 
QuestionError in LoadFolderNodeFromRegistry method Pin
Member 1081340716-Jun-15 17:25
Member 1081340716-Jun-15 17:25 
Generalworks fine in W7 64, IE9, .NET 4.0, VS 2010 Pro ... thanks again ! Pin
BillWoodruff11-Jun-11 3:38
professionalBillWoodruff11-Jun-11 3:38 
GeneralGreat article, but no thanks to LoadFolderNodeFromRegistry [modified] Pin
Adrian Alexander15-Feb-11 11:47
Adrian Alexander15-Feb-11 11:47 
GeneralRe: Great article, but no thanks to LoadFolderNodeFromRegistry Pin
jpmik15-Feb-11 12:00
jpmik15-Feb-11 12:00 
GeneralRe: Great article, but no thanks to LoadFolderNodeFromRegistry [modified] Pin
Member 1081340717-Jun-15 16:04
Member 1081340717-Jun-15 16:04 
GeneralMy vote of 5 Pin
gggustafson8-Aug-10 3:14
mvagggustafson8-Aug-10 3:14 
General[BUG] "Order" reg key does not have to exist for every fav entry - nested processing stops Pin
mcjoxp9-Jul-10 0:29
mcjoxp9-Jul-10 0:29 
GeneralRe: [BUG] "Order" reg key does not have to exist for every fav entry - nested processing stops Pin
jpmik9-Jul-10 7:05
jpmik9-Jul-10 7:05 
GeneralRe: [BUG] "Order" reg key does not have to exist for every fav entry - nested processing stops Pin
mcjoxp9-Jul-10 7:28
mcjoxp9-Jul-10 7:28 
GeneralSubRecord1 byte array length changes for Win7 Pin
mcjoxp6-Jul-10 22:06
mcjoxp6-Jul-10 22:06 
GeneralRe: SubRecord1 byte array length changes for Win7 Pin
jpmik7-Jul-10 8:53
jpmik7-Jul-10 8:53 
GeneralRe: SubRecord1 byte array length changes for Win7 Pin
Adrian Alexander15-Feb-11 17:32
Adrian Alexander15-Feb-11 17:32 
QuestionAn easy program? Pin
Member 697482111-Mar-10 7:49
Member 697482111-Mar-10 7:49 
QuestionCreate a URL Shortcut [modified] Pin
vb.philip7-Dec-08 2:46
vb.philip7-Dec-08 2:46 
QuestionHow to create a custom favorite entry? Pin
debussyster17-Jul-08 23:31
debussyster17-Jul-08 23:31 
GeneralDate format... Pin
slickvguy22-May-08 16:32
slickvguy22-May-08 16:32 
QuestionBut IE is a P.O.S. so what difference does it make? Pin
Clinton Gallagher24-Dec-07 9:37
professionalClinton Gallagher24-Dec-07 9:37 
QuestionLooks nice... 2005 possible? Pin
Dee Olutayo24-Dec-07 8:24
Dee Olutayo24-Dec-07 8:24 
AnswerRe: Looks nice... 2005 possible? Pin
jpmik24-Dec-07 8:31
jpmik24-Dec-07 8:31 
GeneralThanks, nice work ! Pin
BillWoodruff22-Dec-07 17:17
professionalBillWoodruff22-Dec-07 17:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.