The MASM Forum

General => The Campus => Topic started by: jj2007 on February 07, 2014, 10:21:30 AM

Title: Manifest plays foul
Post by: jj2007 on February 07, 2014, 10:21:30 AM
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.
Title: Re: Manifest plays foul
Post by: dedndave on February 07, 2014, 10:28:25 AM
you can either remove the common controls 6.0 dependency
or reference InitCommonControls/Ex
Title: Re: Manifest plays foul
Post by: jj2007 on February 07, 2014, 06:02:47 PM
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
Title: Re: Manifest plays foul
Post by: dedndave on February 07, 2014, 11:06:37 PM
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
Title: Re: Manifest plays foul
Post by: jj2007 on February 07, 2014, 11:33:55 PM
Quote from: dedndave on February 07, 2014, 11:06:37 PM
   exit
   dd InitCommonControls

IMHO it's manifest nonsense but it works :P
Title: Re: Manifest plays foul
Post by: TWell on February 07, 2014, 11:41:08 PM
Thank's dedndave and jj2007
Nice trick and it may work in C too ?
void* pICC = InitCommonControls;
Title: Re: Manifest plays foul
Post by: 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
Title: Re: Manifest plays foul
Post by: TWell on February 08, 2014, 01:15:49 AM
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:
Title: Re: Manifest plays foul
Post by: 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
Title: Re: Manifest plays foul
Post by: TWell on February 08, 2014, 02:04:47 AM
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.
Title: Re: Manifest plays foul
Post by: jj2007 on February 08, 2014, 02:59:19 AM
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...
Title: Re: Manifest plays foul
Post by: 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:
Title: Re: Manifest plays foul
Post by: MichaelW on February 08, 2014, 04:26:09 AM
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



Title: Re: Manifest plays foul
Post by: dedndave on February 08, 2014, 09:05:26 AM
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"
Title: Re: Manifest plays foul
Post by: TWell on February 08, 2014, 09:55:28 AM
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 codemov eax,eax
ret


Link InitCommonControls by ordinal @17 with library generated from this def-fileLIBRARY comctl32.dll
EXPORTS
InitCommonControls@0 @17
Title: Re: Manifest plays foul
Post by: MichaelW on February 08, 2014, 12:27:04 PM
http://blogs.msdn.com/b/oldnewthing/archive/2005/07/18/439939.aspx
Title: Re: Manifest plays foul
Post by: jj2007 on February 08, 2014, 12:43:44 PM
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.
Title: Re: Manifest plays foul
Post by: sinsi on February 08, 2014, 03:06:50 PM
Slightly off-topic, but the later linkers let you specify manifest details on the command line, no need for a resource file.
Title: Re: Manifest plays foul
Post by: MichaelW on February 08, 2014, 04:23:47 PM
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

Title: Re: Manifest plays foul
Post by: TWell on February 08, 2014, 09:05:36 PM
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
Title: Re: Manifest plays foul
Post by: dedndave on February 09, 2014, 02:16:36 AM
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
Title: Re: Manifest plays foul
Post by: dedndave on February 09, 2014, 02:29:01 AM
;###############################################################################################

        .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