The TEMP directory is like a public hot tub whose water hasn’t been changed in over a year


A customer reported that they couldn't install product X. When they ran the installer, the got the error message

setup.exe - Application Error
The application was unable to start correctly (0xc00000ba). Click OK to close the application.

The product X setup team weren't sure what to make of this, and they asked if anybody had any ideas.

The error code 0xc00000ba is STATUS_FILE_IS_A_DIRECTORY, which means that something was supposed to be a file, but instead it was a directory. The path-searching algorithm is not a backtracking algorithm, so once it finds something wrong, it just stops rather than backing up and trying the next directory.

This was enough of a clue to direct further investigation, which revealed that the customer had a directory named C:\Users\Bob\AppData\Local\Temp\version.dll\. The customer responded, "There are plenty of directories with names of DLLs in my TEMP directory, but getting rid of this one fixes the issue. Thanks!"

(Puzzle: Why are there so many directories with the names of DLLs? Psychic answer.)

I slipped something past you a little while back. Did you notice?

Okay, I gave it away in the subject line. The setup program is running from the TEMP directory. That should already set off alarm bells.

The TEMP directory is a dumping ground of random junk. A downloader may have put a DLL there and forgotten to delete it. (Or worse, expected it to stay there forever.) And that DLL might be from an incompatible version of some DLL your setup program uses. (I have seen applications ship their own custom versions of system DLLs! Yeah, because the x86 version of shlwapi.dll from Windows 2000 is drop-in compatible with the version of shlwapi.dll that comes with Windows 7.) Who knows what other yucky things have been lying around in that directory. Since the application directory is the first directory searched when the system looks for a DLL, a rogue DLL in the TEMP directory is a trap waiting to be sprung. (A similar issue applies to a shared Downloads directory.)

It's like the horror movie trope where the frightened pretty girl runs into a room, slams the door shut, then breathes a sigh of relief, believing herself to be safe. But she didn't check that the room was empty! (In other words, she created her airtight hatchway around an insecure room.)

The Program X setup team decided to change their installer so that it created a subdirectory of TEMP and extracted the main setup program there. That way, it got a fresh hot tub with clean water.

Remember, the directory is the application bundle. If you drop your application into a random directory, you've just added everything in that directory to your bundle. And if you don't secure your application directory, you're allowing anybody to add components to your bundle. That's one of the reasons why the Logo program encourages (requires?) applications to install into the Program Files directory: The ACLs on the Program Files directory allow write access only to administrators and installers. This makes the application bundle secure by default. If you want to make your application bundle insecure, you have to go out of your way.

