A customer was experiencing a problem with the SHGetÂFolderÂPath function. Specifically, they had a program that called the function like this:
SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL,
SHGFP_TYPE_CURRENT, pathBuffer);
but it failed with error 0x80070003 which is the HRESULT version of ERROR_. The error occurs only when run from a Jenkins pipeline. If they the run the program standalone, then the function succeeds and returns the expected result.
A procmon trace showed that the application tried to access the folder C:\, which failed with NAME_. And that was the clue that broke things open.
The Common Documents folder defaults to %PUBLIC%\. The PUBLIC environment variable’s normal value is C:\, but when the program runs as part of a Jenkins pipeline, the environment variable is set to autobuild for some reason.
This means that when the program calls SHGetÂFolderÂPath and asks for CSIDL_, the system looks for autobuild\, which doesn’t exist, hence error 0x80070003: “The system cannot find the path specified.”
There are a number of environment variables that have special meaning, and you change them at your peril. You probably know about variables like windir, ProgramFiles, and TEMP, but there are quite a number of other special environment variables, and PUBLIC is one of them.
Armed with this information, the customer went back to see who was messing with the PUBLIC environment variable and try to get them to stop.
“Accidentally reconfiguring the system.”
Its time to learn a new german word: Unfallverhütungsvorschrift!
Also “Software Engineering” may come into your mind…
A PROPERLY designed and implemented product does NOT allow such accidents!
%ProgramData% relative special folders have the same issue.
The strange thing is, this expansion issue only applies to the older special folders. Even if you use the newer Known Folder API, the old special folders have this issue (Common Templates etc.) while the KF-only folders (CommonRingtones etc.) do not.
I recently came across something certainly related to this. I was surprised that scripts running under Jenkins jobs were accessing user profile information from C:\Windows\ instead of C:\Users\. I chalked it up to the fact that we were running Jenkins as a Windows Service.
Normal behaviour if the profile used is C:\Windows\System32\Config\SystemProfile, C:\Windows\ServiceProfiles\LocalService or C:\Windows\ServiceProfiles\NetworkService
The latter two are the profiles for the "NT AUTHORITY\LOCAL SERVICE" alias "LocalService" and the "NT AUTHORITY\NETWORK SERVICE" alias "NetworkService" accounts, both introduced with Windows XP, initially stored in the directories "C:\Documents and Settings\LocalService" and "C:\Documents and Settings\NetworkService", relocated to their current locations with Vista.
The first profile, introduced with Windows 2000, is for the "NT AUTHORITY\SYSTEM" alias "LocalSystem" account.
Its location is yet another design bug, since it is subject to File System Redirection on 64-bit installations!
Admire the result of the "lobotomy" or "schizophrenia" in C:\Windows\SysWoW64\Config\SystemProfile
And while...
Is there a canonical list of environment variables that have special meaning?