About the Fonts folder in Windows, Part 1 (aka What are we talking about?)

Sorting it all Out
Michael Kaplan's random stuff of dubious value
Be sure to read the disclaimer here first!

About the Fonts folder in Windows, Part 1 (aka What are we talking about?)

  • Comments 28

When I first mentioned yesterday that I was going to be blathering about the Fonts folder for a bit, regular reader Rosyna commented:

It'll be interesting. I know virtually nothing about the Windows fonts folder. Many people hate the Mac OS X's multiple fonts folders (System, "Local", Network, User, and Classic). It becomes hard to deal with everything has having multiple duplicate fonts is very possible and almost the case on every single Mac OS X box.

The good thing though is that any font dragged into a Mac OS X font folder is available to all applications immediately.

I suddenly realized I wanted to start things a bit differently than what I was originally going to do.

(For those of you who hate the "Add Font..." dialog, wait for the next post -- I'll be getting to that shortly!)

So, we'll start with simple question: What the hell is the Fonts folder?

The simple answer? It is a Shell namespace extension that causes any display of %WINDIR%\Fonts in the Windows Explorer to have a special view where typical filesystems actions in Explorer such as copy, move, and delete have special handlers.

It is by no means the only way to get fonts ontop Windows, though.

If you look at the Platfrom SDK documentation for the AddFontResource function:

The AddFontResource function adds the font resource from the specified file to the system font table. The font can subsequently be used for text output by any application.

So all you have to do to get a font available to everyone is call this function!

Of course there are things to keep in mind in the remarks section:

Any application that adds or removes fonts from the system font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the operating system. The application should send this message by calling the SendMessage function and setting the hwnd parameter to HWND_BROADCAST.

When an application no longer needs a font resource that it loaded by calling the AddFontResource function, it must remove that resource by calling the RemoveFontResource function.

This function installs the font only for the current session. When the system restarts, the font will not be present. To have the font installed even after restarting the system, the font must be listed in the registry.

Wow, those three paragraphs are like three strong drinks, aren't they? They tell you:

  • you ought to tell everyone else if you added a font via the WM_FONTCHANGE message (seems a bit like this issue with SetLocaleInfo, doesn't it?)
  • Clean up after yourself when you are done via a RemoveFontResource call (just like mom said -- clean it up when you are done with it!)
  • Don't expect it to survive a reboot if you don't do some more work (though it does not tell you precisely what that work is!)

That work in the third bullet point is to add the  font's name and filename to the registry in the following subkey:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts

And although most of the files listed there will have no path (in which case %WINDIR%\Fonts is assumed), this is not a requirement.

All that our Shell Extension Fonts folder does (well, it does more than this, but bear with me for a bit) is wrap all this up. In fact, it is GDI that makes an AddFontResource call on every font in that registry key when it does its own initialization, and it is the folder's handling code that adds and removes fonts from the list in the registry.

But all of the hints are here -- anyone who hates the Shell Fonts folder interface to these things can build their own code. They can even make it a Shell Extension wherever they like, and put in all the same kind of handling code, or better.

Now the Shell code does a bit more here -- for example you can install a font programatically by opening the Fonts folder in Explorer and simply copying the font file to the folder (more on why this is not the best way to do it later!). It also gives some unique views of fonts that are in the folder (more on these later, too), and it completely hides hidden files even if you have the "Hide protected operating system files" setting unchecked (which you would do as well if you saw what was in there!). And lots of other little things like that.

But clearly the widespread belief that fonts need to be in the Fonts folder (which requires admin privileges to write to) is a myth. The only action that truly requires admin-style privileges is writing to that registry key (since it is under HKLM), but just about everything else is a bit more open to people.

The myth is a tribute to What it means to be in the default install, and how hard it is to get noticed as a feature if the feature is not available in some default, built-in fashion.

Imagine for example if the Fonts folder was actually further virtualized into supporting both the current folder in %WINDIR%\Fonts and some kind of per-user folder like under %USERPROFILE%\Fonts or something -- so that anyone could install fonts and you would either have the "just me" or "all users" choice, or if you lacked permissions it would be a "just me" install automatically.

For now one will have to keep imagining (there is no such feature in Vista, for example).

But I will be talking more about the Fonts folder in future posts, specifically to cover:

  • The Add Fonts dialog
  • Various views of fonts located in the folder
  • More on that registry key GDI uses
  • Changes to the Fonts folder in Vista
  • and more!

So stay tuned, there will be much more for font users, typographers, people who find my posts witty, Microsoft bashers, basically just about everyone....

 

This post brought to you by F (U+0046, a.k.a. LATIN CAPITAL LETTER F)

Comment on the blather
Leave a Comment
  • Please add 2 and 4 and type the answer here:
  • Post
Blog - Comment List
  • Hmm. That answers my question quite nicely.

    However, it is a bit vague on one point: the documentation you've quoted refers to "The current session" but then goes on to say "when the system restarts". My idea of "the current session" is the period between someone logging on and someone logging off, but from the mention of restarting I guess this really means that this setting lasts until the machine is shut down.

    This then leads me to wonder whether a non-admin user is able to write/run an app that calls AddFontResource and have that font available to all users until the system is rebooted. In particular, can I register a font called Tahoma which has stupid/offensive glyphs and have apps use that instead? Or does Windows protect existing named fonts from being masked by new registrations?

    (I notice that AddFontResourceEx can do what I would have expected AddFontResource to do -- it can register a font privately for use only by that application. Strangely, it also seems to have an option to bar all apps from "enumerating" the font, which I guess means it won't show up in the font list? I'm not seeing anywhere an option to register a font only for the current login session.

    Of course, I could try this stuff for myself. When I get a moment, I may write a little utility which can just add/remove arbitrary font files from disk, and which can be added to the list of actions on *.ttf files for quick, temporary installation of fonts.
  • Hi Ben --

    Actually, that "restart" text is from an older time when a restart was how the session was reset.

    In Vista, it is always the logon/logoff; in prior versions, it is just a new WindowStation, which means for example a TS logon will get the latest list rather than the one already there.

    AddFontResource cannot be used for provate fonts -- you have to use AddFontResourceEx.... :-)

    Other questions you raised including consequences of that last point!) will be covered in future posts.
  • Very informative. 

    It's interesting that AddFontResoure/AddFontResourceEx doesn't automatically notify clients that the font list has changed. After all, by default, people are extremely lazy and when it comes to doing something, most people take the easiest way out. If you look at ATSActivateFontFromFileSpecification (http://developer.apple.com/documentation/Carbon/Reference/ATS/Reference/reference.html#//apple_ref/doc/c_ref/ATSFontActivateFromFileSpecification) it has the option for a flag, kATSOptionFlagsDoNotNotify, which will supress the notification. I use this when I just need to get a string rendered in an image since I immediately deactivate the font after rendering. It is kind of weird that I have to use the same flags and everything when using RemoveFontResourceEx.

    What's really odd is this comment: "To add a font whose information comes from several resource files, point lpszFileName to a string with the file names separated by a | --for example, abcxxxxx.pfm | abcxxxxx.pfb."
    I'm not sure how I feel about shell folders personally. I think they can be useful but also make the operation significantly less "consistent" with the rest of the file browser UI.

    Hmm, I wonder which group I'm under.
  • "for example you can install a font programatically by opening the Fonts folder in Explorer and simply copying the font file to the folder"

    That 'programatically' (sic) should be 'manually', right? :)
  • I actually meant programatically -- manually copying would be just like drag&drop in Explorer, but I was talking about how the folder, when opened, would have knowledge of things you did outisde of the Shell, such as programmatic copies....
  • > and it completely hides hidden files even if you have the "Hide
    > protected operating system files" setting unchecked (which you
    > would do as well if you saw what was in there!)

    No I wouldn’t. The user has requested that hidden files be visible to him, and his/her orders are not to be questioned. After all, none of these files are too special — there are the files representing bitmap fonts Fixedsys, Terminal, System, Courier, MS Serif, MS Sans Serif, Small Fonts, and Symbol; the Marlett truetype font; and the desktop.ini file which is responsible for all this “magic”. An experienced user deserves to see them.
  • Cenatur,

    The list there is a conceptual list of fonts -- thus even if there are separate files for the various code page and size varieties of the bitmap fonts or marlett, showing them in the Fonts folder would not actually help anyone (since the other versions are not USED in any way.

    What precisely is the functionalitgy you believe is missing?
  • "session" has a specific meaning in Windowsese.  Nevertheless it's a bit hard to pin down.  Its mostly refers to a logged-in user.  So if both Alice and Bob are logged in they are in different sessions.  If Alice calls AddFontResource she will see the new font but Bob won't.  The whole concept gets a bit hazy because logging out and back in again does not necessarily create a new session on XP.  For Vista you always get a fresh session though.

    To be overly pedantic and start moving into the realm of irrelevent implementation details GDI does not read the info in the Fonts key in the registry.  USER does that and (essentially) calls AddFontResource on your behalf at session startup.  So to return to Alice & Bob, if Alice registers the font in the registry Bob still won't see it, but once he relogs it'll appear (assuming his session got recreated).  Interestingly, this happens even if Alice does *not* call AddFontResource.  This seperation between registering font and actually telling GDI to start using it can be confusing at times...
  • I don't know about "deserves", but as an experienced user who's checked the "Show all hidden files" box, if I browse to a directory in my file manager, I want to see the files in that directory.

    A file manager that does not do that one simple thing - the only thing it is meant to do - is broken.

    Look, if I really want to, I can just go to a command prompt, 'cd' to the correct directory and 'dir' it. But it's a pain in the behind, and the point of a GUI is to make things like browsing your filesystem *simpler*. Now you're just making it harder.

    Why do I want to look there? Maybe I'm just curious. Maybe it's because I want to figure out how Windows does things. Maybe I want to see the last-modified timestamp on a font file because some hypothetical virus can exploit a hypothetical recently-found buffer overrun in the font-rendering hinting parser (?) and hides itself in a .ttf file.

    It doesn't matter *why*. On my PC, that's *my* concern. But if I've checked the "show me all hidden files" box, then that's because *I want it to show me all the hidden files*.
  • Hi Adam,

    Well, that's just it -- a Shell extension is not just a file list. It is a virtualized view of the folder -- note how you do not get file names or extensions, either?

    Explorer is a file manager that supports virtualized views, and in many cases uses virtualized folders. Have you looked at "Temporary Internet Files" lately? :-)

    In any case, this particular folder has been around with the very functionality you are against for the last 10+ years and the last 10 versions of Windows. Has it truly made you want to uninstall the OS? I hope not!
  • Michael: Sorry to disappoint you, but I'm a Debian user these days :-0

    And when I use Windows, I generally turn off all the shell extensions that I can. I hate them.

    Look, if I go to the Control Panel and select "fonts", then, sure, I expect to see a list of logical fonts installed on the system. Probably some toolbar/menu items for "install fonts", "remove fonts", etc... (if I have authorisation to do those actions). I don't care about the files used, or even if Explorer is used to display the list of fonts. But if navigate to a particular directory in a file manager, that's because I want to know what files are in it!

    (Sorry, this is starting to get really OT now, but I can't stop.... :)

    Same with temp internet files. If there's an IE button "show cache" then fine - show me whatever you think is appropriate. If I browse to the relevant directory in the filesystem with a file manager, show me what's on the filesystem.

    Ditto Recycle Bin. If I hit the "recycle bin" button on my desktop, launch whatever application is appropriate (including Explorer with some extenstion to give me "undelete" options or whatever). If I browse the filesystem to get there, *I want to know what's on the filesystem.*

    I just want Windows to stop thinking it knows better than me what I actually want to do, because it keeps getting it wrong! If it can't "Do What I Mean" (DWIM) there should just be a button to make it "Do What I Tell You, No Matter How Crazy It Sounds" (priveliges permitting).
  • Michael: Sorry to disappoint you, but I'm a Debian user these days :-0

    Ah, then the command line should be something familiar....

    (Sorry, couldn't resist!)
  • :-)
  • You may have read the first post I wrote about this, titled About the Fonts folder in Windows, Part 1...
  • @Adam: In the good old days, if you suspected Explorer was lying to you then you could look at the same directory with Winfile. But for some reason Winfile doesn't get distributed with Windows these days.
Page 1 of 2 (28 items) 12