(…or what happens when squirrels forget where they buried their nuts)
An issue ran into me a few weeks ago, that served as a great chance to use familiar tools in a new way, and also acted as a kick in the pants that sometimes legacy behaviors are best not forgotten.
A third party application would not install. It failed with error:
"Setup cannot continue. The Microsoft Runtime DLL installer failed to complete installation.”
From the log file generated by the setup attempt we see:
Attempting to launch ""C:\<path>\vcredist_x86.exe" /Q"
Child exited with code 8191
Process returned 8191
This indicated that the parent Setup.exe process was attempting launch vcredist_x86.exe (Visual C++ Redistributable Package) and the failure occurred in that dependency.
I tested the standalone package for vcredist_x86.exe to see if that too failed.
It did, and gave the error:
"Required file install.ini not found. Setup will now exit”
At this point we know it is not the third party application, but the child package. Taking the error message at face value, I suspected some problem with the ini file itself. In order to prove this and get more details of the failure I took a Process monitor trace (Procmon).
Procmon traces in general can be an overload of information. To filter the noise I used a feature that someone recently introduced me to, that I’ve since found to be a huge help when narrowing the scope of the issue by finding application start/stop information and child processes. Using Process Tree(Ctrl-T) view I found where my application started, spun up vcredist_x86.exe, which in turn spun up Install.exe:
Right-click on vcredist_x86.exe and you can select to filter on just those processes:
The first thing I looked at was where Install.exe exits and I can see the same error code that we got in the first setup log: 8191. Which tells me that we’re on the right track and we’ve narrowed it down to a failure in Install.exe.
(8191 by the way is Setup Failure – unknown reason which is due to how the error is handled at the code level. Err for example does not have anything that syncs up with the actual error returned. This blog lists some errors that are not covered by Win32 error codes: http://blogs.msdn.com/b/astebner/archive/2005/12/07/501381.aspx)
A search for Install.ini shows that vcredist_x86.exe creates (create should be thought of as create or open, depending on how it is used) and accesses that file successfully but the child process of install.exe never tries to access that file:
Up to this point I was following a trail of breadcrumbs with the assumption that the destination was a problem with the Install.ini file. To confirm that I was on the right path I took another Procmon of the vcredist_x86.exe on a working machine. Now, in addition to a breadcrumb trail I now had an accurate map of how the install should look:
Here (reading bottom up) the process BaseDllReadWriteIniFile moves to BaseDllReadWriteIniFileOnDisk. And as expected we read the file from disk. In the Failing procmon we don’t appear to go to disk. So the question is – what other path does the code take?
Looking further into the bad Procmon we come upon a similar stack with one major deviation:
And that stack belongs to this entry:
Stepping into my tricked out Delorean…way back to Windows 95/98 time, we used to have Win.ini, System.ini etc files on the root of c:\. Those legacy files still exist but have been moved to their new home in the Registry. We access them with the BaseDllReadWriteIniFileViaMapping code path, verses the OnDisk path.
This is documented here:
102889 Mapping .INI File Entries to the Registry
Doing a quick search on “DoesNotExist” in the registry entry above reveals that if a registry setting for “IniFileMapping” is set to @SYS:DoesNotExist improperly, it will cause any systems to think that all ini files do not exist.
in this case the registry key was changed to prevent Autorun/Autoplay. But it was placed in the wrong location, the root of the IniFileMapping key and not under the intended subkey for Autorun.inf. This is not recommended, first because it can have unknown side-effects, and second, like any squirrel, sometimes we forget where we bury our nuts. Changing keys, incorrectly or correctly, can effect the system far down the road, which makes it difficult to track down.
When troubleshooting, one of my first rules is to know what “Good” looks like. Having a known good trace helped drive to the resolution. To take that a step further, remembering how things work, that ini files on disk may now also be mapped in the registry would have cut troubleshooting time significantly. Finally, remembering what change, where they buried the nuts in the first place, could have saved us from the entire trip… it just wouldn’t have been as much fun.