#pragma once
#include <Windows.h>

/* C */
typedef BOOL(WINAPI *CLOSEHANDLE)(_In_ HANDLE hObject);
typedef HANDLE(WINAPI *CREATEFILEA)(_In_ LPCTSTR lpFileName, _In_ DWORD  dwDesiredAccess, _In_ DWORD dwShareMode, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes, _In_opt_ HANDLE hTemplateFile);
typedef BOOL(WINAPI *CREATEPIPE)(_Out_ PHANDLE hReadPipe, _Out_ PHANDLE hWritePipe, _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes, _In_ DWORD nSize);
typedef BOOL(WINAPI *CREATEPROCESSA)(_In_opt_    LPCSTR lpApplicationName, _Inout_opt_ LPCSTR  lpCommandLine, _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_        BOOL    bInheritHandles, _In_        DWORD   dwCreationFlags, _In_opt_    LPVOID  lpEnvironment, _In_opt_    LPCSTR lpCurrentDirectory, _In_        LPSTARTUPINFO         lpStartupInfo, _Out_       LPPROCESS_INFORMATION lpProcessInformation);
typedef HANDLE(WINAPI *CREATETHREAD)(_In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes, _In_ SIZE_T  dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_  LPVOID  lpParameter, _In_ DWORD   dwCreationFlags, _Out_opt_ LPDWORD lpThreadId);

/* D */
typedef BOOL(WINAPI *DELETEFILE)(_In_ LPCTSTR lpFileName);

