def get_permissions(file, host=nil)
current_length = 0
length_needed = [0].pack('L')
sec_buf = ''
loop do
bool = GetFileSecurity(
file,
DACL_SECURITY_INFORMATION,
sec_buf,
sec_buf.length,
length_needed
)
if bool == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER
raise ArgumentError, get_last_error
end
break if sec_buf.length >= length_needed.unpack('L').first
sec_buf += ' ' * length_needed.unpack('L').first
end
control = [0].pack('L')
revision = [0].pack('L')
unless GetSecurityDescriptorControl(sec_buf, control, revision)
raise ArgumentError, get_last_error
end
if (control.unpack('L').first & SE_DACL_PRESENT) == 0
raise ArgumentError, 'No DACL present: explicit deny all'
end
dacl_present = [0].pack('L')
dacl_defaulted = [0].pack('L')
dacl_ptr = [0].pack('L')
val = GetSecurityDescriptorDacl(
sec_buf,
dacl_present,
dacl_ptr,
dacl_defaulted
)
if val == 0
raise ArgumentError, get_last_error
end
acl_buf = 0.chr * 8
memcpy(acl_buf, dacl_ptr.unpack('L').first, acl_buf.size)
if acl_buf.unpack('CCSSS').first == 0
raise ArgumentError, 'DACL is NULL: implicit access grant'
end
ace_ptr = [0].pack('L')
ace_count = acl_buf.unpack('CCSSS')[3]
perms_hash = {}
0.upto(ace_count - 1){ |i|
unless GetAce(dacl_ptr.unpack('L').first, i, ace_ptr)
next
end
ace_buf = 0.chr * 12
memcpy(ace_buf, ace_ptr.unpack('L').first, ace_buf.size)
if ace_buf.unpack('CCS').first == ACCESS_ALLOWED_ACE_TYPE
name = 0.chr * MAX_PATH
name_size = [name.size].pack('L')
domain = 0.chr * MAX_PATH
domain_size = [domain.size].pack('L')
snu_ptr = 0.chr * 4
val = LookupAccountSid(
host,
ace_ptr.unpack('L').first + 8,
name,
name_size,
domain,
domain_size,
snu_ptr
)
if val == 0
raise ArgumentError, get_last_error
end
name = name[0..name_size.unpack('L').first].split(0.chr)[0]
domain = domain[0..domain_size.unpack('L').first].split(0.chr)[0]
mask = ace_buf.unpack('LLL')[1]
unless domain.nil? || domain.empty?
name = domain + '\\' + name
end
perms_hash[name] = mask
end
}
perms_hash
end