/*
* ExitThrd.c
*
* Sample code for "Multithreading Applications in Win32"
* This is from Chapter 2, Listing 2-3
*
* Demonstrate ExitThread
*/
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
DWORD WINAPI ThreadFunc(LPVOID);
void AnotherFunc(void);
int main()
{
HANDLE hThrd;
DWORD exitCode = 0;
DWORD threadId;
hThrd = CreateThread(NULL,
0,
ThreadFunc,
(LPVOID)1,
0,
&threadId );
if (hThrd)
printf("Thread launched\n");
for(;;)
{
BOOL rc;
rc = GetExitCodeThread(hThrd, &exitCode);
if (rc && exitCode != STILL_ACTIVE )
break;
}
CloseHandle(hThrd);
printf("Thread returned %d\n", exitCode);
return EXIT_SUCCESS;
}
/*
* Call a function to do something that terminates
* the thread with ExitThread instead of returning.
*/
DWORD WINAPI ThreadFunc(LPVOID n)
{
printf("Thread running\n");
AnotherFunc();
return 0;
}
void AnotherFunc()
{
printf("About to exit thread\n");
ExitThread(4);
// It is impossible to get here, this line
// will never be printed
printf("This will never print\n");
}
od
00401000 /$ 83EC 08 sub esp, 8
00401003 |. 53 push ebx
00401004 |. 56 push esi
00401005 |. 8D4424 0C lea eax, dword ptr [esp+C]
00401009 |. 57 push edi
0040100A |. 50 push eax ; /pThreadId
0040100B |. 6A 00 push 0 ; |CreationFlags = 0
0040100D |. 6A 01 push 1 ; |pThreadParm = 00000001
0040100F |. 68 80104000 push 00401080 ; |ThreadFunction = ExitThrd.00401080
00401014 |. 6A 00 push 0 ; |StackSize = 0
00401016 |. 6A 00 push 0 ; |pSecurity = NULL
00401018 |. C74424 24 000>mov dword ptr [esp+24], 0 ; |
00401020 |. FF15 04204000 call dword ptr [<&KERNEL32.CreateThre>; \CreateThread
00401026 |. 8B1D 14204000 mov ebx, dword ptr [<&MSVCRTD.printf>; MSVCRTD.printf
0040102C |. 8BF0 mov esi, eax
0040102E |. 85F6 test esi, esi
00401030 |. 74 0A je short 0040103C
00401032 |. 68 24304000 push 00403024 ; /format = "Thread launched",LF,""
00401037 |. FFD3 call ebx ; \printf
00401039 |. 83C4 04 add esp, 4
0040103C |> 8B3D 00204000 mov edi, dword ptr [<&KERNEL32.GetEx>; kernel32.GetExitCodeThread
00401042 |> 8D4C24 0C /lea ecx, dword ptr [esp+C]
00401046 |. 51 |push ecx
00401047 |. 56 |push esi
00401048 |. FFD7 |call edi
0040104A |. 85C0 |test eax, eax
0040104C |.^ 74 F4 |je short 00401042
0040104E |. 817C24 0C 030>|cmp dword ptr [esp+C], 103 ; still_alive
00401056 |.^ 74 EA \je short 00401042
00401058 |. 56 push esi ; /hObject
00401059 |. FF15 0C204000 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle
0040105F |. 8B5424 0C mov edx, dword ptr [esp+C]
00401063 |. 52 push edx
00401064 |. 68 10304000 push 00403010 ; ASCII "Thread returned %d",LF
00401069 |. FFD3 call ebx ; printf
0040106B |. 83C4 08 add esp, 8
0040106E |. 33C0 xor eax, eax
00401070 |. 5F pop edi
00401071 |. 5E pop esi
00401072 |. 5B pop ebx
00401073 |. 83C4 08 add esp, 8
00401076 \. C3 retn
thread
00401080 . 68 38 30 40 0>ascii "h80@",0
00401085 . FF15 14204000 call dword ptr [<&MSVCRTD.printf>] ; \printf
0040108B . 83C4 04 add esp, 4
0040108E . E8 0D000000 call 004010A0
00401093 . 33C0 xor eax, eax
00401095 . C2 0400 retn 4
00401098 90 nop
00401099 90 nop
0040109A 90 nop
0040109B 90 nop
0040109C 90 nop
0040109D 90 nop
0040109E 90 nop
0040109F 90 nop
004010A0 /$ 56 push esi
004010A1 |. 8B35 14204000 mov esi, dword ptr [<&MSVCRTD.printf>; MSVCRTD.printf
004010A7 |. 68 60304000 push 00403060 ; /format = "About to exit thread",LF,""
004010AC |. FFD6 call esi ; \printf
004010AE |. 83C4 04 add esp, 4
004010B1 |. 6A 04 push 4 ; /ExitCode = 4
004010B3 \. FF15 08204000 call dword ptr [<&KERNEL32.ExitThread>; \ExitThread
004010B9 . 68 48 30 40 0>ascii "hH0@",0
004010BE . FFD6 call esi
004010C0 . 83C4 04 add esp, 4
004010C3 . 5E pop esi
004010C4 . C3 retn
ida
.text:00401000
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000
.text:00401000 ; int __cdecl main(int argc, const char **argv, const char *envp)
.text:00401000 _main proc near ; CODE XREF: start+FAp
.text:00401000
.text:00401000 ExitCode = dword ptr -8
.text:00401000 ThreadId = dword ptr -4
.text:00401000 argc = dword ptr 4
.text:00401000 argv = dword ptr 8
.text:00401000 envp = dword ptr 0Ch
.text:00401000
.text:00401000 sub esp, 8
.text:00401003 push ebx
.text:00401004 push esi
.text:00401005 lea eax, [esp+10h+ThreadId]
.text:00401009 push edi
.text:0040100A push eax ; lpThreadId
.text:0040100B push 0 ; dwCreationFlags
.text:0040100D push 1 ; lpParameter
.text:0040100F push offset StartAddress ; lpStartAddress
.text:00401014 push 0 ; dwStackSize
.text:00401016 push 0 ; lpThreadAttributes
.text:00401018 mov [esp+2Ch+ExitCode], 0
.text:00401020 call ds:CreateThread
.text:00401026 mov ebx, ds:printf
.text:0040102C mov esi, eax
.text:0040102E test esi, esi
.text:00401030 jz short loc_40103C
.text:00401032 push offset Format ; "Thread launched\n"
.text:00401037 call ebx ; printf
.text:00401039 add esp, 4
.text:0040103C
.text:0040103C loc_40103C: ; CODE XREF: _main+30j
.text:0040103C mov edi, ds:GetExitCodeThread
.text:00401042
.text:00401042 loc_401042: ; CODE XREF: _main+4Cj
.text:00401042 ; _main+56j
.text:00401042 lea ecx, [esp+14h+ExitCode]
.text:00401046 push ecx ; lpExitCode
.text:00401047 push esi ; hThread
.text:00401048 call edi ; GetExitCodeThread
.text:0040104A test eax, eax
.text:0040104C jz short loc_401042
.text:0040104E cmp [esp+14h+ExitCode], STILL_ACTIVE
.text:00401056 jz short loc_401042
.text:00401058 push esi ; hObject
.text:00401059 call ds:CloseHandle
.text:0040105F mov edx, [esp+14h+ExitCode]
.text:00401063 push edx
.text:00401064 push offset aThreadReturned ; "Thread returned %d\n"
.text:00401069 call ebx ; printf
.text:0040106B add esp, 8
.text:0040106E xor eax, eax
.text:00401070 pop edi
.text:00401071 pop esi
.text:00401072 pop ebx
.text:00401073 add esp, 8
.text:00401076 retn
.text:00401076 _main endp
.text:00401076
.text:00401076 ; ---------------------------------------------------------------------------
.text:00401077 align 10h
.text:00401080
thread
.text:00401080 ; =============== S U B R O U T I N E =======================================
.text:00401080
.text:00401080 ; Attributes: noreturn
.text:00401080
.text:00401080 ; DWORD __stdcall StartAddress(LPVOID)
.text:00401080 StartAddress proc near ; DATA XREF: _main+Fo
.text:00401080 push offset aThreadRunning ; "Thread running\n"
.text:00401085 call ds:printf
.text:0040108B add esp, 4
.text:0040108E call anotherfunc
.text:0040108E StartAddress endp
.text:004010A0 ; =============== S U B R O U T I N E =======================================
.text:004010A0
.text:004010A0 ; Attributes: noreturn
.text:004010A0
.text:004010A0 anotherfunc proc near ; CODE XREF: StartAddress+Ep
.text:004010A0 push esi
.text:004010A1 mov esi, ds:printf
.text:004010A7 push offset aAboutToExitThr ; "About to exit thread\n"
.text:004010AC call esi ; printf
.text:004010AE add esp, 4
.text:004010B1 push 4 ; dwExitCode
.text:004010B3 call ds:ExitThread
.text:004010B3 anotherfunc endp
.text:004010B3
.text:004010B9 ; ---------------------------------------------------------------------------