// Executable_text.c
// Generated by decompiling Executable.exe
// using Reko decompiler version 0.11.6.0.

#include "Executable.h"

// 00401000: Register word32 fn00401000()
// Called from:
//      Win32CrtStartup
word32 fn00401000()
{
	InitializeCriticalSection(&exported_critical_section);
	fn00401060(0x00402108);
	slow_and_safe_increment(0x01);
	fn00401060(0x00402108);
	fn00401060(0x00402108);
	return 0x00;
}

// 00401050: Register ptr32 fn00401050()
// Called from:
//      fn00401060
//      fn0040173F
ptr32 fn00401050()
{
	return &g_t403378;
}

// 00401060: void fn00401060(Stack word32 dwArg04)
// Called from:
//      fn00401000
void fn00401060(word32 dwArg04)
{
	word32 eax_n = _acrt_iob_func(0x01);
	struct Eq_n * esp_n;
	ptr32 fp;
	esp_n->ptr0000 = fp + 8;
	esp_n->dwFFFFFFFC = 0x00;
	esp_n->dwFFFFFFF8 = dwArg04;
	esp_n->dwFFFFFFF4 = eax_n;
	struct Eq_n * eax_n = fn00401050();
	_stdio_common_vfprintf(eax_n->dw0000, eax_n->dw0004);
}

