Some time ago, I was in the situation to set up a new computer with a Windows XP 64 CD. Well it doesn’t matter that it was 64bit.  However, I always create a separate partitions for Windows XP. And because user profiles tend to get big, I moved a new user to a second partition. (See the Internet how it is done) But as if it wasn’t enough I thought that I also could move the Administrator profile that easy. Way wrong!

First of all, copying a loaded user profile isn’t possible without the BACKUP privilege. You can’t open already opened files a second time (share deny). The solution is: Either you can use a backup application that runs with the special privilege or you can just use another administrative user (which I did).

There are some keys which have absolute path variables that must be changed, too. But that is a minor problem. The big problem was that Windows could not load the profile of the Administrator. Windows tried to start up the users desktop but then failed with the dialog:  “Windows failed to load user profile.”

It got more confusing because every other user in the system didn’t suffer from this problem. And to top it,  sometimes I could successfully login to the Administrator account.

Solution

In such cases the event manager is a good way to find the error source. In my case, it told me that “NTUSER.DAT” (this is where Windows stores the current user keys called a registry hive) was already opened by another process. I really can’t say why this was the case because it shouldn’t be the case shortly after a fresh boot up. (Of course, the file was correct, it had no write protection, and security was set accordingly)

In such a case you usually have some ways to fix the problem:

1. Reinstall Windows
Good choice. But too much work — and who will promise me that it won’t happen again?

2. Leave Administrator where it was
Also good choice. And I tried it. However my Windows could not handle two profile places somehow and the very same error occured with the old profile location.

3. Live with the situation
Some people do it. I thought about it, too, I have to admit. That’s because there is a user called root in the system now.

4. Find the bug and ignore how much time it will cost.
Ouch. I don’t have time, so not a good option.

5.Create a workaround.
YES! That’s what I did.

So I came up with a practical and fast solution. As I’ve already written, the user’s registry hive could not be loaded.
Why? I don’t know much about it but the registry file was blocked.
Well, I’ve found out that if the Administrator registry hive was already loaded (HKEY_USERS\S-1-5-21-xxx-500 is visible) the Windows could successfully logon the Administrator. I simulated this situation by manually loading the user’s profile using the LoadUserProfile function from Windows API. Well, it always worked!

uses
  JwaWindows,
  JwsclToken,
  jwscltypes;

var
   T : TJwSecurityToken;
   ProfileInfo : TJwProfileInfo;
begin
  T := TJwSecurityToken.CreateTokenByProcess(0, TOKEN_ALL_ACCESS);
  try
    T.LoadUserProfile(ProfileInfo, []);
  finally
    T.Free;
  end;

The next step was to do it automatically before an Administrator could logon. Of course, I could have created a service which loads the user profile at startup but I wanted to be fast so there is another option called Task Scheduler.
Every Windows startup I let run the code above as a simple task with Administrator credentials (needs password).

I don’t know whether the Task Scheduler loads the profile (I would guess so). However the problem is that the profile could be unloaded after the process has ended. So the hive would be removed and logon would no more be possible.

Thus the code above just loads the profile but does not unload it. Since profiles are not watched by Windows (at least in XP) the registry hive  stays loaded and a logon attempt will work (T.Free won’t unload it!).

JEDI Windows Security Code Library used features