J
John Regan
Hello All
I am trying to find the owner of a file or folder on our network (Windows
2000 Server) using VB.Net and/or API. so I can search for Folders that don't
follow our company's specified folder structure and naming conventions and
then send a Net send message to those users telling them to rectify.
The information I want to get is when you select the file/folder and then:
Properties -> Security Tab -> Advanced Button -> Owner Tab -> Current Owner
of this Item.
I found the following code (see VBA CODE below) which works a treat in VBA
but would like to convert in into VB.Net.
I attempted to change for VB.Net (see VB.Net CODE below) but the first call
to GetFileSecurity() fails to assign the buffer size to sizeSD so it fails
later on
when calling GetSecurityDescriptorOwner() with NullReferenceException error.
Hope someone rises to the challenge.
Thanks in advance
John
'=========================== VBA CODE====================================
Option Compare Database
Option Explicit
Private Declare 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 Function GetSecurityDescriptorOwner Lib "advapi32.dll" _
(pSecurityDescriptor As Any, pOwner As Long, lpbOwnerDefaulted As Long)
As _
Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias _
"LookupAccountSidA" (ByVal lpSystemName As String, ByVal Sid As Long, _
ByVal name As String, cbName As Long, ByVal ReferencedDomainName As
String, _
cbReferencedDomainName As Long, peUse As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias _
"GetWindowsDirectoryA" (ByVal lpBuffer As String, _
ByVal nSize As Long) As Long
Const OWNER_SECURITY_INFORMATION = &H1
Const ERROR_INSUFFICIENT_BUFFER = 122&
Const MAX_PATH = 255
' return the name of the file owner
'
' runs over Windows NT or 2000, and works only with files in NTFS partitions
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 Long ' Pointer to the Owner's SID
Dim ownerName 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 type
' indicating the type of the account
' Call GetFileSecurity the first time to obtain the size of the buffer
' required for the Security Descriptor.
bSuccess = GetFileSecurity(szfilename, OWNER_SECURITY_INFORMATION, 0,
0&, _
sizeSD)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER)
Then _
Exit Function
' 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
' filename 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)
' exit if error
If bSuccess = 0 Then Exit Function
' Obtain the owner's SID from the Security Descriptor, exit if error
bSuccess = GetSecurityDescriptorOwner(sdBuf(0), pOwner, 0&)
If bSuccess = 0 Then Exit Function
' 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, ownerName, name_len, _
domain_name, domain_len, deUse)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER)
Then _
Exit Function
' Allocate the required space in the name and domain_name string
variables.
' Allocate 1 byte less to avoid the appended NULL character.
ownerName = 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, ownerName, name_len, _
domain_name, domain_len, deUse)
If bSuccess = 0 Then Exit Function
' we've found a result
GetFileOwner = ownerName
End Function
'=========================== VB.Net
CODE====================================
Option Explicit On
Imports System.Runtime.InteropServices
Module Module2
Private Declare Function GetFileSecurity Lib "advapi32.dll" Alias _
"GetFileSecurityA" (ByVal lpFileName As String, ByVal
RequestedInformation _
As Long, ByVal pSecurityDescriptor As Byte, ByVal nLength As Long, _
ByVal lpnLengthNeeded As Long) As Long
Private Declare Function GetSecurityDescriptorOwner Lib "advapi32.dll" _
(<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal pSecurityDescriptor
As Object, ByVal pOwner As Long, ByVal lpbOwnerDefaulted As Long) As _
Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias _
"LookupAccountSidA" (ByVal lpSystemName As String, ByVal Sid As
Long, _
ByVal name As String, ByVal cbName As Long, ByVal
ReferencedDomainName As String, _
ByVal cbReferencedDomainName As Long, ByVal peUse As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias _
"GetWindowsDirectoryA" (ByVal lpBuffer As String, _
ByVal nSize As Long) As Long
Const OWNER_SECURITY_INFORMATION As Long = &H1
Const ERROR_INSUFFICIENT_BUFFER As Long = 122&
Const MAX_PATH = 255
' return the name of the file owner
'
' runs over Windows NT or 2000, and works only with files in NTFS
partitions
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 Long ' Pointer to the Owner's SID
Dim ownerName 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
type
' indicating the type of the account
' Call GetFileSecurity the first time to obtain the size of the
buffer
' required for the Security Descriptor.
bSuccess = GetFileSecurity(szfilename, OWNER_SECURITY_INFORMATION,
0, 0&, _
sizeSD)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <>
ERROR_INSUFFICIENT_BUFFER) Then _
Exit Function
' Create a buffer of the required size and call GetFileSecurity
again
ReDim sdBuf(sizeSD)
' Fill the buffer with the security descriptor of the object
specified by
' the
' filename 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)
' exit if error
If bSuccess = 0 Then Exit Function
' Obtain the owner's SID from the Security Descriptor, exit if error
bSuccess = GetSecurityDescriptorOwner(sdBuf(0), pOwner, 0&)
If bSuccess = 0 Then Exit Function
' 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, ownerName,
name_len, _
domain_name, domain_len, deUse)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <>
ERROR_INSUFFICIENT_BUFFER) Then _
Exit Function
' Allocate the required space in the name and domain_name string
variables.
' Allocate 1 byte less to avoid the appended NULL character.
ownerName = 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, ownerName,
name_len, _
domain_name, domain_len, deUse)
If bSuccess = 0 Then Exit Function
' we've found a result
GetFileOwner = ownerName
End Function
End Module
I am trying to find the owner of a file or folder on our network (Windows
2000 Server) using VB.Net and/or API. so I can search for Folders that don't
follow our company's specified folder structure and naming conventions and
then send a Net send message to those users telling them to rectify.
The information I want to get is when you select the file/folder and then:
Properties -> Security Tab -> Advanced Button -> Owner Tab -> Current Owner
of this Item.
I found the following code (see VBA CODE below) which works a treat in VBA
but would like to convert in into VB.Net.
I attempted to change for VB.Net (see VB.Net CODE below) but the first call
to GetFileSecurity() fails to assign the buffer size to sizeSD so it fails
later on
when calling GetSecurityDescriptorOwner() with NullReferenceException error.
Hope someone rises to the challenge.
Thanks in advance
John
'=========================== VBA CODE====================================
Option Compare Database
Option Explicit
Private Declare 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 Function GetSecurityDescriptorOwner Lib "advapi32.dll" _
(pSecurityDescriptor As Any, pOwner As Long, lpbOwnerDefaulted As Long)
As _
Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias _
"LookupAccountSidA" (ByVal lpSystemName As String, ByVal Sid As Long, _
ByVal name As String, cbName As Long, ByVal ReferencedDomainName As
String, _
cbReferencedDomainName As Long, peUse As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias _
"GetWindowsDirectoryA" (ByVal lpBuffer As String, _
ByVal nSize As Long) As Long
Const OWNER_SECURITY_INFORMATION = &H1
Const ERROR_INSUFFICIENT_BUFFER = 122&
Const MAX_PATH = 255
' return the name of the file owner
'
' runs over Windows NT or 2000, and works only with files in NTFS partitions
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 Long ' Pointer to the Owner's SID
Dim ownerName 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 type
' indicating the type of the account
' Call GetFileSecurity the first time to obtain the size of the buffer
' required for the Security Descriptor.
bSuccess = GetFileSecurity(szfilename, OWNER_SECURITY_INFORMATION, 0,
0&, _
sizeSD)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER)
Then _
Exit Function
' 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
' filename 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)
' exit if error
If bSuccess = 0 Then Exit Function
' Obtain the owner's SID from the Security Descriptor, exit if error
bSuccess = GetSecurityDescriptorOwner(sdBuf(0), pOwner, 0&)
If bSuccess = 0 Then Exit Function
' 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, ownerName, name_len, _
domain_name, domain_len, deUse)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER)
Then _
Exit Function
' Allocate the required space in the name and domain_name string
variables.
' Allocate 1 byte less to avoid the appended NULL character.
ownerName = 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, ownerName, name_len, _
domain_name, domain_len, deUse)
If bSuccess = 0 Then Exit Function
' we've found a result
GetFileOwner = ownerName
End Function
'=========================== VB.Net
CODE====================================
Option Explicit On
Imports System.Runtime.InteropServices
Module Module2
Private Declare Function GetFileSecurity Lib "advapi32.dll" Alias _
"GetFileSecurityA" (ByVal lpFileName As String, ByVal
RequestedInformation _
As Long, ByVal pSecurityDescriptor As Byte, ByVal nLength As Long, _
ByVal lpnLengthNeeded As Long) As Long
Private Declare Function GetSecurityDescriptorOwner Lib "advapi32.dll" _
(<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal pSecurityDescriptor
As Object, ByVal pOwner As Long, ByVal lpbOwnerDefaulted As Long) As _
Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias _
"LookupAccountSidA" (ByVal lpSystemName As String, ByVal Sid As
Long, _
ByVal name As String, ByVal cbName As Long, ByVal
ReferencedDomainName As String, _
ByVal cbReferencedDomainName As Long, ByVal peUse As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias _
"GetWindowsDirectoryA" (ByVal lpBuffer As String, _
ByVal nSize As Long) As Long
Const OWNER_SECURITY_INFORMATION As Long = &H1
Const ERROR_INSUFFICIENT_BUFFER As Long = 122&
Const MAX_PATH = 255
' return the name of the file owner
'
' runs over Windows NT or 2000, and works only with files in NTFS
partitions
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 Long ' Pointer to the Owner's SID
Dim ownerName 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
type
' indicating the type of the account
' Call GetFileSecurity the first time to obtain the size of the
buffer
' required for the Security Descriptor.
bSuccess = GetFileSecurity(szfilename, OWNER_SECURITY_INFORMATION,
0, 0&, _
sizeSD)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <>
ERROR_INSUFFICIENT_BUFFER) Then _
Exit Function
' Create a buffer of the required size and call GetFileSecurity
again
ReDim sdBuf(sizeSD)
' Fill the buffer with the security descriptor of the object
specified by
' the
' filename 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)
' exit if error
If bSuccess = 0 Then Exit Function
' Obtain the owner's SID from the Security Descriptor, exit if error
bSuccess = GetSecurityDescriptorOwner(sdBuf(0), pOwner, 0&)
If bSuccess = 0 Then Exit Function
' 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, ownerName,
name_len, _
domain_name, domain_len, deUse)
' exit if any error
If (bSuccess = 0) And (Err.LastDllError <>
ERROR_INSUFFICIENT_BUFFER) Then _
Exit Function
' Allocate the required space in the name and domain_name string
variables.
' Allocate 1 byte less to avoid the appended NULL character.
ownerName = 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, ownerName,
name_len, _
domain_name, domain_len, deUse)
If bSuccess = 0 Then Exit Function
' we've found a result
GetFileOwner = ownerName
End Function
End Module