aboutsummaryrefslogtreecommitdiff
path: root/src/winNT_portio.c
blob: f06b997e3b4361d0d8945377bb95a087c95521be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * this is a wrapper for the cor port i/o functions for WinNT/2000/XP.
 * this is to be replaced by some functions that are platform/interface
 * specific to access the data lines.
 * for now, this is only for parport access, but in future there will be a way
 * to plug this on the usb bus.
 * if the interface changes, only this file has to be adopted for the target system
 */
#if defined __WIN32__ && defined Z_WANT_LPT

#include <stdio.h>
#include <windows.h>

int read_parport(int port);
void write_parport(int port, int value);
int open_port(int port);

static BOOL bPrivException = FALSE;

int read_parport(int port)
{
	// byte = _inp((unsigned short)port);
	unsigned char value;
#ifdef _MSC_VER
	__asm mov edx,port
	__asm in al,dx
	__asm mov value,al
#else
    // hmm, i should read some documentation about inline assembler
    post("lpt: cannot read from parport (recompile!)");
        return 0;
#endif
	return (int)value;
}

void write_parport(int port, int invalue)
{
  // _outp((unsigned short)port, value);
  BYTE value = (BYTE)invalue;
#ifdef _MSC_VER
  __asm mov edx,port
  __asm mov al,value
  __asm out dx,al
#else
    // hmm, i should read some documentation about inline assembler
    // and probably about assembler in general...
    post("lpt: cannot write to parport (recompile!)");
    /*
    asm(
        "mov %%edx,%0\n"
        "mov %%al,%1\n"
        "out %%dx,%%al\n"
        :
        : "a"(port),"b"(value)
        );
    */
#endif
}

static LONG WINAPI HandlerExceptionFilter ( EXCEPTION_POINTERS *pExPtrs )
{

	if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)
	{
		pExPtrs->ContextRecord->Eip ++; // Skip the OUT or IN instruction that caused the exception
		bPrivException = TRUE;
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	else
		return EXCEPTION_CONTINUE_SEARCH;
}

static BOOL StartUpIoPorts(UINT PortToAccess, BOOL bShowMessageBox, HWND hParentWnd)
{
	HANDLE hUserPort;

	hUserPort = CreateFile("\\\\.\\UserPort", GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	CloseHandle(hUserPort); // Activate the driver
	Sleep(100); // We must make a process switch

	SetUnhandledExceptionFilter(HandlerExceptionFilter);
	
	bPrivException = FALSE;
	read_parport(PortToAccess);  // Try to access the given port address

	if (bPrivException)
	{
		if (bShowMessageBox)
		{
#if 0
    		MessageBox(hParentWnd,"Privileged instruction exception has occured!\r\n\r\n"
								  "To use this external under Windows NT, 2000 or XP\r\n"
								  "you need to install the driver 'UserPort.sys' and grant\r\n"
								  "access to the ports used by this program.\r\n\r\n"
								  "See the file README for further information!\r\n", NULL, MB_OK);
#endif
		}
		return FALSE;
	}
	return TRUE;
}
	/* check if we are running NT/2k/XP */
static int IsWinNT(void)
{
	OSVERSIONINFO OSVersionInfo;
	OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

	GetVersionEx(&OSVersionInfo);

	return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

	/* open parport */
int open_port(int port)
{
	if(IsWinNT())	/* we are under NT and need kernel driver */
	{
		if(StartUpIoPorts(port, 1, 0))
			return(0);
		return(-1);
	}
	else	/* no need to use kernel driver */
	{
		return(0);
	}
}
#endif /* __WIN32__ & Z_WANT_LPT */