#pragma once
#include <Windows.h>

/* B */
typedef uintptr_t(__cdecl *_BEGINTHREADEX)(void *security, unsigned stack_size, unsigned(__stdcall *start_address)(void *), void *arglist, unsigned initflag, unsigned *thrdaddr);

/* C */
typedef int(__cdecl *_CLOSE)(int fd);

/* I */
typedef int(__cdecl *ISDIGIT)(int c);
typedef int(__cdecl *ISSPACE)(int c);
typedef errno_t(__cdecl *_ITOA_S)(int value, char *buffer, size_t sizeInCharacters, int radix);
typedef errno_t(__cdecl *_ITOW_S)(int value, wchar_t *buffer, size_t sizeInCharacters, int radix);

/* M */
typedef int(__cdecl *MEMCMP)(const void *buf1, const void *buf2, size_t count);
typedef void* (__cdecl *MEMCPY)(void *dest, const void *src, size_t count);
typedef errno_t (__cdecl *MEMCPY_S)(void *dest, size_t numberOfElements, const void *src, size_t count);
typedef void*(__cdecl *MEMSET)(void *dest, int c, size_t count);

/* O */
typedef int(__cdecl *_OPEN)(const char *filename, int oflag, ...);

/* R */
typedef int(__cdecl *RAND)(void);
typedef int(__cdecl *READ)(int fd, void *buffer, unsigned int count);

/* S */
typedef int(__cdecl *SSCANF)(const char *buffer, const char *format, ...);
typedef int (__cdecl *STRCMP)(const char *string1, const char *string2);
typedef int (__cdecl *_SNPRINTF_S)(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...);
typedef int(__cdecl *_SNPRINTF)(char *buffer, size_t count, const char *format, ...);
typedef void(__cdecl *SRAND)(unsigned int seed);
typedef size_t(__cdecl *STRLEN)(const char *str);
typedef char *(__cdecl *STRRCHR)(const char *str, int c);
typedef int(__cdecl *SSCANF_S)(const char *buffer, const char *format, ...);
typedef errno_t(__cdecl *STRCAT_S)(char *strDestination, size_t numberOfElements, const char *strSource);
typedef char*(__cdecl *STRDUP)(const char *s1);
typedef char*(__cdecl *STRCHR)(const char *str, int c);
typedef int(__cdecl *STRNCMP)(const char *string1, const char *string2, size_t count);
typedef errno_t(__cdecl *STRNCPY_S)(char *strDest, size_t numberOfElements, const char *strSource, size_t count);
typedef int(__cdecl *_STRNICMP)(const char *string1, const char *string2, size_t count);
typedef double(__cdecl *STRTOD)(const char *nptr, char **endptr);
typedef int(__cdecl *SWPRINTF_S)(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...);

/* T */
typedef time_t(__cdecl *TIME)(time_t *timer);

/* V */
typedef int(__cdecl *_VSCPRINTF)(const char *format, va_list argptr);
typedef int(__cdecl *VSNPRINTF)(char *buffer, size_t count, const char *format, va_list argptr);
typedef int(__cdecl *VSPRINTF)(char *buffer, const char *format, va_list argptr);

/* W */
typedef errno_t(__cdecl *WCSCAT_S)(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource);
typedef errno_t(__cdecl *WCSCPY_S)(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource);
typedef size_t(__cdecl *WCSLEN)(const wchar_t *str);
typedef int(__cdecl *_WRITE)(int fd, const void *buffer, unsigned int count);
typedef int(__cdecl *_WTOI)(const wchar_t *str);

typedef struct _VTABLE_MSVCRT
{
	/* B */
	_BEGINTHREADEX fp_beginthreadex;
	
	/* C */
	_CLOSE fp_close;

	/* I */
	ISDIGIT fp_isdigit;
	ISSPACE fp_isspace;
	_ITOA_S fp_itoa_s;
	_ITOW_S fp_itow_s;

	/* M */
	MEMCMP fpmemcmp;
	MEMCPY	 fp_memcpy;
	MEMCPY_S fp_memcpy_s;
	MEMSET fpmemset;

	/* O */
	_OPEN fp_open;

	/* R */
	RAND fp_rand;
	READ fp_read;

	/* S */
	_SNPRINTF_S fp__snprintf_s;
	_SNPRINTF   fp_snprintf;
	SRAND		fp_srand;
	STRCMP		fp_strcmp;
	STRDUP		fp_strdup;
	STRLEN		fp_strlen;
	STRRCHR		fp_strrchr;
	SSCANF		fp_sscanf;
	SSCANF_S	fp_sscanf_s;
	STRCAT_S	fp_strcat_s;
	STRCHR		fp_strchr;
	STRNCMP     fp_strncmp;
	STRNCPY_S   fp_strncpy_s;
	_STRNICMP   fp_strnicmp;
	STRTOD		fp_strtod;
	SWPRINTF_S	fp_swprintf_s;

	/* T */
	TIME	fp_time;

	/* V */
	_VSCPRINTF fp_vscprintf;
	VSNPRINTF fp_vsnprintf;
	VSPRINTF fp_vsprintf;

	/* W */
	WCSCAT_S fpwcscat_s;
	WCSCPY_S fpwcscpy_s;
	WCSLEN fpwcslen;
	_WRITE fp_write;
	_WTOI fp_wtoi;

	
} VTABLE_MSVCRT, *PVTABLE_MSVCRT;