// 004012CE: Register Eq_n Win32CrtStartup()
Eq_n Win32CrtStartup()
{
	ptr32 fp;
	ui32 dwLoc0C;
	Eq_n edi;
	Eq_n esi;
	word32 ebx;
	word24 ebx_24_8_n = SLICE(ebx, word24, 8);
	fn00401663();
	struct Eq_n * ebp_n = fn00401980(ebx, esi, edi, dwLoc0C, 0x14);
	word32 * esp_n = fp - 8;
	word32 edx;
	if (fn00401474(edx, 0x01) == 0x00)
	{
l00401177:
		esp_n -= 4;
		*esp_n = 0x07;
		fn00401774(*esp_n);
	}
	ebp_n->bFFFFFFE7 = 0x00;
	ebp_n->dwFFFFFFFC = 0x00;
	ebp_n->tFFFFFFDC.u0 = (byte) fn0040143F();
	struct Eq_n * ebp_n = ebp_n;
	word32 eax_n = g_dw403334;
	word32 ebx_n = SEQ(ebx_24_8_n, 0x00);
	if (eax_n != 0x01)
	{
		struct Eq_n * esp_n;
		Eq_n eax_n;
		if (eax_n == 0x00)
		{
			g_dw403334 = 0x01;
			struct Eq_n * esp_n = esp_n - 4;
			esp_n->ptr0000 = &g_t4020EC;
			esp_n->ptrFFFFFFFC = &g_t4020E0;
			esp_n = (struct Eq_n *) ((char *) &esp_n->ptr0000 + 4);
			if (_initterm_e(esp_n->ptrFFFFFFFC, esp_n->ptr0000) != 0x00)
			{
				ebp_n->dwFFFFFFFC = ~0x01;
				eax_n.u0 = 0xFF;
				goto l004012C8;
			}
			esp_n->ptr0000 = &g_t4020DC;
			esp_n->ptrFFFFFFFC = &g_t4020D4;
			_initterm(esp_n->ptrFFFFFFFC, esp_n->ptr0000);
			g_dw403334 = 0x02;
		}
		else
		{
			ebp_n->bFFFFFFE7 = 0x01;
			ebx_n = SEQ(ebx_24_8_n, 0x01);
		}
		struct Eq_n * esp_n = esp_n - 4;
		esp_n->t0000.u1 = ebp_n->tFFFFFFDC.u1;
		fn004015CE(esp_n->t0000.u0);
		struct Eq_n * esp_n = (struct Eq_n *) ((char *) &esp_n->t0000 + 4);
		Eq_n eax_n = fn00401768();
		Eq_n edi_n;
		edi_n.u0 = 0x00;
		if (eax_n.u1->t0000.u1 != 0x00)
		{
			esp_n->t0000.u1 = (struct Eq_n *) eax_n;
			esp_n = (struct Eq_n *) ((char *) &esp_n->t0000 + 4);
			word32 edx_n;
			<anonymous> ** esi_n;
			if (fn00401544(ebx_n, eax_n, 0x00, out edx_n, out ebx_n, out ebp_n, out esi_n, out edi_n) != 0x00)
			{
				esp_n->t0000.u1 = (struct Eq_n *) edi_n;
				esp_n->dwFFFFFFFC = 0x02;
				esp_n->tFFFFFFF8.u1 = (struct Eq_n *) edi_n;
				<anonymous> * esi_n = (<anonymous> *) *esi_n;
				fn00401976();
				esi_n();
			}
		}
		Eq_n eax_n = fn0040176E();
		if (eax_n.u1->t0000.u1 != edi_n)
		{
			esp_n->tFFFFFFFC.u1 = (struct Eq_n *) eax_n;
			word32 edx_n;
			word32 * esi_n;
			word32 edi_n;
			if (fn00401544(ebx_n, eax_n, edi_n, out edx_n, out ebx_n, out ebp_n, out esi_n, out edi_n) != 0x00)
				register_thread_local_exe_atexit_callback(*esi_n);
		}
		char *** eax_n = __p___argv();
		int32 * eax_n = __p___argc();
		struct Eq_n * esp_n;
		esp_n->tFFFFFFFC.u0 = (int32) get_initial_narrow_environment();
		esp_n->dwFFFFFFF8 = *eax_n;
		esp_n->dwFFFFFFF4 = *eax_n;
		Eq_n eax_n = fn00401000();
		byte bl_n = (byte) ebx_n;
		struct Eq_n * esp_n = esp_n;
		if (fn0040188F() == 0x00)
		{
			esp_n->tFFFFFFFC.u0 = (int32) eax_n;
			exit(esp_n->tFFFFFFFC.u0);
		}
		if (bl_n == 0x00)
			cexit();
		struct Eq_n * esp_n = esp_n - 4;
		esp_n->t0000.u1 = 0x00;
		esp_n->dwFFFFFFFC = 0x01;
		fn004015EB(esp_n->t0000.u0);
		ebp_n->dwFFFFFFFC = ~0x01;
		esp_n = (struct Eq_n *) ((char *) &esp_n->t0000 + 4);
		eax_n = eax_n;
l004012C8:
		word32 ebp_n;
		word32 esi_n;
		word32 edi_n;
		fn004019C6(ebp_n, esp_n->dwFFFFFFFC, out ebp_n, out esi_n, out edi_n);
		return eax_n;
	}
	goto l00401177;
}

// 004012D8: void fn004012D8(Stack (ptr32 Eq_n) dwArg04)
void fn004012D8(struct _EXCEPTION_POINTERS * dwArg04)
{
	SetUnhandledExceptionFilter(null);
	UnhandledExceptionFilter(dwArg04);
	TerminateProcess(GetCurrentProcess(), 0xC0000409);
}

// 004013FB: Register (ptr32 Eq_n) fn004013FB(Stack (ptr32 Eq_n) dwArg04, Stack uint32 dwArg08, Register out (ptr32 Eq_n) edxOut)
// Called from:
//      fn00401544
struct Eq_n * fn004013FB(struct Eq_n * dwArg04, uint32 dwArg08, struct Eq_n & edxOut)
{
	struct Eq_n * ecx_n = (struct Eq_n *) ((char *) dwArg04 + dwArg04->dw003C);
	struct Eq_n * edx_n = (struct Eq_n *) ((char *) (&ecx_n->w0014 + 2) + (word32) ecx_n->w0014);
	struct Eq_n * esi_n = edx_n + (word32) ecx_n->w0006;
	struct Eq_n * eax_n;
	for (; edx_n != esi_n; ++edx_n)
	{
		if (dwArg08 >= edx_n->dw000C && dwArg08 < edx_n->dw0008 + edx_n->dw000C)
		{
			eax_n = edx_n;
			goto l00401438;
		}
	}
	eax_n = null;
l00401438:
	edxOut = edx_n;
	return eax_n;
}

