AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Profilverzeichnisse aller Nutzer ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Profilverzeichnisse aller Nutzer ermitteln

Ein Thema von Dalai · begonnen am 15. Feb 2014 · letzter Beitrag vom 17. Feb 2014
Antwort Antwort
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.684 Beiträge
 
Delphi 5 Professional
 
#1

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 16. Feb 2014, 14:19
Wenn die API wirklich diese Informationen nicht zur Verfügung stellt, sollte es doch über die Registryzweige unter HKEY_USERS gehen, oder? Dort liegen ja die einzelnen Userzweige und der des aktuellen Users wird beim Login unter HKEY_CURRENT_USER eingeblendet.
Nein, Irrtum. Unter HKEY_USERS sind nur die Zweige der Nutzer eingeblendet, die derzeit angemeldet sind (siehe Wikipedia). Davon abgesehen komme ich dort weder an den Nutzernamen (Loginname) noch ans Profilverzeichnis.

-----

Ich hab gestern noch eine Lösung erarbeitet, die ganz gut funktioniert, aber wie immer wäre es schön, wenn das irgendwie schöner ginge. Im Grunde wird hier folgendes gemacht:
  • Ermittlung aller auf dem System existierenden Nutzernamen mit NetUserEnum (Level 0)
  • Ermittlung der SID zu jedem Nutzernamen mit GetAccountSid
  • Öffnen des Registry-Schlüssels HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList mit der SID und Auslesen (und Expandieren von Umgebungsvariablen) von ProfileImagePath
Delphi-Quellcode:
function GetAccountSid(const Server, User: WideString; var Sid: PSID): DWORD;
function ConvertSidToStringSid(SID: PSID; var StringSid: LPSTR): Boolean; stdcall;
    external 'advapi32.dllname 'ConvertSidToStringSidA';

implementation


function ExpandEnvStr(const sInput: string): string;
const
  MAXSIZE = 32768; // laut PSDK sind 32k das Maximum
begin
  SetLength(Result, MAXSIZE);
  SetLength(Result,
            ExpandEnvironmentStrings(PChar(sInput), @Result[1], Length(Result))-1);
            //-1 um abschließendes #0 zu verwerfen
end;


function GetAccountSid(const Server, User: WideString; var Sid: PSID): DWORD;
var
  dwDomainSize, dwSidSize: DWord;
  R : LongBool;
  wDomain : WideString;
  Use : DWord;
begin
  Result := 0;
  SetLastError(0);
  dwSidSize := 0;
  dwDomainSize := 0;
  R := LookupAccountNameW(PWideChar(Server), PWideChar(User), nil, dwSidSize,
    nil, dwDomainSize, Use);
  if (not R) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
  begin
    SetLength(wDomain, dwDomainSize);
    Sid := GetMemory(dwSidSize);
    R := LookupAccountNameW(PWideChar(Server), PWideChar(User), Sid,
      dwSidSize, PWideChar(wDomain), dwDomainSize, Use);
    if not R then
    begin
      FreeMemory(Sid);
      Sid := nil;
    end;
  end
  else
    Result := GetLastError;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  EntriesRead, TotalEntries, ResumeHandle : DWORD;
  UserInfo : lpUSER_INFO_0;
  lpBuffer : Pointer;
  i : Integer;
  Res : LongWord;
  sl : TStringList;
  sSID : PChar;
  ptrSID : PSID;
  reg : TRegistry;
begin
    ListBox1.Clear;
    sl:= TStringList.Create;
    ResumeHandle := 0;
    repeat
        Res:= NetUserEnum(nil, 0, 0, lpBuffer, 0, EntriesRead, TotalEntries, ResumeHandle);

        if (Res = NERR_SUCCESS) or (Res = ERROR_MORE_DATA) then
        begin
            UserInfo := lpBuffer;
            for i := 0 to EntriesRead-1 do
            begin
                sl.Add(WideCharToString(UserInfo^.usri0_name));
                ListBox1.Items.Add('------------------------------------------');
                ListBox1.Items.Add(WideCharToString(UserInfo^.usri0_name));
                Inc(UserInfo);
            end;
            NetApiBufferFree(lpBuffer);
        end;
   until (Res <> ERROR_MORE_DATA);

   for i:=0 to sl.Count-1 do
   begin
       GetAccountSid('', sl[i], ptrSID);
       if ConvertSidToStringSid(ptrSID, sSID) then
       begin
           ListBox1.Items.Add(sSID);
           reg:= TRegistry.Create;
           reg.RootKey:= HKEY_LOCAL_MACHINE;
           if reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\' + sSID) then
               ListBox1.Items.Add(ExpandEnvStr(reg.ReadString('ProfileImagePath')));
           reg.CloseKey;
           reg.Free;
       end;
   end;
   sl.Free;
end;
Hinweis: Das ist nur ein Testprojekt, daher an einigen Stellen keine Auswertung der Funktionsrückgaben und alles in der Methode Button1Click. Die Funktion GetAccountSid hab ich von Luckie gemopst. Die Implementation in Delphi diente sowieso nur dem Zweck, das einfacher testen und dann nach AutoIt übertragen zu können. Falls jemand Interesse am AutoIt-Code hat, dann einfach fragen . Noch ein Tip für alle Suchmaschinenbenutzer: Die Funktionen ConvertSidToStringSid und GetAccountSid existieren in AutoIt bereits als UDF _Security__SidToStringSid bzw. _Security__GetAccountSid).

MfG Dalai
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz