Solved

Get registry keys of Windows users that are not currently logged in

Posted on 2010-11-30
7
1,048 Views
Last Modified: 2012-05-10
I have an application that should read all Windows users' registry keys (folders).

I though this is simple. We have HKEY_USERS, and I know how to translate the SIDs to user names. This is not a problem. The problem is that HKEY_USERS only contains the keys (folders) of users that are currently logged in, and any other users are just missing. (But as soon as I log in with a user, its folder appears in HKEY_USERS).

So my question is how I can access the keys of users that are not currently logged in?

My app is in C#, but that's not really relevant.
0
Comment
Question by:kerzner
  • 4
  • 2
7 Comments
 
LVL 16

Expert Comment

by:kris_per
ID: 34238188

Can you try logging in as admin and see if you get the details of other users.
0
 
LVL 1

Author Comment

by:kerzner
ID: 34238207
This is what I do, and the answer is no. I am running Win 7, but the same happened on my old Win XP when we originally discovered the problem.
0
 
LVL 6

Expert Comment

by:ipajones
ID: 34238448
If you make the changes to HKEY_USERS\.DEFAULT then these will be inherited when the users logs in.
0
Portable, direct connect server access

The ATEN CV211 connects a laptop directly to any server allowing you instant access to perform data maintenance and local operations, for quick troubleshooting, updating, service and repair.

 
LVL 16

Expert Comment

by:kris_per
ID: 34239437
To view the profile of other users in Registry:

Start RegEdit (Click Start, click Run, type regedit, click OK)
Click on the HKEY_USERS node.
Select 'Load Hive' under File menu.
Select the NTUSER.DAT file of the other user2 (typically from the folder C:\Documents and Settings\<user name>)
Enter a SubKey name to load (for example AppEvents, Console, etc which you can see under HKEY_USERS\<user sid>\)

Now that subkey will be loaded under HKEY_USERS node and the data under this Subkey can be read from any other programs (like your c# program).

What you need to do is to do this 'Load Hive' functionality programmatically in your program.

A sample on How to programmatically load another user's NTUSER.DAT in registry is available here (in vb code) => http://support.microsoft.com/kb/297060

Hope this helps.


0
 
LVL 16

Accepted Solution

by:
kris_per earned 500 total points
ID: 34239853

In the step 'Enter a SubKey name' I mentioned above, it doesnt need to be an existing key name. It can be anything like 'loadedKey' which you can use to read the values from.

Below is c# code (converted from vb code in the above link). I provide the converted code as is and I haven't tried it run. But I hope this gives you the complete idea on what you need to do.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication4
{
    public partial class Form9 : Form
    {
        private struct LUID
        {
            public long LowPart;
            public long HighPart;
        }

        private struct LUID_AND_ATTRIBUTES
        {
            public LUID pLuid;
            public long Attributes;
        }

        private class TOKEN_PRIVILEGES
        {
            public long PrivilegeCount;
            public LUID_AND_ATTRIBUTES[] Privileges = new LUID_AND_ATTRIBUTES[2];
        }

        private const  int TOKEN_ADJUST_PRIVLEGES = 0x20;
        private const  int TOKEN_QUERY = 0x8;
        private const  int SE_PRIVILEGE_ENABLED = 0x2;
        private const  uint HKEY_USERS = 0x80000003;
        private const  string SE_RESTORE_NAME = "SeRestorePrivilege";
        private const  string SE_BACKUP_NAME = "SeBackupPrivilege";

        [DllImport("kernel32.dll")]
        static extern IntPtr GetCurrentProcess();
        
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool OpenProcessToken(IntPtr ProcessHandle, 
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
            out LUID lpLuid);
        
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, 
            [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges, 
            ref TOKEN_PRIVILEGES NewState, 
            UInt32 Zero,
            IntPtr Null1, 
            IntPtr Null2);
        
        [DllImport("advapi32.dll", SetLastError=true)]
        static extern long RegLoadKey(UInt32 hKey, String lpSubKey, String lpFile);

        [DllImport("advapi32.dll", SetLastError=true)]
        static extern long RegUnLoadKey(
            UInt32 hKey,
            string lpSubKey);
                
        private string strKeyName;
        private IntPtr MyToken;
        private TOKEN_PRIVILEGES TP = new TOKEN_PRIVILEGES();
        private LUID RestoreLuid;
        private LUID BackupLuid;

        public Form9()
        {
            InitializeComponent();
        }

        private void Form9_Load(object sender, EventArgs e)
        {
            strKeyName = "keyLoaded";
            // Path to file on Windows NT: C:\WinNT\Profiles\<Profile Name>\NtUser.Dat
            // Path to file on Windows 2000: C:\Documents and Settings\<Profile Name>\NtUser.Dat
    
            textBox1.Text = "<Path to File>";
            button2.Enabled = false;

            bool bRetval = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVLEGES | TOKEN_QUERY, 
                        out MyToken);
            if (!bRetval) MessageBox.Show("OpenProcess Error");
            
            bRetval = LookupPrivilegeValue(null, SE_RESTORE_NAME, out RestoreLuid);
            if (!bRetval) MessageBox.Show("LookupPrivilegeValue Error");
    
            bRetval = LookupPrivilegeValue(null, SE_BACKUP_NAME, out BackupLuid);
            if (!bRetval) MessageBox.Show("LookupPrivilegeValue Error");
            
            TP.PrivilegeCount = 2;
            TP.Privileges[0].pLuid = RestoreLuid;
            TP.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            TP.Privileges[1].pLuid = BackupLuid;
            TP.Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;

            bRetval = AdjustTokenPrivileges(MyToken, false, ref TP, 0, IntPtr.Zero, IntPtr.Zero);
            if (!bRetval) MessageBox.Show("AdjustTokenPrivileges Error");
        }

        private void buttonLoad_Click(object sender, EventArgs e)
        {
            long Retval = RegLoadKey(HKEY_USERS, strKeyName, textBox1.Text);
            if(Retval != 0) MessageBox.Show("RegLoadKey Error");
            button2.Enabled = true;
        }

        private void buttonUnload_Click(object sender, EventArgs e)
        {
            long Retval = RegUnLoadKey(HKEY_USERS, strKeyName);
            if (Retval != 0) MessageBox.Show("RegUnLoadKey Error");
        }

        private void Form9_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool bRetval = AdjustTokenPrivileges(MyToken, true, ref TP, 0, IntPtr.Zero, IntPtr.Zero);
            if (!bRetval) MessageBox.Show("AdjustTokenPrivileges Error");
        }
    }
}

Open in new window

0
 
LVL 1

Author Comment

by:kerzner
ID: 34312080
Thanks! That code works great in VB. For whatever reason it did not want to run properly under .NET (AdjustTokenPrivileges was always failing), but I guess I will keep it in a VB app and run it from my own app. So problem solved!
0
 
LVL 16

Expert Comment

by:kris_per
ID: 34312934

Great. Glad I could help a bit.
0

Featured Post

Flexible connectivity for any environment

The KE6900 series can extend and deploy computers with high definition displays across multiple stations in a variety of applications that suit any environment. Expand computer use to stations across multiple rooms with dynamic access.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to record audio from input sources to your PC ā€“ connected devices, connected preamp to record vinyl discs, streaming media, that play through your audio card: Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10 ā€“ both 32 bit & 64.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to ā€¦
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial sā€¦

837 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question