![]() |
NetLocalGroupAdd funktioniert nicht
Hallo zusammen,
ich möchte mir ein paar Befehle aus dem MSDN Library in einer Unit zusammenschreiben. Nur irgendwie komme ich nicht ganz damit zurecht das in Delphi zuschreiben. Hier meine Übersetzung :
Delphi-Quellcode:
Wenn ich jetzt die Funktion "AddGroups" so aufrufe :
type
LOCALGROUP_INFO_0 = record // Gruppenname lgrpi0_name : LPWSTR; end; PLOCALGROUP_INFO_0 = ^LOCALGROUP_INFO_0; LOCALGROUP_INFO_1 = record // Gruppenname + Kommentar lgrpi1_name : LPWSTR; lgrpi1_comment : LPWSTR; end; PLOCALGROUP_INFO_1 = ^LOCALGROUP_INFO_1; function NetLocalGroupAdd(servername : PWideChar; level : Integer; buf: PChar; parm_err : Integer) : DWORD; stdcall; external 'netapi32.dll'; function AddGroups(wServer, wGroupName, wComment : WideString):DWORD; var info : PLOCALGROUP_INFO_1; parmerr : Integer; begin parmerr := 0; info.lgrpi1_comment := PWideChar(wComment); info.lgrpi1_name := PWideChar(wGroupName); result := NetLocalGroupAdd (PWideChar (wServer), 1, PChar(@info), parmerr); end;
Delphi-Quellcode:
Bekomme ich eine EAccessViolation in Zeile 22. Warum passiert das ? Ich sehe mal wieder den Wald vor lauter Bäumen nicht.
AddGroups('.', 'Testgruppe', 'Erstellen einer Gruppe Testen');
|
Re: NetLocalGroupAdd funktioniert nicht
Die Befehle gibts doch schon alle in Windows.pas ?
Zitat:
![]() Wenn du Unicodeparameter verwendest, dann musst du NetLocalGroupAddW verwenden. |
Re: NetLocalGroupAdd funktioniert nicht
Ich denke, dass für info vielleicht vor dem Zugriff Speicher alloziert werden sollte. :wink:
|
Re: NetLocalGroupAdd funktioniert nicht
Zitat:
Zitat:
Delphi-Quellcode:
Nur leider bekomme ich immer noch die EAccessViolation in der Zeile 14. Das heißt also wenn ich Speicher alloziere mit GetMem hilft mir auch nicht weiter.
function AddGroups(wServer, wGroupName, wComment : String;):DWORD;
var info : ^PLOCALGROUP_INFO_1; wTempComment : WideString; wTempGroupName : WideString; wTempServer : WideString; parmerr: DWORD; begin wTempComment := wComment; wTempGroupName := wGroupName; wTempServer := wServer; parmerr := 0; GetMem(info,sizeOf(info)); info^.lgrpi1_comment := PWideChar(wTempComment); info^.lgrpi1_name := PWideChar(wTempGroupName); result := NetLocalGroupAdd (PWideChar(wTempServer), 1, @info, parmerr); end; |
Re: NetLocalGroupAdd funktioniert nicht
Zitat:
1. Deine Deklaration ist falsch 2. Deine Verwendung ist falsch. Verwendest du vordefinierte Header, dann hast du nur noch den Fall 2. Setze mal const in die Parameterliste für die Parameter deiner Funktion. Außerdem hast du für die Info Variable einen Pointer auf einen Pointer. Mit GetMem allokierst du Speicher für den Pointer. Und dann übergibst du den Pointer nocht mit dem Addressoperator. Entweder du deklarierst die Info-variable auf dem Stack (ohne Pointer!!! also LOCALGROUP_INFO_1) und übergibst sie mit dem Addressoperator (@) --- oder du erstellst die Variable auf dem Heap mit GetMem (PLOCALGROUP_INFO_1) und verwendest dafür kein Addressoperator bei der Funktion. Aber nicht mischen. Du verwendest eine Ansicode Deklaration der Funktion. Definierst sie aber als Unicode. Dann solltest du sie auch als Unicode laden! Setze ein W ans Ende der Funktion!!!!!
Delphi-Quellcode:
function NetLocalGroupAdd(servername: LPCWSTR; level: DWORD; buf: LPBYTE; parm_err: LPDWORD): NET_API_STATUS; external netapi32 name 'NetLocalGroupAddW';
Deine Deklaration ist falsch.
Delphi-Quellcode:
Laut MSDN für
function NetLocalGroupAdd(servername : PWideChar; level : Integer; buf: PChar;
parm_err : Integer) : DWORD; stdcall; external 'netapi32.dll'; ![]()
Code:
Der Parameter parm_err kann durch den out Typ auch so deklariert werden: "out parm_err : DWORD". Wenn es in/out ist, dann verwenden wir in Delphi "var".
NET_API_STATUS NetLocalGroupAdd(
__in LPCWSTR servername, __in DWORD level, __in LPBYTE buf, __out LPDWORD parm_err ); Pass auf welche Datentype du verwendest. Deine Deklaration verwendet für den zweiten und vierten Parameter ein Integer. Jedoch wird ein DWORD (Cardinal) erwartet. Das sind ganz andere Datentypen. Mein Rat ist, dass du erstmal die vordefinierten WindowsAPI Funktionen verwenden solltest. Wenn das klappt, kannst du immernoch Headerkonvertierung machen. Aber wie du gesehen hast, kann man viel falsch machen. Im schlimmsten Fall funktioniert es in 80% aller Fälle. |
Re: NetLocalGroupAdd funktioniert nicht
Deklarier die Übergabeparameter auch mal als WideString.
|
Re: NetLocalGroupAdd funktioniert nicht
Also, ich habe mir jetzt den Rat von Dezipaitor zu Herzen genommen und es mit der Unit JclWin32 probiert. Ich habe ein Beispielprojekt gemacht. Hier der Code dazu :
Delphi-Quellcode:
Nur leider erhalte ich folgende Fehlermeldung in Zeile 15:
procedure TForm10.Button1Click(Sender: TObject);
var info : Pointer; parmerr : LPDWORD; wComment: WideString; wGroupName: WideString; nerr: Cardinal; begin wComment := Edit2.Text; wGroupName := Edit1.Text; parmerr := nil; GetMem(info,sizeOf(PLOCALGROUP_INFO_1)); PLOCALGROUP_INFO_1(info)^.lgrpi1_comment := PWideChar(wComment); PLOCALGROUP_INFO_1(info)^.lgrpi1_name := PWideChar(wGroupName); nerr := NetLocalGroupAdd(PWideChar('.'), 1, @info, parmerr); if nerr = 0 then ShowMessage('Gruppe erfolgreich erstellt') else ShowMessage('Fehlermeldung : ' + IntToStr(nerr)); end; --------------------------- Project12 --------------------------- Zugriffsverletzung bei Adresse 7C9112F1 in Modul 'ntdll.dll'. Lesen von Adresse 0000002E. --------------------------- OK --------------------------- Was habe ich denn jetzt nun wieder falsch gemacht ? Bin ich wieder mit der Adressierung drucheinander gekommen ? |
Re: NetLocalGroupAdd funktioniert nicht
hehe, jedesmal wenn du Änderungen machst, hast du etwas geändert, was niemand gewollt hat.
Ich sehe, dass du keine Ahnung von Pointern hast und eigentlich nur ausprobierst. Such dir mal (oder frage im Forum) Tutorials über Pointerarithmetik.
Delphi-Quellcode:
Hier verwendest du plötzlich einen untypisierten Pointer. KA warum.
var
info : Pointer;
Delphi-Quellcode:
Das GetMem ist falsch. Mit "sizeOf(PLOCALGROUP_INFO_1)" bekommst du die Größe des Zeigers und nicht die der Struktur. Auf 32Bit Systemen kommt immer 4 raus.
parmerr : LPDWORD;
wComment: WideString; wGroupName: WideString; nerr: Cardinal; begin wComment := Edit2.Text; wGroupName := Edit1.Text; parmerr := nil; GetMem(info,sizeOf(PLOCALGROUP_INFO_1)); Es sollte also LOCALGROUP_INFO_1 sein, für das 8 rauskommt. Zudem erstellst du Speicher für Info, jedoch nicht "parmerr" was ja auch ein Pointer ist (LP... -> Long Pointer).
Delphi-Quellcode:
Hier übergibst du per @-Operator einen Zeiger an die Funktion. Das bedeutet du übergibst die Speicheraddresse des Zeigers an die Funktion.Sozusagen ein Zeiger auf einen Zeiger.
PLOCALGROUP_INFO_1(info)^.lgrpi1_comment := PWideChar(wComment);
PLOCALGROUP_INFO_1(info)^.lgrpi1_name := PWideChar(wGroupName); nerr := NetLocalGroupAdd(PWideChar('.'), 1, @info, parmerr); Resultat: Buffer Overflow (Zugriffsverletzung im besten Fall). Ich hab dir schon geschrieben (was du nicht gelesen oder nicht verstanden hast), dass man einfach LOCALGROUP_INFO_1 als Variablentyp nimmt und kein GetMem verwendet, dafür die Variable mit @ der API-Funktion übergibt. Oder, dass man PLOCALGROUP_INFO_1 mit GetMem verwendet und dafür @ nicht verwendet. Dasselbe gilt für "parmerr". Hättest du keinen untypisierten Zeiger für "info" verwendet, dann müsstest du kein Type-Cast machen. Ich lege dir dringend nahe, dass du dich mit Zeigern beschäftigen solltest, bevor du weitermachst. |
Re: NetLocalGroupAdd funktioniert nicht
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:52 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