def set_permissions(file, perms)
raise TypeError unless perms.kind_of?(Hash)
account_rights = 0
sec_desc = 0.chr * SECURITY_DESCRIPTOR_MIN_LENGTH
unless InitializeSecurityDescriptor(sec_desc, 1)
raise ArgumentError, get_last_error
end
cb_acl = 1024
cb_sid = 1024
acl_new = 0.chr * cb_acl
unless InitializeAcl(acl_new, cb_acl, ACL_REVISION2)
raise ArgumentError, get_last_error
end
sid = 0.chr * cb_sid
snu_type = 0.chr * cb_sid
all_ace = 0.chr * ALLOW_ACE_LENGTH
all_ace_ptr = memset(all_ace, 0, 0)
all_ace[0] = 0
perms.each{ |account, mask|
next if mask.nil?
cch_domain = [80].pack('L')
cb_sid = [1024].pack('L')
domain_buf = 0.chr * 80
server, account = account.split("\\")
if ['BUILTIN', 'NT AUTHORITY'].include?(server.upcase)
server = nil
end
val = LookupAccountName(
server,
account,
sid,
cb_sid,
domain_buf,
cch_domain,
snu_type
)
if val == 0
raise ArgumentError, get_last_error
end
size = [0,0,0,0,0].pack('CCSLL').length
val = CopySid(
ALLOW_ACE_LENGTH - size,
all_ace_ptr + 8,
sid
)
if val == 0
raise ArgumentError, get_last_error
end
if (GENERIC_ALL & mask).nonzero?
account_rights = GENERIC_ALL & mask
elsif (GENERIC_RIGHTS_CHK & mask).nonzero?
account_rights = GENERIC_RIGHTS_MASK & mask
end
all_ace[1] = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE
2.times{
if account_rights != 0
all_ace[2,2] = [12 - 4 + GetLengthSid(sid)].pack('S')
all_ace[4,4] = [account_rights].pack('L')
val = AddAce(
acl_new,
ACL_REVISION2,
MAXDWORD,
all_ace_ptr,
all_ace[2,2].unpack('S').first
)
if val == 0
raise ArgumentError, get_last_error
end
all_ace[1] = CONTAINER_INHERIT_ACE
else
all_ace[1] = 0
end
account_rights = REST_RIGHTS_MASK & mask
}
}
unless SetSecurityDescriptorDacl(sec_desc, 1, acl_new, 0)
raise ArgumentError, get_last_error
end
unless SetFileSecurity(file, DACL_SECURITY_INFORMATION, sec_desc)
raise ArgumentError, get_last_error
end
self
end