I'm writing an application that will write some registry key for every selected user.
I was wondering if there was a proper way to mount another user's hive to write in it.
At the moment, I'm using "REG LOAD" to mount every hive. It's functional, but messy.
Any Idea ?
Thanks in advance for your answers.
Cheers.
--- EDIT 19.06.2013 ---
Okay, thanks for the help, I was able to call the function, but was unauthorized to mount the registry.
I tought it was a missing privilege, and force it to run in admin.
I still recieve a 0x522 error, which mean, according to MSDN, that I don't have the right to mount the hive.
I searched the web and found different explanation and possibilities, but I still can't manage to mount the hive.
I'm pretty new in C# developpement and Windows API...
Here's the code I tried to understand and used in my tests.
Am I missing something ?
Thanks in advance for your answer.
namespace mountregistry2
{
    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public int LowPart;
            public int HighPart;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public LUID Luid;
            public int Attributes;
            public int PrivilegeCount;
        }
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
            public static extern int OpenProcessToken(int ProcessHandle, int DesiredAccess,
            ref int tokenhandle);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetCurrentProcess();
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
            public static extern int LookupPrivilegeValue(string lpsystemname, string lpname,
            [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
            public static extern int AdjustTokenPrivileges(int tokenhandle, int disableprivs,
            [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES Newstate, int bufferlength,
            int PreivousState, int Returnlength);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int RegLoadKey(uint hKey, string lpSubKey, string lpFile);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int RegUnLoadKey(uint hKey, string lpSubKey);
        public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        public const int TOKEN_QUERY = 0x00000008;
        public const int SE_PRIVILEGE_ENABLED = 0x00000002;
        public const string SE_RESTORE_NAME = "SeRestorePrivilege";
        public const string SE_BACKUP_NAME = "SeBackupPrivilege";
        public const uint HKEY_USERS = 0x80000003;
        public string shortname;
        bool unloaded = false;
        private void testmountregistry()
        {
            int token = 0;
            int retval = 0;
            TOKEN_PRIVILEGES TokenPrivileges1 = new TOKEN_PRIVILEGES();
            TOKEN_PRIVILEGES TokenPrivileges2 = new TOKEN_PRIVILEGES();
            LUID RestoreLuid = new LUID();
            LUID BackupLuid = new LUID();
            retval = GetCurrentProcess();
            MessageBox.Show(retval.ToString("X")); //returns FFFFFFFF, which should work
            retval = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
            MessageBox.Show(retval.ToString("X"));//RETURNS 1
            retval = LookupPrivilegeValue(null, SE_RESTORE_NAME, ref RestoreLuid);
            MessageBox.Show(retval.ToString("X"));//Returns 1
            retval = LookupPrivilegeValue(null, SE_BACKUP_NAME, ref BackupLuid);
            MessageBox.Show(retval.ToString("X"));//Returns 1
            TokenPrivileges1.PrivilegeCount = 1;
            TokenPrivileges1.Attributes = SE_PRIVILEGE_ENABLED;
            TokenPrivileges1.Luid = RestoreLuid;
            TokenPrivileges2.PrivilegeCount = 1;
            TokenPrivileges2.Attributes = SE_PRIVILEGE_ENABLED;
            TokenPrivileges2.Luid = BackupLuid;
            retval = AdjustTokenPrivileges(token, 0, ref TokenPrivileges1, 1024, 0, 0);
            MessageBox.Show(retval.ToString("X"));//Returns 1
            retval = AdjustTokenPrivileges(token, 0, ref TokenPrivileges2, 1024, 0, 0);
            MessageBox.Show(retval.ToString("X"));//Returns 1
            uint hkey_users = 0x80000003;
            int interror = RegLoadKey(hkey_users, "test", @"C:\Users\Public\NTUSER.DAT");
            MessageBox.Show(interror.ToString("X"));//Return 0x522
            return;
        }
    }
}
You can call the RegLoadKey API method using platform invoke.
[DllImport("advapi32.dll", SetLastError = true)]
static extern Int32 RegLoadKey(IntPtr hKey, string lpSubKey, string lpFile);
User contributions licensed under CC BY-SA 3.0