Simple example:
include \masm32\include\masm32rt.inc
.code
start:
MsgBox 0, "Hello World", "Masm32:", MB_OK
exit
end start
Without rc file, no problem. But this one-liner as *.rc makes the MsgBox invisible (Win XP SP3):
1 24 "XpManifest.xml"
Any idea why? The manifest is the usual one:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="whatever"
type="win32"
/>
<description></description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Two observations:
- with call InitCommonControls, it works
- when assembled with the MasmBasic library, it also works, although InitCommonControls is not being called.
you can either remove the common controls 6.0 dependency
or reference InitCommonControls/Ex
With "reference" you mean this, right?
include \masm32\include\masm32rt.inc
.code
start:
MsgBox 0, "Hello World", "Masm32:", MB_OK
exit
mov eax, InitCommonControls ; sure that doesn't look logical but it works ;-)
end start
i prefer to invoke InitCommonControlsEx and control the flag bits
but, it seems all you really need is a reference
.DATA
dd InitCommonControls
.CODE
;;;
it could be in the code section, i guess - to avoid an additional section
include \masm32\include\masm32rt.inc
.code
start:
MsgBox 0, "Hello World", "Masm32:", MB_OK
exit
dd InitCommonControls
end start
in reality, you have a data section, but it could be eliminated in this case
Quote from: dedndave on February 07, 2014, 11:06:37 PM
exit
dd InitCommonControls
IMHO it's
manifest nonsense but it works :P
Thank's dedndave and jj2007
Nice trick and it may work in C too ?
void* pICC = InitCommonControls;
depending on which C compiler you are using....
it may recognize that you have a manifest in the project,
and add the call to InitCommonControls/Ex into the startup code
that may be done in a way that is transparent to the programmer
in ASM, we have to make up for such things - and this is a good example of that
Quote from: dedndave on February 08, 2014, 12:02:41 AM
depending on which C compiler you are using....
it may recognize that you have a manifest in the project,
and add the call to InitCommonControls/Ex into the startup code
that may be done in a way that is transparent to the programmer
in ASM, we have to make up for such things - and this is a good example of that
I don't think that C compiler care about manifest, it's a linker thing (and IDE) :icon_confused:
i don't use compilers
but i bet if you add a manifest to a visual C project, it will add the needed code to startup
much like it will perform any required initialization/deinitialization of MSVCRT functionality
Quote from: dedndave on February 08, 2014, 01:25:15 AM
i don't use compilers
but i bet if you add a manifest to a visual C project, it will add the needed code to startup
much like it will perform any required initialization/deinitialization of MSVCRT functionality
MSVCRT: cl.exe with /MD option add /DEFAULTLIB:"MSVCRT" to object file into SECTION .drectve
similar like INCLUDELIB in masm.
Initialization is somewhere in MSVCRT.DLL's DllMain.
dd crt_strlen is not sufficient, i.e. linking in the CRT has no effect.
I've followed the MsgBox down:
MessageBoxTimeout
MessageBoxTimeoutW
MessageBoxIndirect
SoftModalMessageBox
...
call 7E3A490E ; XP SP3...
call 7E3A6048 ; Crucial test
cmp eax, ebx ; if not equal, it will be displayed
...
7E3A760C E8 8A1CFFFF call PeekMessageW
...
7E3A49BF E8 B72B0000 call 7E3A757B ; The BOX, really
It's tedious...
you can save 4 bytes by using MASM's EXTERN directive and the linker option /OPT:NOREF
EXTERN InitCommonControls@0:NEAR
:biggrin:
The 1 and 24 are defined in WinUser.h as:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
And also in the MASM32 windows.inc.
Including a reference does work, but for whatever reason per Microsoft you should link with and call the function:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773175(v=vs.85).aspx
they are defined in windows.inc, but not in resource.h
i usually do something like this...
#include "\masm32\include\resource.h"
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
#ifndef RT_MANIFEST
#define RT_MANIFEST 24
#endif
;#####################################################################################
; manifest file
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "ProjectName.xml"
Quote from: MichaelW on February 08, 2014, 04:26:09 AM
Including a reference does work, but for whatever reason per Microsoft you should link with and call the function:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773175(v=vs.85).aspx
Maybe reference is just enough because then dll is loaded and initialized by OS.
Calling function InitCommonControls() leads just stub function code
mov eax,eax
ret
Link InitCommonControls by ordinal @17 with library generated from this def-file
LIBRARY comctl32.dll
EXPORTS
InitCommonControls@0 @17
http://blogs.msdn.com/b/oldnewthing/archive/2005/07/18/439939.aspx
So it's the DllMain of COMCTL32.DLL that does the initialisation job.
However, Chen's argument chain is not convincing - we observe the contrary:
QuoteRecall that merely listing a lib file in your dependencies doesn't actually cause your program to be bound to the corresponding DLL. You have to call a function in that DLL in order for there to be an import entry for that DLL. And InitCommonControls is that function.
Without the InitCommonControls function, a program that wants to use the shell common controls library would otherwise have no reference to COMCTL32.DLL in its import table. This means that when the program loads, COMCTL32.DLL is not loaded and therefore is not initialized. Which means that it doesn't register its window classes. Which means that your call to the CreateWindow function fails because the window class has not been registered.
Slightly off-topic, but the later linkers let you specify manifest details on the command line, no need for a resource file.
Quote from: jj2007 on February 08, 2014, 12:43:44 PM
However, Chen's argument chain is not convincing - we observe the contrary
His arguments are a bit imprecise, but he gets the essential point across. It's not surprising that a call to InitCommonControls that never executes has the same effect on load-time linking as a call that does execute, or that an EXTERN/EXTERNDEF statement works, or that an InitCommonControls PROTO (which automatically generates an EXTERNDEF) works. But it is surprising, at least to me, that a:
dd InitCommonControls
, even in the data section, also works, like the other methods, causing the linker to create a COMCTL32.DLL reference in the imports:
Imp Addr Hint Import Name from comctl32.dll - Not Bound
-------- ---- ---------------------------------------------------------------
00002000 54 InitCommonControls
Quote from: qWord on February 08, 2014, 03:23:41 AM
you can save 4 bytes by using MASM's EXTERN directive and the linker option /OPT:NOREF
EXTERN InitCommonControls@0:NEAR
:biggrin:
using named variable it is usable for temporary memory place too and not wasted ;)
.data
foo dd InitCommonControls
i wonder.....
we sometimes use LoadLibrary/FreeLibrary, and GetProcAddress to get a function address
i wonder if referencing a function in a library would allow you to use GetModuleHandle
;###############################################################################################
.XCREF
.NoList
INCLUDE \Masm32\Include\Masm32rt.inc
INCLUDE \Masm32\Include\AdvApi32.inc
INCLUDELIB \Masm32\Lib\AdvApi32.lib
.List
;###############################################################################################
.DATA
dd RegCloseKey
szAdvApi db 'AdvApi32.dll',0
szEnumKey db 'RegEnumKeyA',0
;***********************************************************************************************
.DATA?
;###############################################################################################
.CODE
;***********************************************************************************************
_main PROC
INVOKE GetModuleHandle,offset szAdvApi
.if eax
INVOKE GetProcAddress,eax,offset szEnumKey
.endif
print uhex$(eax),13,10
print chr$(13,10)
inkey
INVOKE ExitProcess,0
_main ENDP
;###############################################################################################
END _main
result
77DE53B8
it seems to work :biggrin:
if i comment out
; dd RegCloseKey
it returns 0