// 0040143F: Register byte fn0040143F()
// Called from:
//      Win32CrtStartup
byte fn0040143F()
{
	selector fs;
	if (fn00401B98() == 0x00)
		return 0x00;
	word32 edx_n = fs->ptr0018->dw0004;
	word32 eax_n;
	do
	{
		__lock();
		__cmpxchg<word32>(g_dw403338, edx_n, 0x00, out eax_n);
		if (eax_n == 0x00)
			return 0x00;
	} while (edx_n != eax_n);
	return 0x01;
}

// 00401474: Register byte fn00401474(Register word32 edx, Stack word32 dwArg04)
// Called from:
//      Win32CrtStartup
byte fn00401474(word32 edx, word32 dwArg04)
{
	if (dwArg04 == 0x00)
		g_b403354 = 0x01;
	fn004019FE(edx);
	if (fn00401C48() == 0x00)
		return 0x00;
	if (fn00401C48() != 0x00)
		return 0x01;
	fn00401C48();
	return 0x00;
}

// 004014AD: void fn004014AD(Register word32 ebx, Register Eq_n edi, Stack Eq_n dwArg04)
void fn004014AD(word32 ebx, Eq_n edi, Eq_n dwArg04)
{
	if (dwArg04 == 0x00 || dwArg04 == 0x01)
	{
		if (fn00401B98() != 0x00 && dwArg04 == 0x00)
		{
			if (initialize_onexit_table(0x0040333C) == 0x00)
				initialize_onexit_table(0x00403348);
		}
		else
		{
			ui32 eax_n = __ror<word32,byte>(~0x00, 0x20 - (g_t403004.u1 & 0x1F)) ^ g_t403004.u0;
			g_dw40333C = eax_n;
			g_dw403340 = eax_n;
			g_dw403344 = eax_n;
			g_dw403348 = eax_n;
			g_dw40334C = eax_n;
			g_dw403350 = eax_n;
		}
	}
	else
	{
		fn00401774(0x05);
		int3();
		word32 edx_n;
		word32 ebx_n;
		word32 ebp_n;
		word32 esi_n;
		word32 edi_n;
		fn00401544(ebx, dwArg04, edi, out edx_n, out ebx_n, out ebp_n, out esi_n, out edi_n);
	}
}

// 00401544: Register byte fn00401544(Register word32 ebx, Register Eq_n esi, Register Eq_n edi, Register out word32 edxOut, Register out word32 ebxOut, Register out (ptr32 Eq_n) ebpOut, Register out word32 esiOut, Register out word32 ediOut)
// Called from:
//      Win32CrtStartup
//      fn004014AD
byte fn00401544(word32 ebx, Eq_n esi, Eq_n edi, word32 & edxOut, word32 & ebxOut, struct Eq_n & ebpOut, word32 & esiOut, word32 & ediOut)
{
	word32 edi_n;
	word32 esi_n;
	struct Eq_n * ebp_n;
	word32 edx;
	ui32 dwLoc0C;
	struct Eq_n * ebp_n = fn00401980(ebx, esi, edi, dwLoc0C, 0x08);
	ebp_n->dwFFFFFFFC = 0x00;
	word24 eax_24_8_n = 0x5A;
	word32 eax_n;
	if (g_w400000 == 23117)
	{
		struct Eq_n * eax_n = g_ptr40003C;
		eax_24_8_n = SLICE(eax_n, word24, 8);
		if (eax_n->dw400000 == 0x4550 && eax_n->w400018 == 0x010B)
		{
			ui32 eax_n = ebp_n->dw0008;
			struct Eq_n * eax_n = fn004013FB(&g_w400000, eax_n - 0x00400000, out edx);
			dwLoc0C = eax_n - 0x00400000;
			eax_24_8_n = SLICE(eax_n, word24, 8);
			if (eax_n != null && eax_n->dw0024 >= 0x00)
			{
				ebp_n->dwFFFFFFFC = ~0x01;
				eax_n = SEQ(eax_24_8_n, 0x01);
l004015C8:
				word32 ebx_n = fn004019C6(ebp_n, dwLoc0C, out ebp_n, out esi_n, out edi_n);
				edxOut = edx;
				ebxOut = ebx_n;
				ebpOut = ebp_n;
				esiOut = esi_n;
				ediOut = edi_n;
				return (byte) eax_n;
			}
		}
	}
	ebp_n->dwFFFFFFFC = ~0x01;
	eax_n = SEQ(eax_24_8_n, 0x00);
	goto l004015C8;
}

