Hi all,
In C, WinMain is defined as:

int WINAPI WinMain(
HINSTANCE hInstance, // handle of current instance
HINSTANCE hPrevInstance, // handle of previous instance
LPSTR lpszCmdLine, // pointer to command line
int nCmdShow // show state of window
);
Parameters

effectively, lpszCmdLine *will* contain a pointer to the commandline.

---

When my asm program starts, I thus expected to find the very same thing at (I looked for it also at and in many other addresses, relative to the start of the program), but I couldn't find anything. Only KERNEL32's GetCommandLineA gave me the command line string.

My question is: is this normal? I.e. Windows will NOT pass the commandline automatically, but it's just that C/C++ compilers normally call GetCommandLineA to give our WinMain that pointer?

So instead I should expect the command line in my asm program without having the need to call GetCommandLineA?

Thanks,
Maverick
Posted on 2002-01-16 17:57:54 by Maverick
On entry of a win32 program... your stack is valid, FPU stack should
be empty, direction flag is clear (CLD). You can *not* depend on
any register values. On all current win32 versions, contains
a return address to kernel32 that will eventually end your program
(but you shouldn't really depend on this either - it's not guaranteed
anywhere).

Yes, all the usual WinMain stuff is handled by libc code, just like
main() is. WinMain is generally deemed practial, so a lot of languages
has picked it up.
Posted on 2002-01-16 18:42:54 by f0dder
Hi f0dder,
Sorry if I ask a further question.. I'm so stressed/tired that my IQ is about 10% of what it uses to be (very low :grin: ).

So,

On entry of a win32 program... your stack is valid, FPU stack should
be empty, direction flag is clear (CLD). You can *not* depend on
any register values. On all current win32 versions, contains
a return address to kernel32 that will eventually end your program


Do , , , contain any valid information?

Greets,
Maverick
Posted on 2002-01-16 19:23:14 by Maverick
Many programs, like the GENERIC sample with MASM32, call GetCommandLine before they invoke WinMain. :)
Posted on 2002-01-16 22:45:40 by S/390
maverick, check out this link
Posted on 2002-01-17 03:15:46 by mob
Maverick,

The address of the commandline in WinMain is a leftover of 16 bit windows, so is the previous instance handle. Some compilers supply the lpszCommandLine parameter but they do it from GetCommandLine API.

Its easy enough, if you need a command line you use this API then remove the actual file name from the command line. There are a number of library modules in MASM32 that will do this.

Regards,

hutch@movsd.com
Posted on 2002-01-17 03:28:46 by hutch--
Maverick, *anything* on the stack on win32 entry is undefined and
undocumented. Yes, as mob's link shows, there is stuff there. But
you should not touch this stuff... you just don't have *any* chance
of knowing whether it will be there or not (ie, will you be running
on a 9x or on a NT, and you might have to take into consideration
things like service packs). The " == return-into-kernel32" is
safe on all current win32 versions I know of (except perhaps win32s
for win3.x?). But even that is not guaranteed to work in the next
version of windows.
Posted on 2002-01-17 06:24:03 by f0dder
S/390:

Thanks for the info :)

---

mob:

Nice doc.. thank you. Also, I bought a 2nd hand copy of Pietrek's book many
months ago, but didn't have time yet to read it. It skipped many entries in
my schedule list now.

---

hutch:

Thanks for your info too.

---

Greets,
Maverick
Posted on 2002-01-17 07:26:58 by Maverick
f0dder:

What you say is quite redundant and obvious.

Having my own "OS" includes the advantage that I can fix my library and loader, and then this will reflect automatically to all of my programs (a single, generic patch that recognizes it's one of my programs and patches their loader/win_interface). In case this will be really necessary someday, of course!
Posted on 2002-01-17 07:31:52 by Maverick
When you create a C/C++ program, WinMain is not the start address. A startup routine gets the command line and instance handle, initializes global objects (C++), and finally calls WinMain().
Posted on 2002-01-18 18:10:30 by tank
Hi tank,

When you create a C/C++ program, WinMain is not the start address. A startup routine gets the command line and instance handle, initializes global objects (C++), and finally calls WinMain().


Thank you. Now I'm 100% certain that I've to do those API calls to get the commandline, etc.. and that asm and C/C++ compilers' environment are different in this field.

BTW: what's the best API call to get the handle of my application, since it's not on the stack at the start of my asm program (used to be in VC++)?

Greets,
Mav
Posted on 2002-01-18 18:13:50 by Maverick
GetModuleHandle(NULL). hIstance is the same as your imagebase,
so you *could* use 0x400000. But I advice against this on "normal"
systems, as... well... they might change it to be a "handle" one day.
Posted on 2002-01-18 18:23:14 by f0dder
Again, from the same GENERIC example:



CommandLine dd 0
hInstance dd 0
...
start: invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT


:)
Posted on 2002-01-18 22:44:33 by S/390
Hi all,

f0dder: yup, I'll use GetModuleHandle(NULL) of course.. because not only using the imagebase could possibly mean leaving a bug behind, but there would be no serious speed advantages in using it anyway (there would be none, for the matter). ;)

S/390: thx for the code snippets pal.

Greets,
Maverick
Posted on 2002-01-19 02:10:44 by Maverick
Maverick,

Try and think of the WinMain this way, various compilers construct the WinMain so that it is partially compatible with the old 16 bit version but it comes from maintaining the compatibility with old 16 bit code.

Writing in assembler gives you the freedom to start a program any way you want and that means with OR without the command line. You almost exclusively need the hInstance as various API calls use it and there is no previous instance handle to get, 32 bit windows does not use it.

The earlier example code in MASM32 duplicated the WinMain but later code has no need to do it, once you have the code entry point, you write the code you need, at that entry point you have NOTHING that you do not write yourself so there is no additional overhead that you don't need.

Regards,

hutch@movsd.com
Posted on 2002-01-19 02:52:04 by hutch--