Option Explicit
Private Declare PtrSafe Function GetFileSecurity Lib "advapi32.dll" _
Alias "GetFileSecurityA" ( _
ByVal lpFileName As String, _
ByVal RequestedInformation As Long, _
pSecurityDescriptor As Byte, _
ByVal nLength As Long, _
lpnLengthNeeded As Long _
) As Long
Private Declare PtrSafe Function GetSecurityDescriptorOwner Lib "advapi32.dll" _
(pSecurityDescriptor As Any, _
pOwner As LongLong, _
lpbOwnerDefaulted As Long) As Long
Private Declare PtrSafe Function LookupAccountSid Lib "advapi32.dll" _
Alias "LookupAccountSidA" ( _
ByVal lpSystemName As String, _
ByVal Sid As LongLong, _
ByVal name As String, _
cbName As Long, _
ByVal ReferencedDomainName As String, _
cbReferencedDomainName As Long, _
peUse As Long) As Long
Private Const OWNER_SECURITY_INFORMATION = &H1
Private Const ERROR_INSUFFICIENT_BUFFER = 122&
Function GetFileOwner(ByVal szfilename As String) As String
Dim bSuccess As Long ' Status variable
Dim sizeSD As Long ' Buffer size to store Owner's SID
Dim pOwner As LongLong ' Pointer to the Owner's SID
Dim name As String ' Name of the file owner
Dim domain_name As String ' Name of the first domain for the owner
Dim name_len As Long ' Required length for the owner name
Dim domain_len As Long ' Required length for the domain name
Dim sdBuf() As Byte ' Buffer for Security Descriptor
Dim nLength As Long ' Length of the Windows Directory
Dim deUse As Long ' Pointer to a SID_NAME_USE enumerated
bSuccess = GetFileSecurity( _
szfilename, _
OWNER_SECURITY_INFORMATION, _
0, _
0&, _
sizeSD)
If (bSuccess = 0) And _
(Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER) Then
MsgBox "GetLastError returned : " & Err.LastDllError
Exit Function
End If
' Create a buffer of the required size and call GetFileSecurity again.
ReDim sdBuf(0 To sizeSD - 1) As Byte
' Fill the buffer with the security descriptor of the object specified
' by the szfilename parameter. The calling process must have the right
' to view the specified aspects of the object's security status.
bSuccess = GetFileSecurity( _
szfilename, _
OWNER_SECURITY_INFORMATION, _
sdBuf(0), _
sizeSD, _
sizeSD)
If (bSuccess <> 0) Then
' Obtain the owner's SID from the Security Descriptor.
'
bSuccess = GetSecurityDescriptorOwner(sdBuf(0), pOwner, 0&)
If (bSuccess = 0) Then
MsgBox "GetLastError returned : " & Err.LastDllError
Exit Function
End If
' Retrieve the name of the account and the name of the first
' domain on which this SID is found. Passes in the Owner's SID
' obtained previously. Call LookupAccountSid twice, the first time
' to obtain the required size of the owner and domain names.
bSuccess = LookupAccountSid(vbNullString, pOwner, name, name_len, _
domain_name, domain_len, deUse)
If (bSuccess = 0) And _
(Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER) Then
MsgBox "GetLastError returned : " & Err.LastDllError
Exit Function
End If
' Allocate the required space in the name and domain_name string
' variables. Allocate 1 byte less to avoid the appended NULL character.
'
name = Space(name_len - 1)
domain_name = Space(domain_len - 1)
' Call LookupAccountSid again to actually fill in the name of the owner
' and the first domain.
'
bSuccess = LookupAccountSid(vbNullString, pOwner, name, name_len, _
domain_name, domain_len, deUse)
If bSuccess = 0 Then
MsgBox "GetLastError returned : " & Err.LastDllError
Exit Function
End If
GetFileOwner = name
End If
End Function