[python-win32] HKLM\SOFTWARE\...\ProfileList\... registry subkey query

raf raf at raf.org
Thu Sep 6 06:48:08 CEST 2012


hi,

windows-xp/7 python-2.6.2 pywin32-217

ages ago i wrote some code to get a user's home directory on windows
(even if they'd gone into the registry and moved it). i remember it
working when i wrote it but at some point it stopped working. when i
looked into it, it turned out that the registry subkeys no longer
looked like what the code was expecting.

the code was something like:

  import win32api, win32net, win32netcon, win32security, _winreg, re, os
  def user():
    try:
      dc = win32net.NetServerEnum(None, 100, win32netcon.SV_TYPE_DOMAIN_CTRL)
      dcname = r'\\' + dc[0][0]['name'] if dc[0] and isinstance(dc[0][0], dict) else None
    except Exception:
      dcname = None
    return win32net.NetUserGetInfo(dcname, win32api.GetUserName(), 1)['name']
  def home(username=None):
    if username is None:
      username = user()
    sid = win32security.ConvertSidToStringSid(win32security.LookupAccountName(None, username)[0])
    subkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\' + sid
    key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey)
    val, typ = _winreg.QueryValueEx(key, 'ProfileImagePath')
    if typ == _winreg.REG_EXPAND_SZ: # Which it is
      while True:
        match = re.compile('%\w+%').search(val)
        if match is None:
          break
        varname = val[match.start()+1:match.end()-1]
        val = val[0:match.start()] + os.getenv(varname, '') + val[match.end():]
    return val

given the account sid:

  S-1-5-5-21-725345543-1957994488-859522115

it expected to find this registry key:

  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115

inside which it expected to find:

  ProfileImagePath = %SystemDrive%\Documents and Settings\patricia (WindowsXP)
  ProfileImagePath = C:\Users\patricia                             (Windows7)

however, instead of the above registry key, there are:

  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1003
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1004
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1005
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1006
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1008
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-5-21-725345543-1957994488-859522115-1009

each referring to a different user (patricia happens to be the one ending in 1009).

sadly, i've resorted to poking around likely locations
in the file system but that's not very satisfying.
and i'd like to avoid enumerating through all of these
keys and just assuming that the home directory contains
the user's login name (even though that's very likely).

so my questions are:
did the sid for the account name ever uniquely identify the user?
how do i obtain the "1009" that needs to be appended to the sid
to complete it?

i've attached the real code in case it's of any help.

p.s. i know (as of a few minutes ago) that there is a win32profile module
that looks like it should do all of this for me but according to its
documentation, i can only use win32profile.GetUserProfileDirectory()
if i have a token returned by win32security.LogonUser() but i don't
want or need to log the user in (even if i knew their passwords!)
so i have no such token and i can't use that function.

cheers,
raf

-------------- next part --------------
A non-text attachment was scrubbed...
Name: userhome.py
Type: text/x-python
Size: 5037 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-win32/attachments/20120906/f961a60b/attachment.py>


More information about the python-win32 mailing list