flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Windows > External resource files format? Anyone?

Author
Thread Post new topic Reply to topic
Marut



Joined: 18 Jun 2017
Posts: 7
Location: Veneto, Italy
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' data readable resource from '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:

Quote:
00 00 00 00 - 20 00 00 00 - FF FF 00 00 - ? ? ? ? - ? ? FF FF - 00 00 ? ? --- (SOURCE\FORMATS.INC lines 1688-1698)


in order not to be immediately discarded, so it must be a binary file (certainly not .rc); but the MS format specifications for resource files indicate that, in short, the first DWORD in a .res file is the size (in bytes) of the first resource included, which shouldn't be 0, so it's not that format, either.
(See https://msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx and https://msdn.microsoft.com/en-us/library/windows/desktop/ms648027(v=vs.85).aspx)


So, it would really help me if someone could kindly point me to the format accepted by FASM.



P.S.: IMHO this should be included in FASM.PDF too; given how powerful the macro system is, even the fact that .rc files are not supported is not all that obvious to me...
Post 18 Jun 2017, 16:23
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6585
Location: Kraków, Poland
Is your resource file a 16-bit one? This special header that fasm is checking for is there to distinguish 32-bit resources from 16-bit ones.
You can read about it in these old specs: http://www.csn.ul.ie/~caolan/pub/winresdump/winresdump/doc/resfmt.txt

Quote:
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.

Post 18 Jun 2017, 20:31
View user's profile Send private message Visit poster's website Reply with quote
dancho



Joined: 06 Mar 2011
Posts: 74
@Marut
try to use PellesC Ide as resource editor to create res file,
in my experience fasm have no problem with it...

http://smorgasbordet.com/pellesc/
Post 19 Jun 2017, 09:28
View user's profile Send private message Reply with quote
Mikl___



Joined: 30 Dec 2014
Posts: 55
Hi, Marut!
ftut-08-01.asm

Code:
format PE GUI
include 'win32ax.inc'
; import data in the same section
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3

          xor ebx,ebx
          mov edi,wTitle
          mov esi,400000h
          ; +------------------------------+
          ; | registering the window class |
          ; +------------------------------+
          invoke RegisterClass,esp,ebx,WndProc,ebx,\
          ebx,esi,ebx,10011h,COLOR_WINDOW+1,menu_name,edi
          ; +--------------------------+
          ; | creating the main window |
          ; +--------------------------+
          push ebx esi ebx ebx
          shl esi,9
          invoke CreateWindowEx,ebx,edi,edi,WS_OVERLAPPEDWINDOW+\
          WS_VISIBLE,esi,esi,esi,esi
          mov ebp,esp
          ; +---------------------------+
          ; | entering the message loop |
          ; +---------------------------+
message_loopinvoke GetMessage,ebp,ebx,ebx,ebx
          invoke DispatchMessage,ebp
          jmp message_loop
          ; +----------------------+
          ; | the window procedure |
          ; +----------------------+
proc WndProc,hWnd,uMsg,wParam,lParam
         mov eax,[uMsg]
         dec eax; cmp uMsg,WM_DESTROY
         dec eax
         je wmDESTROY
         sub eax,WM_COMMAND-WM_DESTROY; cmp uMsg,WM_PAINT
         je wmCOMMAND
         leave
         jmp dword [DefWindowProc]

wmCOMMANDmov ebx,[wParam]
         cmp ebx,ZZZ_EXIT
         je wmDESTROY;menu_exit
show_msg:    
         invoke MessageBox,[hWnd],[menu_handlers+ebx*4],menu_name,eax
         ret
wmDESTROY:  invoke ExitProcess,ebx
endp
;--------------------------------------------------------------------
     ;exp = experiment
wTitle    db   'Iczelion Tutorial #8-1:Creating a menu through a resource file in FASM',0 ;name of our window
menu_name       db      'ZZZ_Menu',0
test_msg        db      'You select menu item TEST',0
open_msg        db      'You select menu item OPEN',0
save_msg        db      'You select menu item SAVE',0
menu_handlers dd test_msgopen_msgsave_msg
;---------------------------------------------------------------------
data import

 library KERNEL32'KERNEL32.DLL',\
         user32,   'USER32.DLL'
 import KERNEL32,\
               ExitProcess,        'ExitProcess'
 import user32,\
                RegisterClass,      'RegisterClassA',\
                CreateWindowEx,     'CreateWindowExA',\
                DefWindowProc,      'DefWindowProcA',\
                GetMessage,         'GetMessageA',\
                DispatchMessage,    'DispatchMessageA',\
                DestroyWindow,      'DestroyWindow',\
                MessageBox,         'MessageBoxA'
end data
section '.rsrc' resource from 'ftut_08-01.res' data readable

ftut-08-01.rc

Code:
#define ZZZ_TEST 0
#define ZZZ_OPEN 1
#define ZZZ_SAVE 2
#define ZZZ_EXIT 3

ZZZ_Menu MENU 
{
        POPUP "&File"
        {       MENUITEM "&Test",ZZZ_TEST
                MENUITEM "&Open",ZZZ_OPEN
                MENUITEM "&Save",ZZZ_SAVE
                MENUITEM SEPARATOR
                MENUITEM "&Exit",ZZZ_EXIT
        }
        MENUITEM "&Exit",ZZZ_EXIT
}

bat-file

Code:
set masm32_path=\masm32\
set filename=ftut_08-01
%masm32_path%\bin\RC /r /i"%masm32_path%\Include" %filename%.rc



Description:
Filesize: 30.41 KB
Viewed: 884 Time(s)

00.png


Description:
Download
Filename: ftut_08-01.zip
Filesize: 2.63 KB
Downloaded: 51 Time(s)

Post 19 Jun 2017, 12:29
View user's profile Send private message Reply with quote
Marut



Joined: 18 Jun 2017
Posts: 7
Location: Veneto, Italy
Hi everyone, thank you all for your help.

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:
  1. 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.
  2. 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.
  3. 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.
  4. 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.

    1. 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.
    2. Open the VS editor
    3. Select File > New > Project
    4. 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
    5. Select View > Resource View
    6. Select Project > Add new element...
    7. 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
    8. 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.
    9. 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
    10. 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

    Quote:
    "C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x86\rc.exe" /D _UNICODE /D UNICODE /l0x0409 /nologo /i"C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um" /i"C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\shared" /fo<outputfile> <inputfile>

    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.
  5. 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)
Post 21 Jun 2017, 17:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15152
Location: GW170817
The macros in fasm and fasmg are reasonably powerful. It would also be possible to make a resource compiler using macros.
Post 21 Jun 2017, 18:56
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 814
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). Smile
Post 21 Jun 2017, 21:22
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6585
Location: Kraków, Poland

Marut wrote:
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.

Thank you. I believe I have it fixed now.
Post 21 Jun 2017, 21:38
View user's profile Send private message Visit poster's website Reply with quote
TheRaven



Joined: 22 Apr 2008
Posts: 73
Location: U.S.A.

Furs wrote:
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). Smile



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

_________________
Nothing is so sought after and often avoided as the truth.
Post 15 Sep 2017, 20:51
View user's profile Send private message Reply with quote
ctl3d32



Joined: 30 Dec 2009
Posts: 204
Location: Brazil
This is the RC compiler i use: GoRC. It's great.

http://www.godevtool.com/index.htm
Post 18 Sep 2017, 10:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.