Re: Executable enty points incorrectly documented



What does any of this have to do with .NET? The .NET framework does not
receive any special treatment from the OS and is just a bunch of DLLs and
some stub code in the EXE as far as the OS is concerned.



The info on /Entry and /main is specific to Microsoft?s compilers, linkers,
etc. has no bearing on how Borland or Intel or anyone else?s compilers work.
C compilers and linkers that produce binaries for other platforms also have
unrelated behaviour even though they can compile the SAME code.



The OS does care that the PE format is followed by the compiler and that the
instructions are valid for the platform (well actually, the CPU cares about
that and the OS cares about the exception).



The user cares that the program functions as expected; and it usually works
much better when the stack isn?t corrupted! So, the correct entry point
signature is a good thing. Use this one: (C declaration derived from the
/Entry doc in MSDN)



int __stdcall Entry(LPVOID var1, DWORD var2, LPVOID var3)



If you are interested in more detail, I suggest that you fire up windbg and
watch a call to CreateProcess() or LoadLibrary(). You can also search the
archives of this NG as peripherally related topics have been discussed
variously.


"Kornél Pál" <kornelpal@xxxxxxxxxxxxxxxx> wrote in message
news:%23aEJTTaeJHA.5540@xxxxxxxxxxxxxxxxxxxxxxx
Hi,

All these things are correct but this is more specific and related to the
.NET Framework than to Windows API and the C++ linker and does not mention
the actual entry point signatures either.

Where did you find this?

Kornél

m wrote:
I'm not even going to try to figure out what you were thinking when you
wrote this



In the case of an EXE, and process creation:



After the OS loader has created the new process object and setup the
address space, it creates the first thread of the process. This thread
then examines the PE and loads it, and any statically linked
dependencies, into the process' address space. Each module, whether a
DLL or EXE, has an entry point defined in the PE and this is what is
called by the loader. Whatever language your program is written in, this
function must be binary compatible with what the loader expects. That is
to say, that the sequence of CPU instructions must conform to the calling
convention and use / leave the registers & stack in the right state.
Whatever this entry point does internally, whether starting up the .NET
runtime or JRE or CRT, is irrelevant to the loader.



The /Entry option of the MS C/C++ linker LINK.EXE controls the behaviour
of this part of the platform interface. Usually the linker will include
the entry point from the CRT, but with this option, one can override the
default behaviour and specify a custom entry point. This is most useful
when writing applications that do not link to the CRT.



The documentation problem to which you allude is that it is the CRT entry
point that calls one of the versions of main / WinMain that is defined in
your program. If you look at the CRT source that comes with Visual
Studio, you will see how this is accomplished.



There is a similar compiler option for C# (/main), but this does NOT
control the platform interface but allows the application to have an
application entry point that is not named main. The same is true of the
VB option /main because in both cases, the compiler (CSC.EXE or VBC.EXE)
will always create the entry point that the platform will call. And it
can't be any other way with these languages because they can't be used to
write code that could even run as the entry point.



The interaction is similar in the case of a DLL and LoadLibrary().



"Kornél Pál" <kornelpal@xxxxxxxxxxxxxxxx> wrote in message
news:OD5n03VeJHA.4684@xxxxxxxxxxxxxxxxxxxxxxx
Hi,

This is the signature of the managed (.NET) entry point (as it is stated
in the citation) that has nothing to do with native executables/DLLs. Of
course it's good to document that as well but native entry point
signatures are missing:

DWORD WINAPI ExeMain(void);
BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);

Also note that the managed entry when not using the C/C++ runtime that
makes sense because /ENTRY is intended to specify your own entry point
rather than rely on the C/C++ runtime has different signature:

See ECMA-335, Partition II, 15.4.1.2 The .entrypoint directive

Return value may be void, int32, unsigned int32, and either has no
arguments or a single string[] that means that there are six different
possible signatures, none of them mathching the one documented for
/ENTRY.

Kornél

m wrote:
You are correct: this page contains erroneous and confusing
information. The function signature is there though



<snip>

When creating a managed image, the function specified with /ENTRY must
have a signature of (LPVOID var1, DWORD var2, LPVOID var3).

</snip>

though it should really be listed like this

int __stdcall Entry(LPVOID var1, DWORD var2, LPVOID var3)

with a note that a call to ExitProcess is mandatory on some OS versions
when using certain APIs (ie gethostbyname on XP & server 2003) because
they create threads that never die.



