#include "windows.h"

#define DLL_DECL _declspec(dllexport)
#define DLL_CALL_TYPE DLL_DECL BOOL _cdecl 

extern HANDLE g_hDriver;

BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD dwReason, PVOID lpvReserved)
{
	switch (dwReason)
	{ 
        case DLL_PROCESS_ATTACH: 
		{
			if(g_hDriver == NULL || g_hDriver == INVALID_HANDLE_VALUE)
			{
				/*
				REMEMBER: Close the handle when leaving the DLL.
				*/
				g_hDriver = CreateFile(TEXT("\\\\.\\3SRTE"),
														 GENERIC_READ | GENERIC_WRITE,
													0,
													NULL,
													OPEN_EXISTING,
													FILE_ATTRIBUTE_NORMAL,
													NULL);
			}
			break; 
		}
        case DLL_PROCESS_DETACH:
		{
			if(g_hDriver != NULL && g_hDriver != INVALID_HANDLE_VALUE)
				CloseHandle(g_hDriver);
			break;
        }
		case DLL_THREAD_ATTACH: 
		{
			break;
        }
        case DLL_THREAD_DETACH: 
		{
			break;
        }
 		default: 
			break; 
	} 
 
    return TRUE; 
} 

//All the functions that are called through the Asynch-call-interface must look the same:
// BOOL <FunctionName>(char* pInput, int nSizeIn, char* pOutput, int nSizeOut);
#if __cplusplus
extern "C" {
#endif
DLL_CALL_TYPE TestFunction1(char* pInput, int nSizeIn, char* pOutput, int nSizeOut)
{
    //in/out buffers contain structures/data specific for this functioncall.
    //So just cast the pointers, but remember to specify pack(1) for structures defined in IEC.
    int i, iMax;
    
    iMax = min(nSizeIn,nSizeOut);

    for(i = 0; i < iMax - 1; i++)
    {
        pOutput[i] = pInput[i];
    }
    pOutput[i] = '\0';

    return TRUE; 
}

DLL_CALL_TYPE TestFunction2(char* pInput, int nSizeIn, char* pOutput, int nSizeOut)
{
    //in/out buffers contain structures/data specific for this functioncall.
    //So just cast the pointers, but remember to specify pack(1) for structures defined in IEC.
    int i, iMax;
    
    iMax = min(nSizeIn,nSizeOut);

    for(i = 0; i < iMax - 1; i++)
    {
        pOutput[i] = pInput[i];
    }
    pOutput[i] = '\0';

    return TRUE; 
}

DLL_CALL_TYPE TestFunction3(char* pInput, int nSizeIn, char* pOutput, int nSizeOut)
{
    //in/out buffers contain structures/data specific for this functioncall.
    //So just cast the pointers, but remember to specify pack(1) for structures defined in IEC.
    int i, iMax;
    char* p =NULL;
    
    iMax = min(nSizeIn,nSizeOut);

    for(i = 0; i < iMax - 1; i++)
    {
        pOutput[i] = pInput[i];
    }
    pOutput[i] = '\0';

    *pInput = *p; //Exceptiontest
    
    return TRUE; 
}

DLL_CALL_TYPE TestFunction4(char* pInput, int nSizeIn, char* pOutput, int nSizeOut)
{
    //in/out buffers contain structures/data specific for this functioncall.
    //So just cast the pointers, but remember to specify pack(1) for structures defined in IEC.
    int i, iMax;
    
    iMax = min(nSizeIn,nSizeOut);

    for(i = 0; i < iMax - 1; i++)
    {
        pOutput[i] = pInput[i];
    }
    pOutput[i] = '\0';

    while(1)
        _asm nop; //Timeouttest.
    
    return TRUE; 
}

#if __cplusplus
}
#endif
