AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

NetUserEnum die 2.

Ein Thema von CalganX · begonnen am 7. Feb 2003 · letzter Beitrag vom 21. Apr 2012
Antwort Antwort
Seite 2 von 3     12 3      
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#1
  Alt 7. Feb 2003, 14:11
Ätsch, Bätsch ausgetrickst. Wenn ich
inc(integer(aWorkBuffer), sizeOf(PUSERINFO0)); mache gibts kein Problem, aber nachdem ich nun einfach
inc(aWorkBuffer); {oder} inc(integer(aWorkBuffer)); mache, dann gibts ne' AccessViolation...

Chris
  Mit Zitat antworten Zitat
MiKaEr
(Gast)

n/a Beiträge
 
#2

AW: NetUserEnum die 2.

  Alt 20. Apr 2012, 20:57
ich finde bei mir den fehler leider nicht. es kommt eine unerklärliche AV beim lesen von irgendetwas. es wird der nutzername Administrator in meine ListBox geschrieben mehr aber nicht. das ist erst passiert als ich das record _USER_INFO_0 um password, password_age und home_dir erweitert habe:

Delphi-Quellcode:
unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

type
 TForm1 = class(TForm)
  ListView1: TListView;
  ListBox1: TListBox;
  procedure FormCreate(Sender: TObject);
 private
  { Private-Deklarationen }
 public
  { Public-Deklarationen }
 end;

var
 Form1: TForm1;

const
 NERR_Success = 0;

function NetApiBufferAllocate(ByteCount: DWORD; var Buffer: Pointer): DWORD; stdcall; external 'netapi32.dll';
function NetGetDCName(servername: LPCWSTR; domainname: LPCWSTR; bufptr: Pointer): DWORD; stdcall; external 'netapi32.dll';
function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external 'netapi32.dll';
function NetWkstaGetInfo(servername: LPWSTR; Level: DWORD; bufptr: Pointer): Longint; stdcall;
 external 'netapi32.dllname 'NetWkstaGetInfo';

function NetUserEnum(servername: LPCWSTR; Level: DWORD; filter: DWORD; var bufptr: Pointer; prefmaxlen: DWORD;
 var entriesread: DWORD; var totalentries: DWORD; resume_handle: PDWORD): DWORD; stdcall; external 'netapi32.dll';

type
 WKSTA_INFO_100 = record
  wki100_platform_id: DWORD;
  wki100_computername: LPWSTR;
  wki100_langroup: LPWSTR;
  wki100_ver_major: DWORD;
  wki100_ver_minor: DWORD;
 end;

 LPWKSTA_INFO_100 = ^WKSTA_INFO_100;

 _USER_INFO_0 = record
  usri1_name: LPWSTR;
  usri1_password: LPWSTR;
  usri1_password_age: DWORD;
  usri1_home_dir: LPWSTR;
 end;

 TUserInfo0 = _USER_INFO_0;

function NetUserChangePassword(Domain: PWideChar; UserName: PWideChar; OldPassword: PWideChar; NewPassword: PWideChar)
 : Longint; stdcall; external 'netapi32.dllname 'NetUserChangePassword';

implementation

{$R *.dfm}

function GetNetParam(AParam: integer): string;
var
 PBuf: LPWKSTA_INFO_100;
 Res: Longint;
begin
 result := '';
 Res := NetWkstaGetInfo(nil, 100, @PBuf);
 if Res = NERR_Success then
  begin
   case AParam of
    0:
     result := string(PBuf^.wki100_computername);
    1:
     result := string(PBuf^.wki100_langroup);
   end;
  end;
end;

function GetComputerName: string;
begin
 result := GetNetParam(0);
end;

function GetDomainName: string;
begin
 result := GetNetParam(1);
end;

function GetDomainControllerName(const ADomainName: string): string;
var
 wDomainName: WideString;
 Controller: PWideChar;
begin
 wDomainName := ADomainName;
 NetGetDCName(nil, PWideChar(wDomainName), @Controller);
 result := WideCharToString(Controller);
 NetApiBufferFree(Controller);
end;

procedure GetUsers(Users: TStrings; AServer: string);
type
 TUserInfoArr = array [0 .. 3] of TUserInfo0;
var
 UserInfo: Pointer;
 entriesread, totalentries, ResumeHandle: DWORD;
 Res: DWORD;
 i: integer;
 FServer: WideString;
begin
 FServer := AServer;
 ResumeHandle := 0;
 repeat
  Res := NetUserEnum(PWideChar(FServer), 0, 0, UserInfo, 64 * 3, entriesread, totalentries, @ResumeHandle);
  if (Res = NERR_Success) or (Res = ERROR_MORE_DATA) then
   begin
    for i := 0 to entriesread - 1 do
     Users.Add(TUserInfoArr(UserInfo^)[i].usri1_name);
    NetApiBufferFree(UserInfo);
   end;
 until Res <> ERROR_MORE_DATA;