This is where the C language, Win32, as a C API, and implementation
details of the platform (ie PE and OS loader) and CRT cross paths. The
documentation is sparse and often confusing; but since hardly any
programs need to care about the details it isn't likely high on
Microsoft's list of things to fix.



"Kornél Pál" <kornelpal@xxxxxxxxxxxxxxxx> wrote in message
news:e6h5rOKeJHA.3708@xxxxxxxxxxxxxxxxxxxxxxx
Hi,

I was speaking about Windows SDK not MSDN Library entirely, but even
if Windows SDK conatins C/C++ documentation I believe that
main/WinMain belong to C/C++ documentation rather than Windows API
documentation. (So we agree on this.)

As for the entry point signature:
I am referreing to
http://msdn.microsoft.com/en-us/library/f9t8842e.aspx
If there is a better version please let me know.

It's correct about the default entry point names used by the linker
and also correct about what those entry points call and because this
is the C/C++ documentation it's entriely correct that it describes the
C/C++ runtime behavior this way.

But this is incorrect:

"The parameters and return value must be defined as documented in the
Win32 API for WinMain (for an .exe file) or DllEntryPoint (for a
DLL)."

Because this is the real entry and because it's possible to use your
own entry point form C/C++ (I actually do this whenever I want to
avoid CRT dependency) here should be the signature of the function
expected by the /ENTRY argument rather than the signature expected by
the CRT entry point wrappers. Neither WinMain nor main (not referenced
here) qualifies as a real entry point.

DllEntryPoint on the other hand is incorrect beause it's name is
documented and used as DllMain so using DllEntryPoint just confuses
the user and makes finding documentation more difficult.

This page does not contain the signature definition of either the EXE
entry point or the DLL entry point.

Kornél

m wrote:
Look at /Entry in MSDN. The signature of the entry point is defined
and many caveats mentioned.



Also, you are absolutely correct in that main / WinMain have nothing
to do with the core of the OS. They are, however, the entry points
used by most C/C++ programs and MSDN contains CRT and other
documentation besides the core OS too. In my MDSN anyway, they are
found under the Windows Management section and not in Win32 at all.







"Kornél Pál" <kornelpal@xxxxxxxxxxxxxxxx> wrote in message
news:49707D7D.7060801@xxxxxxxxxxxxxxxxxxx
Hi,

Thanks for your reply.

You wrote that WinMain is not a starting function in CRT, but an
user-defined entry point for a Windows application.

This is true but this actually should read entry point for a Windows
application written in C/C++.

I believe that the fact that this function is called by the C/C++
runtime clearly backs my opinion that WinMain has nothing to do with
the operating system.

Even if WinMain documentation remains in Windows SDK it would be
wise to explicitly state that support for this entry point is
provided by the C/C++ runtime rather than Windows itself.

My bigger problem however is that the real entry point signature is
not documented anywhere in Windows SDK.

That is the entry point called by Windows in a PE executable and the
entry point signature expected by the linker. For this reason
documentation for the real entry point is definitely missing.

Some comments to Jeroen's opinion:
The fact that WinMain is suppoted both by C/C++ and some Pascal
variants (or any other languages) does not mean that it is an
operating system feature. And the entry point signature of a PE
executable is definitely part of the programming interface (call it
API or ABI) rather than an OS internal.

I agree with him that the Windows SDK's primary targer is C/C++ and
all the header files were written for C/C++. On the other hand as
long as the application binary interface (ABI) is well defined (and
it is) anyone has the chance to write his own comipler or use any
compiler (and language) he/she wants. This means that the function
signatures specified in C are only a representation of the API.

Jeroen also has the point that macros for example are C/C++ specific
but they just provide extra functionality to C/C++ users. Ideally
everything that cannot be expressed using a C function or structure
signature should be documented using texts. And fortunately this is
the case for most of the things.

And I would like to add one more documentation request related to PE
files:

HMODULE and HINSTANCE were two different things in Win16 but in
Win32 (and Win64) they both are the same and some functions use
HMODULE while others HINSTANCE that causes confusion. (See
http://blogs.msdn.com/oldnewthing/archive/2004/06/14/155107.aspx for
a short explanation.)

This HMODULE is also the base address of the module (EXE or DLL)
that means the address of the MZ header of the memory mapped image.

These facts are well known and widely used by the developer
community there are several articles about them but is not
documented by the Windows SDK.

