@real:
Danke für den Hinweis. Ich hatte es bisher noch nicht ohne Debugger versucht...
Ich bin dabei auf ein seltsames Phänomen gestoßen, das auf einen Fehler in PB 3.94 und PB 4 oder im Win-API deuten könnte:
Wenn ich mit GetFileSecurity() die nötige Puffergröße für den Security Descriptor anfordere, erhalte ich in Variable SecurityDescriptorBufferSize den Wert 36 zurück. Beim zweiten Aufruf von GetFileSecurity() zur Erstellung der Kopie des Security Descriptor wird in SecurityDescriptorBufferSize der Wert 20 zurückgegeben...
Die Analyse des DrWatson-Dumps zeigt, daß der Fehler bei der Heap-Auflösung auftritt. Zuerst habe ich gemerkt, daß ich den SecurityDescriptorBuffer nicht mit FreeMemory() wieder freigegeben habe. Aber auch das Hinzufügen von FreeMemory() behebt den Fehler nicht.
Ich habe das Problem umgangen, indem ich den Speicher für den Security Descriptor nicht mehr mit dem anscheinend problematischen AllocateMemory() anfordere, sondern für den Puffer eine mit Leerzeichen vorbelegte Zeichenkette in der richtigen Länge anlege...
Code: Alles auswählen
Procedure.S GetLastError()
ErrorBufferPointer.L
ErrorCode.L
ErrorText.S
ErrorCode = GetLastError_()
ferr = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER | #FORMAT_MESSAGE_FROM_SYSTEM, 0 , ErrorCode, GetUserDefaultLangID_(), @ErrorBufferPointer, 0, 0)
If ErrorBufferPointer <> 0
ErrorText = PeekS(ErrorBufferPointer)
LocalFree_(ErrorBufferPointer)
ProcedureReturn RemoveString(ErrorText, #CRLF$)
EndIf
EndProcedure
#OWNER_SECURITY_INFORMATION = 1
AccountName.S
AccountNameSize.L
BufferSize.L
DomainName.S
DomainNameSize.L
Path.S
SIDPointer.L
SIDDefaultedPointer.L
SIDType.L
SecurityDescriptorBuffer.S
SecurityDescriptorBufferSize.L
; ----- Verzeichnispfad oder Verzeichnispfad mit Dateiname
Path = "C:\"
; ----- Puffergröße für Security Descriptor ermitteln
GetFileSecurity_(@Path, #OWNER_SECURITY_INFORMATION, 0, 0, @SecurityDescriptorBufferSize)
If SecurityDescriptorBufferSize = 0
MessageRequester("Fehler", "1.GetFileSecurity()-Aufruf: " + GetLastError())
End
EndIf
SecurityDescriptorBuffer = Space(SecurityDescriptorBufferSize)
; ----- Security Descriptor für Ordner oder Datei erstellen lassen
If GetFileSecurity_(@Path, #OWNER_SECURITY_INFORMATION, @SecurityDescriptorBuffer, SecurityDescriptorBufferSize, @BufferSize) = #False
MessageRequester("Fehler", "2.GetFileSecurity()-Aufruf: " + GetLastError())
End
EndIf
; ----- Security ID (SID) des Besitzers ermitteln
If GetSecurityDescriptorOwner_(@SecurityDescriptorBuffer, @SIDPointer, @SIDDefaultedPointer) = #False
MessageRequester("Fehler", "GetSecurityDescriptorOwner()-Aufruf: " + GetLastError())
End
EndIf
If IsValidSid_(SIDPointer) = #False
MessageRequester("Fehler", "IsValidSid()-Aufruf: Die vom GetSecurityDescriptorOwner()-Aufruf erhaltene Security ID ist ungültig!")
End
EndIf
; ----- Länge von Benutzerkennung und Domänenname ermitteln
LookupAccountSid_(#NULL$, SIDPointer, 0, @AccountNameSize, 0, @DomainNameSize, SIDType)
If AccountNameSize = 0
MessageRequester("Fehler", "Fehler beim 1.LookupAccountSid()-Aufruf: Die Länge der Benutzerkennung ist ungültig!")
End
EndIf
AccountName = Space(AccountNameSize + 1)
DomainName = Space(DomainNameSize + 1)
; ----- Benutzername und Domänenname ermitteln
If LookupAccountSid_(#Null, SIDPointer, @AccountName, @AccountNameSize, @DomainName, @DomainNameSize, @SIDType) = #False
MessageRequester("Fehler", "2.LookupAccountSid()-Aufruf: " + GetLastError())
End
EndIf
MessageRequester("Info", "Verzeichnis/Dateiname: " + Path + #CR$ + "Benutzerkennung: " + AccountName + #CR$ + "Domäne/Arbeitsgruppe: " + DomainName, #MB_ICONINFORMATION)
End
Diese Version läuft in PB 3.94 und in PB 4 korrekt, sowohl mit als auch ohne Debugger.