Beyond good ol’ Run key, Part 94

This is a short post to cover a ‘new feature’ of Windows 10 that some users complain about online.

When you use this ugly system for a while, and at some time need to restart it, you may notice that sometimes applications that are running prior to restart are re-launched after you log on.

A good example is Regedit. If you open it, restart the system, the application will be re-launched after the reboot.

How does the Windows 10 know which processes to re-launch after the reboot?

Prior to restart the system populates the RunOnce key adding a list of items in a form of:

  • HKCU\SOFTWARE\Microsoft\
    Windows\CurrentVersion\
    RunOnce\Application Restart #N
    =<Application Path>

where N is a number (the code is inside the winsrvext.dll).

So, if you come across entries like this, at least we can guess where they come from.

Now, how does the OS actually know which programs to restart?

If you ever used OSX you may be familiar with the a cool feature of re-opening currently opened applications after the reboot. Could that be that Windows 10 is following this path? Turns out that the truth is far more boring. This is actually not a Mac OSX-like feature at all. The OS simply grabs a list of programs that called the RegisterApplicationRestart API during their run-time, and only these will be added to the RunOnce key.

Last, but not least, I have no idea why Regedit calls this API at all…

btw. I am getting old, I covered it in the past here, although in a different context.

advpack.dll ! DelNodeRunDLL32 and its flags

It’s one of these “I was looking at something else, and as usual, came across something else” cases. In this particular instance it was the good ol’ DelNodeRunDLL32 function exported by the advpack.dll.

A quick search followed, and I soon discovered that @bohops twitted about it a while ago, so there was not that much to add…

However…

Looking closer at the DelNodeRunDLL32W function I noticed that it tries to take two arguments, not one, as originally assumed. If the second argument is not present, it is assumed to be 0.

Why not checking what the second argument is all about though? And here we are…

A few more Google searches later we can (re-)discover that DelNodeRunDLL32 function can delete both individual files, and whole directories + change its behavior if we ask it too.

How?

Via its flags. Ones that we can choose to pass via a command line argument (the second one, as you guessed by now).

Again, googling around I came across this header file that lists all the flags that are documented:

// FLAGS:
#define ADN_DEL_IF_EMPTY 0x00000001 // delete the directory only if it's empty
#define ADN_DONT_DEL_SUBDIRS 0x00000002 // don't delete any sub-dirs; delete only the files
#define ADN_DONT_DEL_DIR 0x00000004 // don't delete the dir itself
#define ADN_DEL_UNC_PATHS 0x00000008 // delete UNC paths

Running

  • rundll32.exe advpack.dll,DelNodeRunDLL32 “c:\test” – will wipe out the whole ‘test’ directory
  • rundll32.exe advpack.dll,DelNodeRunDLL32 “c:\test\file” – will delete the ‘file’ only
  • rundll32.exe advpack.dll,DelNodeRunDLL32 “c:\test”,4 – will wipe out the whole ‘test’ directory except the ‘test’ directory itself
  • rundll32.exe advpack.dll,DelNodeRunDLL32 “c:\test”,1 – will wipe out the whole ‘test’ directory only if it is empty

Little trivia, but always…