http://blog.kalmbachnet.de/?postid=65
It seem that there is a subtle difference between how a console application (the main() CRT function) and a Win32 application (WinMain) is handling the process termination.
if you have this:
DWORD WINAPI MyThread2(LPVOID)
{
while(true) { }
return 0;
}
#pragma comment(linker, "/entry:myMain")
int WINAPI myMain()
{
DWORD dwThreadId;
CloseHandle(CreateThread(NULL, 0, MyThread2, NULL, 0, &dwThreadId));
return 0;
}
the application is a windows application (using myMain entrypoint) and it run infinitely.
but a similar console application:
int t_main()
{
DWORD dwThreadId;
CloseHandle(CreateThread(NULL, 0, MyThread2, NULL, 0, &dwThreadId));
return 0;
}
will return immediately after the 'return 0;'
the difference is this one:
the console application uses CRT which, after the user code return from main, it calls ExitProcess which terminates the application.
it seems that when a thread terminates, Win OS internally calls EndThread. The EndThread internally looks if there is any other thread running in the process and calls TerminateThread(if there are any) or ExitProcess (if there isnt any).
hence, in a Win32 application, if any thread returns, internally EndThread is called and this in turn, if no other threads are still running, will call ExitProcess.
in a CRT app, when the main thread returns, ExitProcess is called directly.