# File lib/win32/file.rb, line 247
      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

         # No DACL exists
         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 # byte, byte, word, word, word (struct ACL)
         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 # ACE_HEADER, dword, dword (ACCESS_ALLOWED_ACE)
            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, # address of ace_ptr->SidStart
                  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