0

I am working on a legacy program, the executable is coded in C using just the Windows API, with Visual C++ 6.0.

Since all default libraries are removed, I cannot use WinMain() as normal. How can I specify a new entry point, I cannot find the option anywhere. I know this is possible as I have done it on Visual Studio C++ 2010.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MessageBoxA(NULL,"Hello World!","info",0);
return 0;
}

Error.

LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
Release/calcy.exe : fatal error LNK1120: 1 unresolved externals
securityauditor
  • 293
  • 3
  • 13

1 Answers1

0

I found it just after posting the question. Add this below header files.

#pragma comment(linker, "/ENTRY:main")
securityauditor
  • 293
  • 3
  • 13
  • 3
    Well, be aware that the declaration of `main` as specified by the C standard does not match whats expected from a Win32 process entry point. First and foremost, a Win32 process entry point function doesn't return (it must call `ExitProcess` with the exit code instead). Also neither the argument list, nor the process environment have been set up either (both expected to be passed to `main` as parameters). Since `main` is something defined by the C language standard, it's a bad idea to use it for direct entry, without the C runtime environment being set up. – datenwolf Feb 08 '23 at 02:47
  • [WinMain is just the conventional name for the Win32 process entry point](https://devblogs.microsoft.com/oldnewthing/20110525-00/?p=10573). That shows what the raw entry point would need to look like. And hints at *some* of the issues you'll have to solve (e.g. no initialized static data). There are many more. – IInspectable Feb 08 '23 at 06:32
  • @datenwolf I am happy to use ExitProcess(0); and I am not using command line arguments. I am not sure what you mean by process environment? I am completely avoiding the CRT. – securityauditor Feb 09 '23 at 23:52
  • @IInspectable I read the article. What do you mean by no initialised static data? Whenever I create a variable I always assign it to something. – securityauditor Feb 09 '23 at 23:55
  • @securityauditor for any variable that lives in the global scope, or a function static, these "assignments" are translated into initialization values in the `.data` segment (technically this is a term introduced by \*nix, but Win32 compilers do understand it as well). This segment however is *not* magically initialized by the OS. The initialization of this segment is part of the responsibilities of the runtime, carried out through the entry function, before calling `main` or `WinMain`. If you're avoiding the CRT, you'll have to do these tasks yourself. – datenwolf Feb 10 '23 at 01:00
  • @datenwolf So whenever I create a global variable, or a variable within a static function, make sure I initialise it. I normally use the highest /WALL warning level which forces me to initialise variables, and the C99 standard makes me declare all variables at the top of my function (I know there are ways to get around this but I like doing it). – securityauditor Feb 10 '23 at 01:43
  • 1
    This is literally just scratching the surface. The amount of work the CRT does for you is mind-boggling. I'm not sure you have understood the consequences of not using the CRT just yet (here's another one: No 64-bit integer arithmetic for 32-bit code). – IInspectable Feb 10 '23 at 17:30
  • @securityauditor: Yes, among other things: These static / global scope initializers are translated into a chunk of data + location info, written to a specific position of the executable binary (file). It is the responsibility of the CRT to locate that chunk of data + location info in the binary (file), and use it, to copy the init data to the locations specified. – datenwolf Feb 10 '23 at 17:37