Exemplo n.º 1
0
/* Write resource file */
void
write_res_file (const char *fn,const rc_res_directory *resdir)
{
  asection *sec;
  rc_uint_type language;
  bfd *abfd;
  windres_bfd wrbfd;
  unsigned long sec_length = 0,sec_length_wrote;
  static const bfd_byte sign[] =
  {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  filename = fn;

  abfd = windres_open_as_binary (filename, 0);
  sec = bfd_make_section (abfd, ".data");
  if (sec == NULL)
    bfd_fatal ("bfd_make_section");
  if (! bfd_set_section_flags (abfd, sec,
			       (SEC_HAS_CONTENTS | SEC_ALLOC
			        | SEC_LOAD | SEC_DATA)))
    bfd_fatal ("bfd_set_section_flags");
  /* Requiring this is probably a bug in BFD.  */
  sec->output_section = sec;

  set_windres_bfd (&wrbfd, abfd, sec,
		   (target_is_bigendian ? WR_KIND_BFD_BIN_B
					: WR_KIND_BFD_BIN_L));

  language = -1;
  sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
				    (const rc_res_id *) NULL,
				    (const rc_res_id *) NULL, &language, 1);
  if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3))
    bfd_fatal ("bfd_set_section_size");
  if ((sec_length & 3) != 0)
    set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
  set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
  language = -1;
  sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir,
					  (const rc_res_id *) NULL,
					  (const rc_res_id *) NULL,
					  &language, 1);
  if (sec_length != sec_length_wrote)
    fatal ("res write failed with different sizes (%lu/%lu).", (long) sec_length,
    	   (long) sec_length_wrote);

  bfd_close (abfd);
  return;
}
Exemplo n.º 2
0
/* write resource directory to binary resource file */
static rc_uint_type
write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_directory *rd,
                     const rc_res_id *type, const rc_res_id *name, rc_uint_type *language,
                     int level)
{
    const rc_res_entry *re;

    for (re = rd->entries; re != NULL; re = re->next)
    {
        switch (level)
        {
        case 1:
            /* If we're at level 1, the key of this resource is the
               type.  This normally duplicates the information we have
               stored with the resource itself, but we need to remember
               the type if this is a user define resource type.  */
            type = &re->id;
            break;

        case 2:
            /* If we're at level 2, the key of this resource is the name
               we are going to use in the rc printout.  */
            name = &re->id;
            break;

        case 3:
            /* If we're at level 3, then this key represents a language.
               Use it to update the current language.  */
            if (! re->id.named
                    && re->id.u.id != (unsigned long) *language
                    && (re->id.u.id & 0xffff) == re->id.u.id)
            {
                *language = re->id.u.id;
            }
            break;

        default:
            break;
        }

        if (re->subdir)
            off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
                                       level + 1);
        else
        {
            if (level == 3)
            {
                /* This is the normal case: the three levels are
                   TYPE/NAME/LANGUAGE.  NAME will have been set at level
                   2, and represents the name to use.  We probably just
                   set LANGUAGE, and it will probably match what the
                   resource itself records if anything.  */
                off = write_res_resource (wrbfd, off, type, name, re->u.res,
                                          language);
            }
            else
            {
                fprintf (stderr, "// Resource at unexpected level %d\n", level);
                off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
                                          re->u.res, language);
            }
        }
    }

    return off;
}