Comments (28)
  1. Oh, tell me about that.

    An enterprise backup product of a first tier antivirus/backup vendor installs a DLL to %TEMP% and WILL NOT run if it's not there or doesn't have "execute" permissions. If you delete the DLL, it gets silently re-created. Ever so helpful MS antivirus found it untrusted and quarantined it. So I'm now getting those nice daily reminders of the failed backup. Not that I care.

    And shlwapi is a HORRIBLE API. Those pesky lawyers forced it to the surface, causing unending shame to its creators.

  2. And shlwapi is a HORRIBLE API

    In case you're wondering why: none of Path* functions has an argument for the buffer size.

  3. @alegr1: shlwapi is deprecated – new code should be using something else, as shown here: msdn.microsoft.com/…/bb759845%28v=vs.85%29.aspx

  4. @RaceProUK:

    SHLWAPI Wrapper functions doesn't seem to mean what you think it means.

  5. Joshua says:
    1. I wouldn't be surprised if an application shipping Win2000's shlwapi works just fine on Win7 if it loads that shlwapi. Of course any other application encountering it …

    2. We really need a TMP that is cleared on reboot. The question is how to get it without breaking the few programs that depend on TMP sticking around after reboot.

  6. Nathan Mates says:

    Joshua – I wrote a small app that scans a directory and deletes app files not created/written to in the last N days. (Directory and # of days are on commandline). I run it on startup on my personal boxes, saying that any file not written to %temp% in the last 14 days should be toast. And any directories that were just emptied are also subject to deletion.

    Seems to work fine for me — 14 days is enough time that it won't kill something written just before a reboot — but it does keep %temp% from having 5 year old bathwater in it. I don't see it as a shippable fix for the net at large — e.g. something expects to be in %temp% after the next reboot, but the system clock jumps forward > 14 days after the reboot.

    I know it's a little late to change it, but I wish _*mktemp_s() was extended or took other parameters — whether the file should be preserved after a reboot, or a max age on the file.

  7. Random User 9274896 says:

    It could be argued that programs that need "temp" things to hang around should just create a folder in "local app data", do what needs done, and clean up after itself later. Leaving "temp" for things that can truly vanish at any time random time (provided they aren't locked).

    But maybe that idea has its own problems.

  8. David Walker says:

    @Nathan Mates:  You wrote a small app to recreate what the free EMPTEMP program does?  Search the Web and you'll find it.  It has been around forever, and it works great in Windows 7.  I haven't tried it in Windows 8.  

    I have mine set to 2 days.  Any app that wants to put something in %temp% and execute it on reboot (some installers do this) won't be adversely affected.  I also install this on any computers that I clean out for friends and customers.

  9. Maurits says:

    Some OSes make the temp directory a RAM disk.

  10. jader3rd says:

    I'm tellin' ya, Windows needs a file attribute called Expired Date (or something similar) that tells the OS, once a file reaches that date the OS can clean it up as part of regular disk maintenance.

  11. Mc says:

    Nice mock up of the dialog box in HTML.   Should of made the OK button do something a bit more interesting though!

  12. Mark VY says:

    About expired dates, funny story: thedailywtf.com/…/Classic-WTF-The-Bug-That-Shut-Down-Computers-WorldWide.aspx.

    Still, could be a good idea.

  13. Christopher says:

    @jader3rd

    Funny that you mention that… blogs.msdn.com/…/10119675.aspx

  14. waleri says:

    >> I have mine set to 2 days.

    Imagine what will happen when you go on vacation…

  15. WndSks says:

    OT: Also, functions like PathFindExtension are documented with "string of maximum length MAX_PATH" which is stupid and would make the internals of the function more complicated for no reason (IIRC the *A function does not call the *W version)

  16. >> Imagine what will happen when you go on vacation…

    I imagine that he won't install new software without a reboot just before going on vacation…

  17. Anonymous Coward says:

    @MC: Unfortunately Webkit defaults the border colour to ‘gray’ which diminishes the experience somewhat.

  18. Why can't Photo Gallery view pictures sequentially when extracted to the Temp directory? It doesn't seem to "find" the next picture?

  19. Eugen says:

    @ Maurits [MSFT]: Actually I have installed DataRAM and make a RAM disk of 3GB, from total of 12GB (can be used up 4GB in free version), make three folders there: USERTEMP, SYSTEMP and OPERATEMP, saved the image and put do load it on startup, so now no more problems with temporaries, on shutdown the RAM disk is destroyed with all it's contents and on start-up just a clean 3GB image (this image do not make a difference for boot-up time as is clean). Many applications work faster and lot more faster works many installers which use the TEMP folders.

  20. Danny says:

    "The setup program is running from the TEMP directory. That should already set off alarm bells. "

    They are dumb, didn't you tell them that Ray? I mean, you make a product, create a nice site around it and users all over the world will start taking the installer from your site and give it a try. The very first thing they would is to test that case. Every major browser will allow you to "Run/Open" / "Save" the installer from your site. And most users will press "Run/Open". That means the browser will download the installer into TEMP directory and then launch it from there. What did they expect? 90's? to ship the CD via air-mail so the installer starts from a clean directory? Tell them you're still working on that time machine.

  21. Muzer says:

    @Maurits Yeah, having the /tmp directory as a ramdisk is rather a good idea for computers with very slow I/O. I actually experimented with making various subdirs of /var a ramdisk at one point (this wasn't a server so most things in /var didn't really need to stick around after a reboot) but gave up on the idea because of the number of various caches that would have to be backed up to avoid yet more I/O, and the irritation of log files being deleted. I don't think all Linux distros have /tmp set up as a ramdisk, but some either do or recommend doing so. But with I/O the speed it is nowadays, it's not really necessary for most cases.

  22. Random832 says:

    @Danny

    In most downloadable installers, the exe you download is standalone and extracts the files for the real installer. The problem is that this one extracted the files directly to the TEMP directory instead of making a directory under it.

    Or did you think that the user downloaded all the files including this dll separately then ran the installer after downloading it last?

  23. km007 says:

    Another option for cleaning up the temp folder is Disk Cleanup. It removes temp files that haven't been accessed in a week. However since Vista turned of the updating of the last file access timestamp this effectively mean files that were created a week ago get removed.

  24. SimonRev says:

    I once wrote a program that needed to create a fair number temp files.  Unfortunately I didn't realize that I was leaking them some times (usually because I was forcibly terminating my program during debugging).  After a few years GetTempFilename was taking over a minute to complete.  Turns out I had ~100,000 temp files for my program and it was sequentially polling available numbers.

    I quickly rewrote things to clean up abandoned files from a previous session.

  25. John says:

    In related news, on my machine %UserProfile%AppDataLocalMicrosoftWebsiteCache contains OVER NINE THOUSAND (literally) empty folders.

  26. Danny says:

    @Random832

    No dude, I understood that! I'm not dumb, I can read what Ray wrote there. But my question, darling, is : Did you even read my post before commenting on it? Because it seems you missed my point by at least 3 miles.

  27. @Danny,

    Let's make the point 3 miles big, so you don't miss it.

    A self-extracting executable is run from %TEMP%. It needs to extract files and run the actual installer. Now, where does it extract the files?

    Option 1: directly to %TEMP%;

    Option 2: Make a subdirectory in %TEMP% and extract the files there;

    Option 3: Use some other location.

    The customer used option 1. But it's the least appropriate option.

  28. Danny says:

    @alegr1

    Pff another one. My point was that the customer did NOT tested that option 1!! Capisci?!! Hard to read? Or to use the single neuron?

Comments are closed.