External resource files format? Anyone?

Hi everyone,

I've been programming using FASM for a few years now, without too many headaches (quite powerful programming environment, in fact), and until now I've always compiled resources using internal macroinstructions. Recently I started a more "serious" project which needs a lot of fiddling with GDI and the user interface; since using an IDE to design dialog boxes and stuff is way faster and less cumbersome, I tried including an external resource file using:

Code:

section'.rsrc'datareadableresourcefrom'resource.res'

but it gave me an "Error: invalid file format" message. I also tried including a .rc file, with the same result.

Peeking inside the source code, I found out that the file must start with:

Because it might be desirable for an ISV's tool that reads and writes
resource files to be able to read either the older Windows 16 format
files and the new Windows 32 format, Microsoft has devised a method
to do this using illegal type and name ordinal numbers.

The method involved is to place an illegal resource in the resource
file. The following eight bytes were chosen:

0x00 0x00 0x00 0x00 0x20 0x00 0x00 0x00

Assume that it is a 16-bit file. In that case, the Type is illegal
since the first 0x00 says string, but a zero-length string is an
illegal string. This, then is an illegal 16-bit resource header,
indicating that the file is a 32-bit file.

Assume that it is a 32-bit file. Given that, the size of the data is
zero, which surely will never be the case.

The Windows 32 resource compiler prefaces each 32-bit resource file
with this string of data (followed by an additional data structure
describing a zero-length resource with 0 ordinal type and 0 ordinal
name), allowing differentiation of 16 and 32-bit resource files. Any
tools reading resource files should ignore this resource.

It looks like Privalov is right: my .res file was 16-bit (probably), so that's one mistery solved. I managed to make it work by using the resource compiler in VS 2017 Community, since I already had it lying around for other reasons; it's a bit bulky, but it works well for the moment.
Let me insist though, it would be wise in my opinion to add a line to the documentation pointing out what type of resource file FASM is exactly expecting to read.

Note for Privalov: while tinkering with Visual Studio at some point it spit out an empty/corrupted .res file, which is basically just the first 0x20 bytes stub header. I'm not sure if the part of code in FASM dedicated to resource importing is supposed to be fail-proof or not, but anyway merely importing that file makes both FASMW and FASM crash during compilation. Just in case you wanted to investigate the problem.

The following is for the posterity, in case someone in need chances upon this thread.

Info for anyone having problems importing/designing resources for FASM:

THE KEY ISSUE: if using internal macros to build resources is not for you, your only other option is to include an external 32-bit compiled resource file (.res) created via an external program. That means that resource script files (.rc) are a no-go (get yourself a resource compiler, also see below) and most importantly 16-bit .res files are not good either (legitimate, it's been what, 20 years since Windows 95?)
Now, unfortunately very often resource editors/compilers don't tell explicitly if they output 16-bit or 32-bit .res files, but you can find out for yourself: create and compile a test resource file and open it in a hex editor (don't have one? Go get XVI32) and check its first 16 bytes; if they are

Quote:

00 00 00 00 - 20 00 00 00 - FF FF 00 00 - FF FF 00 00

then it's probably a 32-bit .res file.

WHAT DIDN'T WORK: ResEdit produces 16-bit .res files, don't be fooled by the fact that it's available as a 64-bit executable; I found no option to change the output format.
I also tried XNResourceEditor (in portable version) but it crashed on me twice before I could do anything concrete, so I gave up. Some say that it works just fine for them, though.

WHAT KINDA WORKED: ResourceHacker, the latest version; the output format is correct, but I find the interface a bit slow and counterintuitive, plus I had some strange phenomena happening on me (had a dialog with 2 buttons, setting the VS_VISIBLE flag in both made them disappear, setting it only in one made them both visible, weird). It works natively in .rc format, and supports importing from/exporting to .res (32-bit) and even editing resources directly inside of PE .exe/.dll files. I guess it could be useful for some quick adjusting, once you get used with how the interface works, but always with a grain of salt.

WHAT WORKED FOR ME IN THE END: having Visual Studio 2017 Community already installed in my system, I opted to give it a try, and so far it worked rather well. I would discourage installing VS 2017 for this sole purpose, it's rather bulky; you might want to consider the alternatives further below. On the contrary, if you have it installed already, I'll explain below how to get it to compile resources for you. You need the code editor, some version of the Windows SDK (I have Win 10) and most likely even the C/C++ compiler (try without it, just in case) to be installed on your system for the following to work. Keep in mind that the paths below are relative to my version of the Windows 10 SDK, if you have another version just change the paths accordingly.