// 004015CE: void fn004015CE(Stack Eq_n bArg04)
// Called from:
//      Win32CrtStartup
void fn004015CE(Eq_n bArg04)
{
	if (fn00401B98() != 0x00 && bArg04 == 0x00)
		g_dw403338 = 0x00;
}

// 004015EB: void fn004015EB(Stack Eq_n bArg08)
// Called from:
//      Win32CrtStartup
void fn004015EB(Eq_n bArg08)
{
	if (g_b403354 == 0x00 || bArg08 == 0x00)
	{
		fn00401C48();
		fn00401C48();
	}
}

// 00401613: Register ui32 fn00401613(Stack ui32 dwArg04)
// Called from:
//      fn0040164E
ui32 fn00401613(ui32 dwArg04)
{
	Eq_n eax_n;
	eax_n.u0 = g_t403004.u0;
	word32 eax_n;
	if (__ror<word32,byte>(eax_n ^ g_dw40333C, (byte) eax_n & 0x1F) == ~0x00)
		eax_n = crt_atexit();
	else
		eax_n = register_onexit_function(0x0040333C);
	return (word32) (eax_n != 0x00) - 1 & dwArg04;
}

// 0040164E: void fn0040164E(Stack ui32 dwArg04)
void fn0040164E(ui32 dwArg04)
{
	fn00401613(dwArg04);
}

// 00401663: void fn00401663()
// Called from:
//      Win32CrtStartup
void fn00401663()
{
	ptr32 fp;
	Eq_n tLoc10;
	tLoc10.dwLowDateTime = (DWORD) 0x00;
	tLoc10.dwHighDateTime = (DWORD) 0x00;
	Eq_n eax_n;
	eax_n.u0 = g_t403004.u0;
	if (eax_n != 0xBB40E64E && (eax_n & 0xFFFF0000) != 0x00)
		g_t403000.u0 = (ui32) ~eax_n;
	else
	{
		GetSystemTimeAsFileTime(&tLoc10);
		ui32 v17_n = tLoc10.dwHighDateTime ^ tLoc10.dwLowDateTime ^ GetCurrentThreadId() ^ GetCurrentProcessId();
		Eq_n tLoc18;
		QueryPerformanceCounter(&tLoc18);
		Eq_n ecx_n = tLoc18.dw0004 ^ (tLoc18.u).LowPart ^ v17_n ^ fp - 8;
		if (ecx_n == 0xBB40E64E)
			ecx_n.u0 = ~0x44BF19B0;
		else if ((ecx_n & 0xFFFF0000) == 0x00)
			ecx_n |= (ecx_n | 0x4711) << 0x10;
		g_t403004.u0 = (ui32) ecx_n;
		g_t403000.u0 = (ui32) ~ecx_n;
	}
}

// 004016FF: void fn004016FF()
void fn004016FF()
{
}

// 00401703: void fn00401703()
void fn00401703()
{
}

// 00401709: void fn00401709()
void fn00401709()
{
}

// 0040170C: void fn0040170C()
void fn0040170C()
{
	InitializeSListHead(&g_u403358);
}

