Menu

Windows Disk cleanup in-depth

May 19, 2011 - Programming

Fig 1-1: Process Explorer viewing disk cleanup DLL files

Ever wonder how the windows disk cleanup utility works? Go ahead. Try googling it. All you’ll get are various “tech tips” on how to effectively use the program, nothing on how it actually does it’s task. I became curious recently in a forum thread regarding Disk cleanup and a few other similar tools. Ages ago I recall reading some article or Q&A column or something where the author described some of the intricacies of disk cleanup; I couldn’t find it, (it was probably in the MSDN library collection I was using at the time)- and it was written for Windows 98 Anyways. So, I decided to determine the method disk cleanup uses to figure this out. My first tool in this fight was to try to use Process Explorer to try to determine what DLLs disk cleanup loaded, shown in Fig 1-1.

 

 

 

 

From this, there isn’t a whole lot to go on. There is a lot of informational noise, in that it’s difficult to determine which files would be the presumed “plugin” dlls and which are simply loaded by other DLLs and so forth; Additionally, there is also the possibility that it doesn’t keep the DLL loaded and therefore it wouldn’t appear in this list at all. However, there would still be behaviour using the DLL and related data, and it has to retrieve the list of “plugin” DLLs or whatever from somewhere, so I turned to Process Monitor instead.

Process Monitor

Generally speaking, I actually prefer to avoid using Process Monitor if I can. It’s not that I dislike the program- it is extremely powerful and replaces both of the older filemon and regmon utilities. The problem I have is that even though it provides a number of powerful tools for filtering the various events, it is still a lot of data to sift through. In this case, I set a filter to include only cleanmgr.exe related events, ran disk cleanup, (or at least let it “enumerate” what it could clean) and then sifted through the various events. Searching through the results I found some entries corresponding to the names of each “cleanup” list item, which can be seem in Fig 1-2.

Fig 1-2:Process Monitor finds something relevant to my goose chase

From this, it seems clear that Disk cleanup is getting many of it’s cleanup “entries” from a list contained in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches. Naturally I assume this differs if the tool is run as a standard user (rather than as administrator). Each key seems to have a few pieces of data; a filelist, for example, and a Folder, both of which seem to allow for pipes separating multiple values as well as wildcards. They also have a Description entry, which is either a string or it could be a resource reference in the form @filename.ext,-resid where resid is the resource id in the dll/exe’s string table that is referenced by the @filename.ext. This same format is repeated for a few other entries as well as what icon Disk cleanup should show in the list.

More interesting however is the “default” item, which references a CLSID; I followed the CLSID for one cleanup entry, in this case the “chkdsk temporary files” entry. This clsid can be found in HKEY_CLASSES_ROOT\clsid and it’s inprocserver32 is %SystemRoot%\System32\DATACLEN.DLL. Because CLSID’s are in fact class IDs and

Fig 1-3: OLE/COM Object viewer failing to load dataclen.dll

therefore we can assume that DATACLEN.DLL is in fact a COM component, I opened it up with OLE/COM Object viewer included with the Windows SDK. Unfortunately, it refused to open it, as seem in fig 1-3; inspecting the file with Resource Hacker, I determined that the cause was in fact because the file did not have the TYPELIB resource entry that is typical of COM components; or, more precisely, that entry was probably stripped. So, I was somewhat at a loss here; clearly, disk cleanup interfaces with DLLs as COM components and passes the data from each registry key to that component in order to perform that particular phase of cleanup; in the case of the chkdsk temporary files cleaner for example, it passes in a FileList of *.CHK, and also a list of folders, ?:\FOUND.000|?:\FOUND.001|?:\FOUND.002|?:\FOUND.003|?:\FOUND.004|?:\FOUND.005|?:\FOUND.006|?:\FOUND.007|?:\FOUND.008|?:\FOUND.009 which I would imagine means to search the specified drive for each of those given “found.00#” folders and delete all .chk files within them. Pretty straightforward, judging from this we can assume that dataclen.dll is what actually is doing the grunt work here, in that many of the entries specified- at least in my registry- point to dataclen.dll with varying folders and file masks.

For a bit, I figured “well, maybe it’s a secret interface that isn’t documented” but no doubt there would be trouble over that- Microsoft is apparently supposed to work with their insides out nowadays but I digress; either way, application vendors have been adding functionality to Disk cleanup for ages so I assumed there was some sort of documentation, which led me to this page.

This documents exactly what I originally suspected; Disk cleanup does use a specific interface, in this case IEmptyVolumeCache and IEmptyVolumeCache2. So far, the way Disk cleanup works appears to be something like this:

it enumerates all keys in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches. It may also enumerate other keys for similar entries.

In this case the default value for each key will be a CLSID; this CLSID points to a class that implements either IEmptyVolumeCache or IEmptyVolumeCache2; the latter of which is of course newer and adds a single new function which adds better multi-language support. Disk Cleanup opens the appropriate registry key (which again may be in HKEY_CURRENT_USER in the case of a non-admin run) and passes the HKEY handle to the initialize routine of the instantiated class. Then presumably each cleanup class will “do it’s thing” to initialize from that key. This explains why some of the keys present in VolumeCaches seem to have different values; the different DLLs and CLSIDs can require different keys and values to be present which can mean different things. That said most of them are in fact “standard”, and are documented here. the “stateflags” entry appears to be the one affected by using /sageset and /sagerun, the behaviour and effects of which to me were a final puzzle piece:

 

By running the disk cleanup manager’s executable file—Cleanmgr.exe—from a command line, you can declare cleanup profiles. These profiles are composed of a subset of the available handlers and are given a unique numeric label. This allows you to automate the running of different sets of handlers at different times.

The command line “cleanmgr.exe /sageset:nnnn“, where nnnn is a unique numeric label, displays a UI allowing you to choose the handlers to be included in that profile. As well as defining the profile, the sageset parameter also writes a value named StateFlagsnnnn, where nnnn is the label you used in the parameter, to all of the subkeys under VolumeCaches. There are two possible data values for those entries.

  • 0: Do not run this handler when this profile is run.
  • 2: Include this handler when this profile is run.

For example, suppose that the command line “cleanmgr.exe /sageset:1234” is run. In the UI that is presented, the user chooses Downloaded Program Files, but does not choose Temporary Internet Files. The following values are then written to the registry.

 

The command line “cleanmgr.exe /sagerun:nnnn“, where the value of nnnn matches the label declared with the sageset parameter, runs all of the handlers selected in that profile.

A generic StateFlags value is written to the registry when Disk Cleanup is run normally. This value simply stores the state (checked or unchecked) of the handler the last time it was presented as an option to the user. There are two possible data values for those entries.

  • 0: The handler was not selected.
  • 1: The handler was selected.

 

What can we glean from this? well, aside from changing a few flags in the registry, this doesn’t actually change the list of usable cleanup options. “But BC” I hear you say- “My list is different when I use cleanmgr /sageset:65536 & cleanmgr /sagerun:65536”!

 

Of course it is. when you run cleanmgr /sageset, it lists <every> handler; even those that would normally be excluded because of permissions, since you are merely changing the values of them in the registry. When you then use the /sagerun switch you aren’t actually performing the cleanup for all those items, only those valid for the current profile. Compare for example the list you see when you use /sageset:65536 to the list you get when you run cleanmgr.exe as an administrator. For me, I see no difference. /sageset and /sagerun don’t actually change the available cleanup options, they just change the cleanup options chosen (which boxes are checked by default).

Have something to say about this post? Comment!