/* E */
typedef void(WINAPI *ENTERCRITICALSECTION)(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
typedef DWORD (WINAPI *EXPANDENVIRONMENTSTRINGSA)(_In_ LPSTR lpSrc,	_Out_opt_ LPCSTR lpDst,	_In_ DWORD   nSize);
typedef VOID(WINAPI *EXITTHREAD)(_In_ DWORD dwExitCode);

/* F */
typedef BOOL (WINAPI *FINDCLOSE)(_Inout_ HANDLE hFindFile);
typedef HANDLE (WINAPI *FINDFIRSTFILEA)(_In_ LPCSTR lpFileName,	_Out_ LPWIN32_FIND_DATA lpFindFileData);
typedef BOOL (WINAPI *FINDNEXTFILEA)(_In_ HANDLE hFindFile, _Out_ LPWIN32_FIND_DATA lpFindFileData);
typedef BOOL(WINAPI *FLUSHFILEBUFFERS)(_In_ HANDLE hFile);
typedef BOOL (WINAPI *FREELIBRARY)(_In_ HMODULE hModule);


/* G */
typedef HANDLE(WINAPI *GETCURRENTPROCESS)(void);
typedef UINT (WINAPI *GETDRIVETYPEA)(_In_opt_ LPCSTR lpRootPathName);
typedef DWORD(WINAPI *GETENVIRONMENTVARIABLEA)(_In_opt_  LPCSTR lpName, _Out_opt_ LPSTR  lpBuffer, _In_ DWORD   nSize);
typedef DWORD(WINAPI *GETENVIRONMENTVARIABLEW)(_In_opt_  LPCWSTR lpName, _Out_opt_ LPWSTR  lpBuffer, _In_ DWORD   nSize);
typedef DWORD(WINAPI *GETFILESIZE)(_In_ HANDLE  hFile, _Out_opt_ LPDWORD lpFileSizeHigh);
typedef DWORD(WINAPI *GETLASTERROR)(void);
typedef FARPROC (WINAPI *GETPROCADDRESS)(HMODULE hModule, LPCSTR lpProcName);
typedef VOID(WINAPI *GETSYSTEMTIMEASFILETIME)(_Out_ LPFILETIME lpSystemTimeAsFileTime);
typedef DWORD(WINAPI *GETTICKCOUNT)(void);
typedef LPVOID(WINAPI *GLOBALLOCK)(_In_ HGLOBAL hMem);
typedef BOOL(WINAPI *GLOBALUNLOCK)(_In_ HGLOBAL hMem);

/* I */
typedef void(WINAPI *INITIALIZECRITICALSECTION)(_Out_ LPCRITICAL_SECTION lpCriticalSection);

/* L */
typedef void(WINAPI *LEAVECRITICALSECTION)(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
typedef HLOCAL (WINAPI *LOCALALLOC)(_In_ UINT uFlags,_In_ SIZE_T uBytes);
typedef HMODULE(WINAPI *LOADLIBRARYA)(LPSTR lpFileName);
typedef HLOCAL (WINAPI *LOCALFREE)(_In_ HLOCAL hMem);
typedef HLOCAL (WINAPI *LOCALREALLOC)(_In_ HLOCAL hMem,_In_ SIZE_T uBytes,_In_ UINT   uFlags);

/* O */
typedef void (WINAPI *OUTPUTDEBUGSTRINGA)(_In_opt_ LPCSTR lpOutputString);

/* R */
typedef BOOL(WINAPI *READFILE)(_In_ HANDLE hFile, _Out_ LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead, _Inout_opt_ LPOVERLAPPED lpOverlapped);

/* S */
typedef VOID (WINAPI *SLEEP)(_In_ DWORD dwMilliseconds);

/* V */
typedef LPVOID(WINAPI *VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef LPVOID(WINAPI *VIRTUALALLOCEX)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef BOOL(WINAPI *VIRTUALFREE)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
typedef BOOL(WINAPI *VIRTUALPROTECT)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);

/* W */
typedef DWORD(WINAPI *WAITFORSINGLEOBJECT)(_In_ HANDLE hHandle, _In_ DWORD  dwMilliseconds);
typedef BOOL(WINAPI *WRITEFILE)(_In_ HANDLE hFile, _In_ LPCVOID lpBuffer, _In_  DWORD  nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped);

typedef struct _VTABLE_KERNEL32
{
	/* C */
	CLOSEHANDLE fpCloseHandle;
	CREATEFILEA fpCreateFileA;
	CREATEPIPE fpCreatePipe;
	CREATEPROCESSA fpCreateProcessA;
	CREATETHREAD fpCreateThread;

	/* D */
	DELETEFILE fpDeleteFile;

	/* E */
	ENTERCRITICALSECTION fpEnterCriticalSection;
	EXPANDENVIRONMENTSTRINGSA fpExpandEnvironmentStringsA;
	EXITTHREAD fpExitThread;

	/* F */
	FINDCLOSE fpFindClose;
	FINDFIRSTFILEA fpFindFirstFileA;
	FINDNEXTFILEA fpFindNextFileA;
	FLUSHFILEBUFFERS fpFlushFileBuffers;
	FREELIBRARY fpFreeLibrary;

	/* G */
	GETCURRENTPROCESS fpGetCurrentProcess;
	GETDRIVETYPEA  fpGetDriveTypeA;
	GETENVIRONMENTVARIABLEA fpGetEnvironmentVariableA;
	GETENVIRONMENTVARIABLEW fpGetEnvironmentVariableW;
	GETFILESIZE fpGetFileSize;
	GETLASTERROR	fpGetLastError;
	GETPROCADDRESS fpGetProcAddress;
	GETSYSTEMTIMEASFILETIME fpGetSystemTimeAsFileTime;
	GETTICKCOUNT fpGetTickCount;
	GLOBALLOCK fpGlobalLock;
	GLOBALUNLOCK fpGlobalUnlock;

	/* I */
	INITIALIZECRITICALSECTION fpInitializeCriticalSection;
	
	/* L */
	LEAVECRITICALSECTION fpLeaveCriticalSection;
	LOCALALLOC   fpLocalAlloc;
	LOCALFREE	 fpLocalFree;
	LOCALREALLOC fpLocalRealloc;
	LOADLIBRARYA fpLoadLibraryA;

	/* O */
	OUTPUTDEBUGSTRINGA fpOutputDebugStringA;

	/* R */
	READFILE fpReadFile;

	/* S */
	SLEEP fpSleep;

	/* V */
	VIRTUALALLOC fpVirtualAlloc;
	VIRTUALALLOCEX fpVirtualAllocEx;
	VIRTUALFREE fpVirtualFree;
	VIRTUALPROTECT fpVirtualProtect;

	/* W */
	WAITFORSINGLEOBJECT fpWaitForSingleObject;
	WRITEFILE fpWriteFile;

} VTABLE_KERNEL32, *PVTABLE_KERNEL32;

