![]() |
Speicher freigeben, der noch gebraucht wird
Folgende Funktion:
Delphi-Quellcode:
Wenn ich den Zeiger SecDescriptor in der Funktion freigeben ist der Rückgabewert natürlich ungülig. aber wie und wo geben ich den Speicher wieder frei bzw. wie bekomme ich den Zeiger als Ergebnis ohne mir ein Speicherleck einzuhandeln?
function GetProcessOwner(PID: DWord; var SID: PSID): Boolean;
var hProcess : THandle; ppsidOwner : PSID; SecDescriptor : PSECURITY_DESCRIPTOR; err : DWord; const SE_UNKNOWN_OBJECT_TYPE: DWord = 0; SE_FILE_OBJECT : DWord = 1; SE_SERVICE : DWord = 2; SE_PRINTER : DWord = 3; SE_REGISTRY_KEY : DWord = 4; SE_LMSHARE : DWord = 5; SE_KERNEL_OBJECT : DWord = 6; SE_WINDOW_OBJECT : DWord = 7; begin hProcess := 0; err := 0; try hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or GENERIC_READ, False, pid); if (hProcess <> 0) then begin err := GetSecurityInfo(hProcess, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, @ppsidOwner, nil, nil, nil, @SecDescriptor); if (err = 0) then begin SID := ppsidOwner; //LocalFree(Cardinal(SecDescriptor)); end; CloseHandle(hProcess); end; except end; Result := (err = 0) and (hProcess <> 0); end; |
Re: Speicher freigeben, der noch gebraucht wird
Kopie erstellen. Kopiere den Inhalt in den SSID Zeiger, welchen du übergibst.
|
Re: Speicher freigeben, der noch gebraucht wird
Das wäre dann MemCopy oder wie heißt die Funktion?
|
Re: Speicher freigeben, der noch gebraucht wird
Joa, MemCopy oder das gute alte Pascal Move(), etc
Nochmals im Detail: Grundlegend: Du hast Speicheradresse angegeben welcher er einen Zeiger auf von ihm alloziierten Speicher zurück gibt. Genauso bekommt deine Funktion beim Aufruf einen Zeiger auf einen vom Aufrufer bereitgestellten Speicherplatz zur Verfügung. Nun hast du zwei Speicherplätze von denen du einen füllen sollst und den anderen musst du wieder freigeben. Du könntest natürlich auf das freigeben verzichten und einfach den Zeiger von dem Aufrufer auf den anderen Speicher zeigen lassen. Damit wäre dann der vom Aufrufer bereitgestellte Speicher verloren und der Aufrufer bekommt seine Daten im fremden Speicher. Von daher: kopieren. Das du den Pointer des Aufrufers (SSID) überhaupt verbiegen kannst ist eigentlich schon bedenklich. Im Normalfall sollte das konstant sein und dadurch kann sich der Aufrufer sicher sein, dass sein beim Aufruf angegebener Speicher auch nach dem Aufruf immernoch der gleiche ist. |
Re: Speicher freigeben, der noch gebraucht wird
Ich hatte es erst so:
Delphi-Quellcode:
Ich übergebe eigentlich gerne var Paramter, damit ich den Rückgabewert zum Überprüfen, ob die Funktion erfolgreich war oder nicht nutzen kann.
function GetProcessOwner(PID: DWord; var SID: PSID): Boolean;
var hProcess : THandle; pSIDDummy : PSID; SecDescriptor : PSECURITY_DESCRIPTOR; err : DWord; const SE_UNKNOWN_OBJECT_TYPE: DWord = 0; SE_FILE_OBJECT : DWord = 1; SE_SERVICE : DWord = 2; SE_PRINTER : DWord = 3; SE_REGISTRY_KEY : DWord = 4; SE_LMSHARE : DWord = 5; SE_KERNEL_OBJECT : DWord = 6; SE_WINDOW_OBJECT : DWord = 7; begin hProcess := 0; err := 0; try hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or GENERIC_READ, False, pid); if (hProcess <> 0) then begin err := GetSecurityInfo(hProcess, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, @pSIDDummy, nil, nil, nil, @SecDescriptor); if (err = 0) then begin SID := pSIDDummy; //LocalFree(Cardinal(SecDescriptor)); end; CloseHandle(hProcess); end; except end; // Successfull if err = 0 AND hProcess <> 0 Result := (err = 0) and (hProcess <> 0); end; Wie würdest du es denn machen? |
Re: Speicher freigeben, der noch gebraucht wird
Zitat:
Von daher würde ich es so machen:
Delphi-Quellcode:
Warum gibst du überhaupt den SecDescriptor an, wenn du ihn nicht nutzt? Dann würde ein NIL dort auch vollkommen reichen. Aber ich gehe mal davon aus, dass du ihn später noch nutzen willst, von daher gebe ich ihn mit frei.
function GetProcessOwner(const PID: DWord; const SID: PSID): Boolean;
var hProcess : THandle; SecDescriptor : PSECURITY_DESCRIPTOR; err : DWord; const SE_UNKNOWN_OBJECT_TYPE: DWord = 0; SE_FILE_OBJECT : DWord = 1; SE_SERVICE : DWord = 2; SE_PRINTER : DWord = 3; SE_REGISTRY_KEY : DWord = 4; SE_LMSHARE : DWord = 5; SE_KERNEL_OBJECT : DWord = 6; SE_WINDOW_OBJECT : DWord = 7; begin Result := false; try hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or GENERIC_READ, False, pid); try if (hProcess <> 0) then begin err := GetSecurityInfo(hProcess, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, @SID, nil, nil, nil, @SecDescriptor); try // was du hier auch immer noch mit dem SecDescriptor machen willst, tue es hier... Result := ( err = 0 ); // am Ende. Wenn irgendwas schiefgeht springt er in finally und diese Zuweisung wird nie ausgeführt... finally LocalFree(SecDescriptor); end; end; finally CloseHandle(hProcess); end; except ; // böses Karma... end; end; Grundsätzlich programmiere ich solche Funktionen, welche viele Bedingunen haben bis sie zum endgültigen Aufruf kommen, so, dass ich Result auf false setze und bei erfolgreicher Ausführung der Funktion in der tiefen Bedingung kann ich True setzen. Damit ist bei allen anderen Fehlern, Exceptions etc ein False als Result. Damit spare ich mir auch das zuweisen von lokalen Variablen auf einen initialisierten Wert, die dann eh immer zugewiesen werden (siehe hProcess). So, gute Nacht! |
Re: Speicher freigeben, der noch gebraucht wird
Also, dass man dort auch nil angeben kann, habe ich nicht gewusst. Geht aber. Und da ich ihn eigentlich gar nicht weiter brauche, gebe ich da jetzt auch nil an und habe keinen Ärger mit dem Speicher. Allerdings den Parametr als const angeben geht nicht, denn dann kann in ihn nichts geschrieben werden und er bleibt leer. ;)
Danke noch mal für deine Hilfe. |
Re: Speicher freigeben, der noch gebraucht wird
Zitat:
![]() |
Re: Speicher freigeben, der noch gebraucht wird
Moin Michael,
Zitat:
Delphi kapselt die Vorgehensweise ja nur. |
Re: Speicher freigeben, der noch gebraucht wird
Zitat:
Code:
void ChangeIt(int &i)
{ i = 5; } [...] { int i = 0; ChangeIt(i); [...] } |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 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