end;

function isPw(const User, Password: string): Boolean;
var
 Err: LongWord;
begin
 Err := NetUserChangePassword(nil, PWideChar(WideString(User)), PWideChar(WideString(Password)),
  PWideChar(WideString(Password)));
 result := Err = 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 GetUsers(ListBox1.Items, '');
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#3

AW: NetUserEnum die 2.

  Alt 20. Apr 2012, 21:58
Und warum wird schonwieder alles Wichtige unterschlagen?


Wie genau lautet die Fehlermeldung? (der Vorschlag mit Strg+C ist immernoch sehr zu empfehlen)

An welcher Stelle tritt sie auf? (auch wenn meine schon fast eine Vermutung hat)

Wie kommst du auf die saudämliche Idee diesen Record verändern zu wollen und warum hast du genau diese neuen Felder dort so reingemacht?
Das Format dieser Puffer ist genau definiert und der Aufbau ist über MSDN-Library durchsuchenNetUserEnum zu finden und deinen Aufbau dieser Records kann ich nirgendwo entdecken.

Da du immernoch den Info-Level 0 abfragst, muß es zwangsweise schief gehn, denn dort ist ausschließlich das Feld "name" vorhanden.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (20. Apr 2012 um 22:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

AW: NetUserEnum die 2.

  Alt 20. Apr 2012, 22:00
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  NERR_Success = 0;
  MAX_PREFERRED_LENGTH = DWORD(-1);

type
  NET_API_STATUS = DWORD;
  TEnumUers = function(Username: string; cntUsers: Integer; Data: Pointer): Boolean;

  TUserInfo1 = record
    usri1_name: LPWSTR;
    usri1_password: LPWSTR;
    usri1_password_age: DWORD;
    usri1_priv: DWORD;
    usri1_home_dir: LPWSTR;
    usri1_comment: LPWSTR;
    usri1_flags: DWORD;
    usri1_script_path: LPWSTR;
  end;
  PUserInfo1 = ^TUserInfo1;

   function NetUserEnum(servername: LPCWSTR; level: DWORD; filter: DWORD; var buf: Pointer; prefmaxlen: DWORD; var
  entriesred: DWORD; var totalentries: DWORD; resumehandle: PDWORD): NET_API_STATUS; stdcall;
 function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall;

var
  Form1: TForm1;

implementation

const
  netapi32lib = 'netapi32.dll';

function NetUserEnum; external netapi32lib name 'NetUserEnum';
function NetApiBufferFree; external netapi32lib name 'NetApiBufferFree';

{$R *.dfm}

function EnumUsersCallback(Username: string; cntUsers: Integer; Data: Pointer): Boolean;
begin
  TListBox(Data).Items.Add(Username);
  Result := True;
end;

function EnumUsers(const Server: WideString; filter: DWORD; Callback: TEnumUers; Data: Pointer): DWORD;
var
  ui1 : Pointer;
  pWork : Pointer;
  EntriesRead : DWORD;
  EntriesTotal : DWORD;
  NetError : DWORD;
  Loop : Integer;
begin
  ui1 := nil;
  pWork := nil;
  try
    NetError := NetUserEnum(PWideChar(Server), 0, filter, ui1, MAX_PREFERRED_LENGTH, EntriesRead, EntriesTotal, nil);
    if (NetError = NERR_SUCCESS) and (EntriesRead > 0) then
    begin
      pWork := ui1;
      if Assigned(Callback) then
      begin
        for Loop := 0 to EntriesRead - 1 do
        begin
          if not Callback(PUserInfo1(ui1)^.usri1_name, EntriesRead, Data) then
            break;
          Inc(Integer(ui1), sizeof(Pointer));
        end;
      end;
    end;
  finally
    NetApiBufferFree(pWork);
  end;
  Result := NetError;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Data: Pointer;
begin
  Data := nil;
  EnumUsers('', 0, @EnumUsersCallback, Form1.Listbox1);
end;

end.
Anwendungsbeispiel für meine Unit MpuNTUser: http://michael-puff.de/Programmierung/Delphi/Units/

Wenn du meine Unit benutzt, dann brauchst du natürlich nur die Callback implementieren und die Funktion EnumUsers aufrufen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#5

AW: NetUserEnum die 2.

  Alt 20. Apr 2012, 22:19
@Luckie: Ein Level-1-Info-Record, aber ebenfalls Level 0 als Abfrageparameter?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.123 Beiträge
 
Delphi 11 Alexandria
 
#6
  Alt 7. Feb 2003, 14:12
Moin Chris,

nein, muss es nicht.

So hab' ich das gemacht

Delphi-Quellcode:
function NetUserEnum(
  const servername: LPCWSTR;
  const level: DWORD;
  const filter: DWORD;
  const bufptr: Pointer;
  const prefmaxlen: DWORD;
  var entriesread: DWORD;
  var totalentries: DWORD;
  const resume_handle: PDWORD
): NET_API_STATUS; stdcall; external 'netapi32.dll';

function NetApiBufferFree(const pBuffer : Pointer): NET_API_STATUS; stdcall; external 'netapi32.dll';


procedure TfrmMAIN.miFileOpenClick(Sender: TObject);

var
  rui0Work : PUSER_INFO_0;
  rui0Save : PUSER_INFO_0;
  dwEntriesRead : DWORD;
  i : integer;
begin
  if NetUserEnum(nil, 0, FILTER_NORMAL_ACCOUNT, @rui0Work, MAX_PREFERRED_LENGTH,
                 dwEntriesRead, dwEntriesRead, nil) = NERR_SUCCESS then begin
    rui0Save := rui0Work;
    for i:=1 to dwEntriesRead do
    begin
      ListBox1.Items.Add(rui0Work.usri0_name);
      [color=red]inc(rui0Work);[/color]
    end;
  end;
  NetAPIBufferFree(rui0Save);
end;
und es funktioniert einwandfrei.

(Ich hab' sogar mal die Funktionsdeklarationen benutzt, wie es die Jedis machen)
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#7
  Alt 7. Feb 2003, 14:16
HILFE!!!! Ich drehe hier noch durch. Also, wenn ich das mache, was du gemacht hast, dann kommt:
Zitat:
[Error] UserInfo.pas(20): Types of actual and formal var parameters must be identical
Allerdings ist bei mir bufptr mit var versehen und so steht es auch bei den Jedis...

Chris
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.123 Beiträge
 
Delphi 11 Alexandria
 
#8
  Alt 7. Feb 2003, 14:17
Moin Luckie,

dann nimm meinetwegen die Jedi Units:

Delphi-Quellcode:
procedure TfrmMAIN.miFileOpenClick(Sender: TObject);

type
  PUserInfo0 = ^TUserInfo0;
  _USER_INFO_0 = record
    usri0_name: LPWSTR;
  end;
  TUserInfo0 = _USER_INFO_0;
  USER_INFO_0 = _USER_INFO_0;

var
  rui0Work : PUserInfo0;
  rui0Save : PUserInfo0;
  dwEntriesRead : DWORD;
  i : integer;
begin
  if NetUserEnum(nil, 0, FILTER_NORMAL_ACCOUNT, @rui0Work, MAX_PREFERRED_LENGTH,
                 dwEntriesRead, dwEntriesRead, nil) = NERR_SUCCESS then begin
    rui0Save := rui0Work;
    for i:=1 to dwEntriesRead do
    begin
      ListBox1.Items.Add(rui0Work.usri0_name);
      inc(rui0Work);
    end;
  end;
  NetAPIBufferFree(rui0Save);
end;
Mein Methode funktioniert trotzdem
(Auch ohne die Jedi Deklarationen anzufassen)
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#9
  Alt 7. Feb 2003, 14:22
Also, nochmal *wimmer*:
Delphi-Quellcode:
procedure ListAllUsers(hTreeView: DWORD; hMasterParent: Cardinal; var iEntriesRead: Cardinal);
var
  aTempIStruct: TTVInsertStruct;
  aUserBuffer, aWorkBuffer: PUSERINFO0;
  dwEntriesRead: Cardinal;
  i: integer;
  sTemp: string;
begin
  aTempIStruct.item.mask := TVIF_TEXT;
{27 =>}  if NetUserEnum(nil, 0, FILTER_NORMAL_ACCOUNT, @aUserBuffer{<=}, MAX_PREFERRED_LENGTH,
                 dwEntriesRead, dwEntriesRead, nil) = NERR_SUCCESS then begin
    aWorkBuffer := aUserBuffer;
    for i:=0 to dwEntriesRead-1 do begin
      aTempIStruct.hParent := Pointer(hMasterParent);
      sTemp := {PUserInfo0(}aWorkBuffer{)^}.usri0_name;
      aTempIStruct.item.pszText := @sTemp[1];
      SendMessage(hTreeView, TVM_INSERTITEM, 0, integer(@aTempIStruct));

      inc({integer(}aWorkBuffer{), sizeOf(PUSERINFO0)});
    end;
  end;
  NetAPIBufferFree(aUserBuffer);
end;
Kommentare deswegen, dass ich alles schnell wiederrückgängig machen kann.
Nun, wenn ich das so mache (die Typen-deklarationen sind bereits in den Units drin; das gleiche, wenn ich sie reinschreibe), dann gibts den Fehler:
Zitat:
[Error] UserInfo.pas(27): Types of actual and formal var parameters must be identical
Chris
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.123 Beiträge
 
Delphi 11 Alexandria
 
#10
  Alt 7. Feb 2003, 14:30
Moin Chris,

könntest Du bitte auch noch mal markieren, was denn Zeile 27 ist?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 01:24 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