// 00401718: void fn00401718()
void fn00401718()
{
	if (controlfp_s(0x00, 0x00010000, 0x00030000) == 0x00)
		return;
	fn00401774(0x07);
	int3();
	fn00401739();
}

// 00401739: Register ptr32 fn00401739()
// Called from:
//      fn00401718
//      fn0040173F
ptr32 fn00401739()
{
	return &g_t403360;
}

// 0040173F: void fn0040173F()
void fn0040173F()
{
	struct Eq_n * eax_n = fn00401050();
	word32 ecx_n = eax_n->dw0004;
	eax_n->dw0000 |= 0x04;
	eax_n->dw0004 = ecx_n;
	struct Eq_n * eax_n = fn00401739();
	word32 ecx_n = eax_n->dw0004;
	eax_n->dw0000 |= 0x02;
	eax_n->dw0004 = ecx_n;
}

// 0040175C: void fn0040175C()
void fn0040175C()
{
}

// 00401768: Register ptr32 fn00401768()
// Called from:
//      Win32CrtStartup
ptr32 fn00401768()
{
	return &g_t403388;
}

// 0040176E: Register ptr32 fn0040176E()
// Called from:
//      Win32CrtStartup
ptr32 fn0040176E()
{
	return &g_t403384;
}

// 00401774: void fn00401774(Stack word32 dwArg04)
// Called from:
//      Win32CrtStartup
//      fn004014AD
//      fn00401718
void fn00401774(word32 dwArg04)
{
	if (IsProcessorFeaturePresent(0x17) == 0x00)
	{
		g_dw403368 = 0x00;
		ptr32 fp;
		memset(fp - 808, 0x00, 0x02CC);
		word32 dwLoc5C;
		memset(&dwLoc5C, 0x00, 0x50);
		dwLoc5C = 0x40000015;
		Eq_n eax_n = IsDebuggerPresent();
		Eq_n tLoc0C;
		tLoc0C.ExceptionRecord = (PEXCEPTION_RECORD) &dwLoc5C;
		tLoc0C.ContextRecord = (PCONTEXT) (fp - 808);
		SetUnhandledExceptionFilter(null);
		byte bl_n = 0x00 - (eax_n != 0x01);
		if (UnhandledExceptionFilter(&tLoc0C) == 0x00)
			g_dw403368 &= 0x00 - ((word32) (bl_n + 0x01) != 0x00);
	}
	else
		__fastfail(dwArg04);
}

// 0040188F: Register byte fn0040188F()
// Called from:
//      Win32CrtStartup
byte fn0040188F()
{
	Eq_n eax_n = GetModuleHandleW(null);
	if (eax_n == null || eax_n->unused != 23117)
		return 0x00;
	struct Eq_n * eax_n = eax_n[0x0F] + eax_n;
	if (eax_n->dw0000 != 0x4550 || (eax_n->w0018 != 0x010B || eax_n->dw0074 <= 0x0E))
		return 0x00;
	return (byte) (eax_n->dw00E8 != 0x00);
}

// 004018D3: void fn004018D3()
void fn004018D3()
{
	SetUnhandledExceptionFilter(&g_t4018DF);
}

LONG g_t4018DF(struct _EXCEPTION_POINTERS * ExceptionInfo) = ??/* Unexpected function type (fn LONG ((ptr32 (struct "_EXCEPTION_POINTERS" 0008)))) */ ; // 004018DF
// 00401920: void fn00401920()
void fn00401920()
{
	word32 * esi_n = g_a4024C8;
	if (false)
	{
		do
		{
			if (*esi_n != 0x00)
			{
				fn00401976();
				fn00000000();
			}
			++esi_n;
		} while (esi_n < g_a4024C8);
	}
}

// 00401976: void fn00401976()
// Called from:
//      Win32CrtStartup
//      fn00401920
void fn00401976()
{
	g_ptr4020D0();
}