Currently in VS 2017 there's an annoying bug that prevents the resource editor from working; hopefully it will be fixed soon. As a temporary workaround it should be enough to copy "C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x86\rcdll.dll" to "c:\Program Files (x86)\Windows Kits\10\bin\x86". You will also need to restart Visual Studio, maybe even reboot.

Open the VS editor

Select File > New > Project

On the left pane of the New project window, select Templates > Visual C++ > General, and then pick Empty Project; give it a name and a destination folder and click OK

Select View > Resource View

Select Project > Add new element...

On the left pane of the New element window, select Visual C++ > Resource, then pick Resource file (.rc); give it a name and click OK. Now you should see it appear in the Resource view tab.
From now on, if any error message boxes appear it probably means that either the resource editor or VS itself aren't configured correctly; in that case I'm afraid I can't help you

Now it's time to edit the resource file. On the Resource view tab, right-click on the newly created file, and select Add resource...; pick the resource you want to add and click New. It should open automatically. Now just follow the VS guides for resource editing, Google is your friend. When editing dialogs, right-click on the dialog and select Properties to bring up the Properties tab. Use the buttons on the right to bring up the toolbox.

When you're ready to compile, select Build > Build solution. Building will fail because there is no source file associated with the project, but the resources are recompiled regardless

Bring up the Explore solution tab (bottom-left), right-click on the name of the project and select Open folder in File Explorer; or, just navigate to the project folder, inside the omonymous folder. You should see among other files your .rc file. Now open the Debug folder: the .res file should be there.

You can re-use the project afterwards to create and compile as many resource files as you want, you just need to add more .rc files to the project and they'll get compiled as well.
It's a bit of an unorthodox method, bit it does the job rather well. There's supposed to be an option to export a resource file directly instead of doing all this, but for some reason for me it's always greyed out.

In case you need it for some reason, the command line to compile the resource file from outside the VS environment is

or something similar according to the SDK version you have. The hex value after the /l option is the language code for en-US.
Just one thing I'm not entirely happy about: you don't have complete control over what appears in the final .res file, some additional resources might be created. I guess it's fine during the developing process, and at the pre-release stage the additional resources can be deleted manually in the resource script or with ResourceHacker.

WHAT PROBABLY WORKS: Pelles C, a freeware C development kit, has a fully-featured resource editor included, and from the looks of it it's relatively lightweight. It can't hurt to have a C compiler installed anyway. I would dare say this is your best bet if you want a quick and easy solution, although keep in mind I haven't tested it personally, I'm taking dancho's word for it.
There are other C suites that similarly provide tools for resource editing/compiling, such as OpenWatcom and LCC-Win32. Again, not tested by me.
Another theoretical solution could be to use a resource editor to prepare a .rc file, and a separate resource compiler such as GoRC to produce the .res file, although most resource editors also include compiling functionality. I tried doing that with ResEdit and ResourceHacker, but first ResEdit complained about missing header files (it's notorius for doing that on newer versions of Windows) and then didn't accept Windows 10 SDK header files (adding that to the fact that its current official download has been repeatedly reported to contain malware, i guess we can safely tick off ResEdit)

BTW off topic but, since you mentioned a Hex Editor, I'd recommend instead HxD, it can also deal with larger files than 2GB (doesn't memory map it, and only writes the part of the file actually modified when saving).

Note for Privalov: while tinkering with Visual Studio at some point it spit out an empty/corrupted .res file, which is basically just the first 0x20 bytes stub header. I'm not sure if the part of code in FASM dedicated to resource importing is supposed to be fail-proof or not, but anyway merely importing that file makes both FASMW and FASM crash during compilation. Just in case you wanted to investigate the problem.

BTW off topic but, since you mentioned a Hex Editor, I'd recommend instead HxD, it can also deal with larger files than 2GB (doesn't memory map it, and only writes the part of the file actually modified when saving).

Agreed. DMA -RAM -etc. --HxD is quite powerful.

_________________Nothing is so sought after and often avoided as the truth.

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum