without using a driver is it possible to do low level input/output to ports(Primarly 0x378) under windows xp?
Thanks in advance!
Winter,
I use WinIO from http://www.internals.com/ . I don't think it's using a driver (although it has that option) because it gives direct access to the I/O space which you can use with IN and OUT asm instructions.
Paul.
dioxin,
Thanks, I didn't test yet I'm trying to learn how it works.
Is there any reason that motivated such a restriction?
Thanks in advance!
WinIO does use a device driver.
QuoteIt bypasses Windows protection mechanisms by using a combination of a kernel-mode device driver and several low-level programming techniques.
Paul
Paul,
WinIO allows 2 methods for accesssing the I/O space once it is installed.
you can use
GetPortVal(201, joy,1)
which would call a device driver and read the port value from I/O location 201 into location joy
Or
you can use direct I/O access using IN and OUT
mov dx,201
in al,dx
mov joy,ax
The first way uses a device driver which is slow and not compatible with software written the "usual" way.
The second method, although stuff has to be installed and setup, I don't think is classed as using a device driver because the application gets direct access to the I/O. This is done by WinIO removing the permission restrictions on I/O access.
Paul.
Is there anyway to change settings in windows XP (Doesn't have to be programaticly) so that my program may atleast access port 0x378?
Thanks in advance!
No. Officially, the device driver is the only way on NT-derived systems to directly access hardware.
The device driver provides centralized control over a device. The device driver can be set up so that one program does not cancel the desired effects of another program, if they are sharing the device. Because of the one-code-for-access-to-all-device-functions capability, the file/device opening function CreateFile can also enforce that, at most, one program, at any given time, is granted access to the hardware.
Lets say I have a joystick(2 buttons) that sets 2 pins on port 0x378 to 1, 0 respectufully to if the button is up, or down. Where should I start for developing this driver?
Thanks in advance!
Winter,
use WinIO from http://www.internals.com/ . It'll do what you need.
Paul.
ok
Heres what I have
SC_HANDLE hSCManager;
SC_HANDLE hService;
SC_HANDLE hs;
HANDLE hDriver;
// adds " around path of exe
char *f;
f = new char[512];
memset(f, 0, 512);
f[0] = '\"';
f[strlen(argv[0])] = '\"';
strcpy(&f[1], argv[0]);
f[strlen(argv[0])+1] = '\"';
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(hSCManager == NULL)
{
cout << "Manager failed" << flush;
freeze(); // Goes into an infite loop for console not to close
}
hService = CreateService(hSCManager,
"WINIO1",
"WINIO1",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
(1 == true) ? SERVICE_DEMAND_START : SERVICE_SYSTEM_START,
SERVICE_ERROR_NORMAL,
TEXT("C:\\ab.sys"),
NULL,
NULL,
NULL,
NULL,
NULL);
if(hService == NULL)
{
cout << "Service failed\n";
cout << flush;
hs = OpenService(hSCManager, "WINIO1", SERVICE_ALL_ACCESS);
if(hs != NULL)
DeleteService(hs);
freeze();
}
hs = OpenService(hSCManager, "WINIO1", SERVICE_ALL_ACCESS);
if(hs == NULL)
{
cout << "failed to open service\n" << flush;
freeze();
}
if(StartService(hs, 0, NULL)==0) // This fails
{
cout << "start failed\n" << flush;
if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)
cout << "already running\n" << flush;
freeze();
}
hDriver = CreateFile("\\\\.\\WINIO1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hDriver==INVALID_HANDLE_VALUE)
{
cout << "opened failed\n" << flush;;
//freeze();
}
__asm{
mov dx, 0x378
mov al, 2
out dx, al
}
DeleteService(hs);
CloseServiceHandle(hs);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
Why does StartService fail.
Thanks in advance!
winter,
You could start at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_resources.asp
You can use:
CreateFile - to open a serial or parallel port
ReadFile - to read from that port
WriteFile - to write to that port
This works in all Window versions without any drivers or "tricks"
hth
farrier
http://projects.pointofnoreturn.org/ledmeter/
Quote from: farrier on January 16, 2005, 04:19:15 AM
You can use:
CreateFile - to open a serial or parallel port
ReadFile - to read from that port
WriteFile - to write to that port
These functions actually use device drivers to perform their functions. The drivers just happen to be included with Windows. They might have too much latency.
Too much latency for serial comminications? Hard to believe! I must admit that I've only used these functions up to 115,200 bps, but have never noticed any latency problems. But it might depend on the application in question.
Quote from: tenkey on January 17, 2005, 01:26:36 AM
These functions actually use device drivers to perform their functions. The drivers just happen to be included with Windows
I was referring to something a programmer/user would have to add to their Windows installation/application.
farrier
For data communications, latency is usually not a problem.
However, when controlling or sampling electronics, you sometimes need a guaranteed response time. And that response time might be very short. When this requirement is too hard to meet, you increase the intelligence of the device, so that it relies less on the PC for timed control.
Take a look in the nohaven reply to this thread:
http://board.win32asmcommunity.net/viewtopic.php?p=153900#153900
Maybe the function NtSetInformationProcess is the answer to your question
to access I/O ports without a driver.
Regards,
Opcode
Hi
I played around with comms a lot in XP last year, and have pretty good success at 19.2K, using standard Windows drivers. Originally got the IO permissions map scheme to work OK, but then MS issued a security fix midway thru year, which wiped it. So had to do it the proper way. If you still want I can give details. There is support for watching the handshake lines etc.
Howard
Quote from: Howard on January 26, 2005, 12:26:52 AM
Hi
I played around with comms a lot in XP last year, and have pretty good success at 19.2K, using standard Windows drivers. Originally got the IO permissions map scheme to work OK, but then MS issued a security fix midway thru year, which wiped it. So had to do it the proper way. If you still want I can give details. There is support for watching the handshake lines etc.
Howard
Yes! Can you post it?
Scott
Hi Scott
As farrier has earlier mentioned, this method is based on Createfile,ReadFile & Writefile.
Refer MSDN - Excellent, though a little confusing, Technical Article entitled "Serial Communications in Win32"
and documentaion on CreateFile, SetUpComm, SetCommState, SetCommTimeouts, WriteFile & ReadFile.
I found the Timeouts (for retries) to be the critical area. It seems that because Windows is Pre-emptive Multi, it can
occasionally miss a received chtr or 2 in a good sized block (often up to 7 or 8 in a 6000h length block), and then will
of course just sit there waiting for the missed chtrs to turn up (since a fixed length RX). My selection works well for
my app. under Win98, XP Home, & XP Prof on a range of different speed machines.
;This code was built using Ramon's EasyCode
.Data?
EBuff DB 128 Dup(?)
.Data
ComPort DB 16 Dup(0)
hPS DD 0
cto COMMTIMEOUTS <>
sDCB DCB <>
;brBits BITRECORD <1, 0, 0, 1, DTR_CONTROL_ENABLE, 0, 1, 0, 0, 0, 0, \
; RTS_CONTROL_ENABLE, 0, 0>
brBits DD 1099H ;since structure above doesn't work
.Code
;I use a dialog box to select the comm port
dlgConfigureProcedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_DLGCONFIGURE_PORTSELECT
Mov hPS, Eax
fn SendMessage, hPS, CB_ADDSTRING, 0, "COM1"
fn SendMessage, hPS, CB_ADDSTRING, 0, "COM2"
fn SendMessage, hPS, CB_ADDSTRING, 0, "COM3"
fn SendMessage, hPS, CB_ADDSTRING, 0, "COM4"
.ElseIf uMsg == WM_CLOSE
Invoke SendMessage, hPS, WM_GETTEXT, 16, Addr ComPort
.If Eax > 0
Invoke CreateFile, Addr ComPort, GENERIC_READ Or GENERIC_WRITE, \
0, NULL, OPEN_EXISTING, 0, NULL
.If Eax == INVALID_HANDLE_VALUE
Jmp OpenError
.EndIf
Mov hCom, Eax
Invoke SetupComm, hCom, 6010H, 6010H ;Setup Comms buffers - I TX/RX chunks 6000h long in my app.
Mov sDCB.DCBlength, SizeOf sDCB
Mov sDCB.BaudRate, CBR_19200
Mov Eax, brBits
Mov sDCB.fbits, Eax
Mov sDCB.ByteSize, 8
Mov sDCB.Parity, NOPARITY
Mov sDCB.StopBits, ONESTOPBIT
Invoke SetCommState, hCom, Addr sDCB
.If !Eax
Jmp DCBError
.EndIf
Mov cto.ReadIntervalTimeout, 10000
Mov cto.ReadTotalTimeoutMultiplier, 1
Mov cto.ReadTotalTimeoutConstant, 2000
Mov cto.WriteTotalTimeoutMultiplier, 10
Mov cto.WriteTotalTimeoutConstant, 10000
Invoke SetCommTimeouts, hCom, Addr cto
.If !Eax
Jmp DCBError
.EndIf
Jmp CloseOut
.Else
Jmp CloseOut
.EndIf
OpenError:
fn MessageBox, NULL, "Comms Port Not Available", "Open Comms Port",
MB_OK Or MB_ICONWARNING ;Normally means another app. has grabbed it.
Jmp CloseOut
DCBError:
Invoke GetLastError
mov ecx,eax
invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,NULL,ecx,0,ADDR EBuff,128,NULL
fn MessageBox, NULL, Addr EBuff, "Open Comms Port", MB_OK Or MB_ICONWARNING
CloseOut:
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.Endif
Return FALSE
dlgConfigureProcedure EndP
;***********************
;SENDING MODULE snippets
;***********************
.Const
ACK Equ 06
NAK Equ 15H
.Data?
.Data
hCom DD 0 ;Port handle
HBuff DB 8 Dup(0)
BCount DD 0
Buffer DB 260 Dup(0)
hCount DD 0 ;Static Count Box in Fetch or Send
Buff5 DB 12 Dup(0)
FCommand DB 0F5H, 0FBH, 0F0H
.Code
SndCommand Proc lpCommand:DWord
;BOOL WriteFile(
; HANDLE hFile, // handle to file
; LPCVOID lpBuffer, // data buffer
; DWORD nNumberOfBytesToWrite, // number of bytes to write
; LPDWORD lpNumberOfBytesWritten, // number of bytes written
; LPOVERLAPPED lpOverlapped // overlapped buffer (- I haven't tried Overlapped)
Invoke WriteFile, hCom, lpCommand, 3, Addr BCount, NULL
.If !Eax
Call Err1
Return FALSE
.ElseIf BCount != 3
Call Err2
Return FALSE
.EndIf
;My app. expects an immediate reflection of the command
Invoke ReadFile, hCom, Addr Buffer, 3, Addr BCount, NULL
.If !Eax
Call Err1
Return FALSE
.ElseIf BCount != 3
Call Err4
Return FALSE
.EndIf
Lea Esi, Buffer
Mov Edi, lpCommand
Mov Ecx, 3
Repe Cmpsb ;Ensure reflection correct
Jz ReflOK
Call SndNAK
Jmp SndCommand
ReflOK:
Call SndACK
Return Eax
SndCommand EndP
SndNAK:
Mov Al, NAK
Jmp SndSingle
SndACK:
Mov Al, ACK
SndSingle:
Mov [HBuff], Al
Invoke WriteFile, hCom, Addr HBuff, 1, Addr BCount, NULL ;snd C/S
.If !Eax
Jmp Err1
.EndIf
.If !BCount
Jmp Err2
.EndIf
Return TRUE
Err1:
Invoke GetLastError
Mov Ecx, Eax
Invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM, NULL, Ecx, 0, Addr Buffer, 128, NULL
Return FALSE
Err2:
fn MessageBox, NULL, "Send Timeout", "Comms Error", MB_OK Or MB_ICONWARNING
Return FALSE
Err4:
fn MessageBox, NULL, "Receive Timeout:", "Comms Error", MB_OK Or MB_ICONWARNING
Return FALSE
Howard
Howard,
Thanks! I'll look through it later on. :U
Scott