// 00401980: Register ptr32 fn00401980(Register word32 ebx, Register Eq_n esi, Register Eq_n edi, Stack ui32 dwArg00, Stack ui32 dwArg08)
// Called from:
//      Win32CrtStartup
//      fn00401544
ptr32 fn00401980(word32 ebx, Eq_n esi, Eq_n edi, ui32 dwArg00, ui32 dwArg08)
{
	ptr32 fp;
	struct Eq_n * esp_n = fp - 8 - dwArg08;
	esp_n->dwFFFFFFFC = ebx;
	esp_n->tFFFFFFF8.u1 = (struct Eq_n *) esi;
	esp_n->tFFFFFFF4.u1 = (struct Eq_n *) edi;
	esp_n->tFFFFFFF0.u1 = (word32) (g_t403004.u0 ^ fp + 8);
	esp_n->dwFFFFFFEC = dwArg00;
	selector fs;
	fs->ptr0000 = fp - 8;
	return fp + 8;
}

// 004019C6: Register word32 fn004019C6(Register (ptr32 Eq_n) ebp, Stack ui32 dwArg00, Register out ui32 ebpOut, Register out word32 esiOut, Register out word32 ediOut)
// Called from:
//      Win32CrtStartup
//      fn00401544
word32 fn004019C6(struct Eq_n * ebp, ui32 dwArg00, ui32 & ebpOut, word32 & esiOut, word32 & ediOut)
{
	selector fs;
	fs->dw0000 = ebp->dwFFFFFFF0;
	ui32 ebp_n = ebp->dw0000;
	ebp->dw0000 = dwArg00;
	ebpOut = ebp_n;
	word32 dwArg0C;
	esiOut = dwArg0C;
	word32 dwArg08;
	ediOut = dwArg08;
	word32 dwArg10;
	return dwArg10;
}

// 004019FE: void fn004019FE(Register word32 edx)
// Called from:
//      fn00401474
void fn004019FE(word32 edx)
{
	g_dw40336C = 0x00;
	g_dw403010 |= 0x01;
	if (IsProcessorFeaturePresent(0x0A) != 0x00)
	{
		g_dw403010 |= 0x02;
		g_dw40336C = 0x01;
		__cpuid(0x00, 0x00, &0x00, &0x01, &0x00, &edx);
		__cpuid(0x01, 0x00, &0x01, &0x01, &0x00, &edx);
		byte bLoc14_n = 0x00;
		ui32 edi_n;
		if ((edx ^ 0x49656E69 | 1818588270 | 0x756E6546) == 0x00 && (false || (false || (false || (false || (false || false))))))
		{
			ui32 edi_n = g_dw403370;
			g_dw403370 = edi_n | 0x01;
			edi_n = edi_n | 0x01;
		}
		else
			edi_n = g_dw403370;
		if (false)
		{
			__cpuid(0x07, 0x00, &0x07, &0x01, &0x00, &edx);
			bLoc14_n = 0x01;
			if (false)
				g_dw403370 = edi_n | 0x02;
		}
		if (false)
		{
			g_dw403010 |= 0x04;
			g_dw40336C = 0x02;
			if (false && (false && (((word32) __xgetbv(0x00) & 0x06) == 0x06 && true)))
			{
				ui32 eax_n = g_dw403010;
				g_dw40336C = 0x03;
				g_dw403010 = eax_n | 0x08;
				if ((bLoc14_n & 0x20) != 0x00)
				{
					g_dw40336C = 0x05;
					g_dw403010 = eax_n | 0x08 | 0x20;
				}
			}
		}
	}
}

// 00401B98: Register uint32 fn00401B98()
// Called from:
//      fn0040143F
//      fn004014AD
//      fn004015CE
uint32 fn00401B98()
{
	return (uint32) (g_dw403014 != 0x00);
}

// 00401BA4: void fn00401BA4()
void fn00401BA4()
{
}

// 00401C48: Register byte fn00401C48()
// Called from:
//      fn00401474
//      fn004015EB
byte fn00401C48()
{
	return 0x01;
}

