[Solved] Crash calling Windows API (netapi32.dll) lazarus / 34-Windows ---------------------------------------------------------------------- ArminLinder · 2017-02-24 10:30 Hi, I try to make calls to the NetAPI32 Windows networking API. Generally I think I got the translation of the C-Style API calls to Pascal conventions right, I can, for instance, query user infos and such using similar code. But this call to NetUserGetLocalGroups gives me headaches: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i implementation {$R *.lfm} uses Windows, CTypes; const  MAX_PREFERRED_LENGTH = DWORD(-1);  NERR_SUCCESS = 0; type  TLocalGroup_Users_Info0 = record    lgrui0_name: LPWSTR;  end;  PTLocalGroup_Users_Info0 = ^TLocalGroup_Users_Info0; function NetUserGetLocalGroups(ServerName, UserName: PWideChar;  Level: DWORD; var Buffer: Pointer; PrefMaxLen: DWORD;  var EntriesRead: DWORD; var TotalEntries: DWORD): DWORD;  stdcall; external 'netapi32.dll'; function NetApiBufferFree(Buffer: pointer): DWORD; stdcall;  external 'netapi32.dll'; { TForm1 } procedure TForm1.ButtonLocalGroupsClick(Sender: TObject); var  dwEntriesRead, dwEntriesTotal: DWORD;  pBuffer: Pointer;  pInfo: PTLocalGroup_Users_Info0;  ServerName,UserName:WideString;  Result : DWORD; begin  ListBox1.Clear;  ServerName := ServerEdit.Text;  UserName := UserEdit.Text;  Result := NetUserGetLocalGroups(PWideChar(Servername), PWideChar(UserName), 0, pBuffer, MAX_PREFERRED_LENGTH, dwEntriesRead, dwEntriesTotal);  If Result = NERR_SUCCESS then    try      pInfo := pBuffer;      while dwEntriesRead > 0 do      begin        ListBox1.Items.Add(pInfo^.lgrui0_name);        Inc(pInfo);        Dec(dwEntriesRead);      end;    finally      NetAPIBufferFree(pBuffer);    end  else    ListBox1.Items.Add('Error ' + IntToStr(Result));end; The call to NetUserGetLocalGroups in the button click handler causes an access violation error (SIGSEV) in samcli!NetUserGetLocalgroups, and I cannot figure out what I possibly have done wrong. There is also plenty of sample code around about this call which looks very similar to mine, I did even try to use some, but all crash the same way. From forum comments I read, the code has once been working, though 10 years ago. Seems something has changed which breaks the old code? Anyone knows why this call fails? Thx Armin. ---------------------------------------------------------------------- balazsszekely · 2017-02-24 11:08 First of all we have a nice unit named jwaWindows. A lot of winapi stuff is declared there, no need to re-delcare variables. Secondly you missing the fourth parameter(Flags) just after Level. See here: https://msdn.microsoft.com/en- us/library/windows/desktop/aa370655(v=vs.85).aspx Thirdly it can be done much simpler. Try something like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses JwaWindows; function NetUserGetLocalGroups(ServerName, UserName: PWideChar;  Level, Flags: DWORD; var Buffer: Pointer; PrefMaxLen: DWORD;  var EntriesRead: DWORD; var TotalEntries: DWORD): DWORD;  stdcall; external 'netapi32.dll'; function NetApiBufferFree(Buffer: pointer): DWORD; stdcall;  external 'netapi32.dll'; { TForm1 } procedure TForm1.Button1Click(Sender: TObject);type  LocalGroupUsers = array[0..ANYSIZE_ARRAY-1] of LOCALGROUP_USERS_INFO_0;  PLocalGroupUsers = ^LocalGroupUsers;var  dwEntriesRead, dwEntriesTotal: DWORD;  pBuffer: PLocalGroupUsers;  I: Integer;  nErr: integer;  ServerName,UserName:WideString;  Result : DWORD;begin  ListBox1.Clear;  ServerName := ServerEdit.Text;  UserName := UserEdit.Text;  Result := NetUserGetLocalGroups(PWideChar(Servername), PWideChar(UserName), 0, LG_INCLUDE_INDIRECT, PByte(pBuffer), MAX_PREFERRED_LENGTH, dwEntriesRead, dwEntriesTotal);  If Result = NERR_SUCCESS then    try      for I := 0 to dwEntriesRead - 1 do      ListBox1.Items.Add(pBuffer^[I].lgrui0_name);    finally      NetAPIBufferFree(pBuffer);    end  else    ListBox1.Items.Add('Error ' + IntToStr(Result));end; ---------------------------------------------------------------------- ArminLinder · 2017-02-24 11:37 Aaaarg. Shame on me. I indeed missed the flags parameter, though I went through the call at least a dozen times. Filled it in, and got success. Thnx, Armin. ---------------------------------------------------------------------- ArminLinder · 2017-02-24 13:08 Aaaaarg #2. Looking deeper into JwaWindows I found it includes a unit JWAlmaccess, which does already contain everything I need to access the Windows network and the local group membership infos specifically. No need to write the api wrappers for netapi32.dll, they are already there. Only the call parameters differ slightly from the approach above, easy fix: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Result := NetUserGetLocalGroups(PWideChar(Servername), PWideChar(UserName), 0, LG_INCLUDE_INDIRECT, PByte(pBuffer), MAX_PREFERRED_LENGTH, @dwEntriesRead, @dwEntriesTotal); Thanks for sticking my nose into the Jedi library, I guess it is going to be a regular companion for me in the future :-) Armin.