The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: winter on January 15, 2005, 01:11:31 AM

Title: port i/o under winxp
Post by: winter on January 15, 2005, 01:11:31 AM
without using a driver is it possible to do low level input/output to ports(Primarly 0x378) under windows xp?

Thanks in advance!
Title: Re: port i/o under winxp
Post by: dioxin on January 15, 2005, 01:16:36 AM
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.
Title: Re: port i/o under winxp
Post by: winter on January 15, 2005, 01:47:25 AM
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!
Title: Re: port i/o under winxp
Post by: pbrennick on January 15, 2005, 01:49:32 AM
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
Title: Re: port i/o under winxp
Post by: dioxin on January 15, 2005, 11:06:05 AM
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.
Title: Re: port i/o under winxp
Post by: winter on January 15, 2005, 08:34:52 PM
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!
Title: Re: port i/o under winxp
Post by: tenkey on January 15, 2005, 10:43:16 PM
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.
Title: Re: port i/o under winxp
Post by: winter on January 16, 2005, 12:18:52 AM
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!
Title: Re: port i/o under winxp
Post by: dioxin on January 16, 2005, 12:23:09 AM
Winter,
    use WinIO from http://www.internals.com/ . It'll do what you need.


Paul.
Title: Re: port i/o under winxp
Post by: winter on January 16, 2005, 01:34:03 AM
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!
Title: Re: port i/o under winxp
Post by: farrier on January 16, 2005, 04:19:15 AM
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
Title: Re: port i/o under winxp
Post by: Kestrel on January 16, 2005, 06:40:39 AM
http://projects.pointofnoreturn.org/ledmeter/
Title: Re: port i/o under winxp
Post by: tenkey on January 17, 2005, 01:26:36 AM
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.
Title: Re: port i/o under winxp
Post by: farrier on January 17, 2005, 02:58:15 AM
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
Title: Re: port i/o under winxp
Post by: tenkey on January 17, 2005, 03:21:54 AM
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.
Title: Re: port i/o under winxp
Post by: Opcode on January 17, 2005, 04:03:51 AM
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
Title: Re: port i/o under winxp
Post by: 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
Title: Re: port i/o under winxp
Post by: sbrown on January 26, 2005, 05:01:56 PM
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
Title: Re: port i/o under winxp
Post by: Howard on January 27, 2005, 05:04:00 AM
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
Title: Re: port i/o under winxp
Post by: sbrown on February 08, 2005, 04:51:23 PM
Howard,

Thanks! I'll look through it later on. :U


Scott