Although - unlike PE entry point signature - this qualifies for
being an OS internal, it is so widely known fact and so many
programs take advantage of it that I can't imagine that it would
change without introducing a new OS API that would break all the
applications anyway so I belive that this should be documented in
Windows SDK as well.

Kornél

Jialiang Ge [MSFT] wrote:
Hello

This is an interesting topic. I basically agree with Jeroen. Here
is the addition of my opinion. (w)mainCRTStartup,
(w)WinMainCRTStartup are the starting addresses from the C runtime
library. They have the same signature of int XXXXX(void). Only one
of them will be compiled:

(The following code is quoted from C:\Program Files\Microsoft
Visual Studio 9.0\VC\crt\src\crtexe.c)

#ifdef _WINMAIN_

#ifdef WPRFLAG
int wWinMainCRTStartup(
#else /* WPRFLAG */
int WinMainCRTStartup(
#endif /* WPRFLAG */

#else /* _WINMAIN_ */

#ifdef WPRFLAG
int wmainCRTStartup(
#else /* WPRFLAG */
int mainCRTStartup(
#endif /* WPRFLAG */

The starting function calls to the user-defined entry point (main
or WinMain) based on the app type. WinMain is not a starting
function in CRT, but an user-defined entry point for a Windows
application. MSVC runtime actually passes some Windows arguments to
WinMain (see the Windows API GetStartupInfo. GetStartupInfo is not
a part of CRT):

(The following code is quoted from C:\Program Files\Microsoft
Visual Studio 9.0\VC\crt\src\crtexe.c)

int wWinMainCRTStartup(
_TUCHAR *lpszCommandLine;
STARTUPINFO StartupInfo;
BOOL inDoubleQuote=FALSE;

.....
__try {
/*
Note: MSDN specifically notes that
GetStartupInfo returns no error, and throws unspecified SEH if it
fails, so
the very general exception handler below is
appropriate
*/
GetStartupInfo( &StartupInfo );
} __except(EXCEPTION_EXECUTE_HANDLER) {
return 255;
}

.....

mainret = WinMain(
#endif /* WPRFLAG */
(HINSTANCE)&__ImageBase,
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);

.....


Therefore, I feel that it is reasonable to place WinMain in Win32
documentation, instead of C/C++ documentation. This is my opinion.
Please feel free to further discuss it with me.


Regards,
Jialiang Ge (jialge@xxxxxxxxxxxxxxxxxxxx, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your
comments and suggestions about how we can improve the support we
provide to you. Please feel free to let my manager know what you
think of the level of service provided. You can send feedback
directly to my manager at: msdnmg@xxxxxxxxxxxxxx

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each
follow up response may take approximately 2 business days as the
support professional working with you may need further
investigation to reach the most efficient resolution. The offering
is not appropriate for situations that require urgent, real-time or
phone-based interactions. Issues of this nature are best handled
working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.






.



Relevant Pages

  • Re: Executable enty points incorrectly documented
    ... You wrote that WinMain is not a starting function in CRT, but an user-defined entry point for a Windows application. ... I believe that the fact that this function is called by the C/C++ runtime clearly backs my opinion that WinMain has nothing to do with the operating system. ... Even if WinMain documentation remains in Windows SDK it would be wise to explicitly state that support for this entry point is provided by the C/C++ runtime rather than Windows itself. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Executable enty points incorrectly documented
    ... you are absolutely correct in that main / WinMain have nothing to do ... They are, however, the entry points used by most ... they are found under the Windows Management ... My bigger problem however is that the real entry point signature is not ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Executable enty points incorrectly documented
    ... This is the signature of the managed entry point that has nothing to do with native executables/DLLs. ... The documentation is sparse and often confusing; but since hardly any programs need to care about the details it isn't likely high on Microsoft's list of things to fix. ... I was speaking about Windows SDK not MSDN Library entirely, but even if Windows SDK conatins C/C++ documentation I believe that main/WinMain belong to C/C++ documentation rather than Windows API documentation. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Executable enty points incorrectly documented
    ... I was speaking about Windows SDK not MSDN Library entirely, but even if Windows SDK conatins C/C++ documentation I believe that main/WinMain belong to C/C++ documentation rather than Windows API documentation. ... It's correct about the default entry point names used by the linker and also correct about what those entry points call and because this is the ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Executable enty points incorrectly documented
    ... The function signature is there though ... belong to C/C++ documentation rather than Windows API documentation. ... As for the entry point signature: ...
    (microsoft.public.win32.programmer.kernel)

Loading