Port access under Windows 9x is possible as long as you refrain from accessing trapped ports. Several VxDs hook I/O ports to virtualize hardware and will block any attempt to modify these ports from a Windows application. If you wish to control a piece of hardware which is mapped to free addresses such as 300h, you can use the inp/outp functions with no fear. However, any attempt to access system ports (such as those reserved for the DMA chip, HD controller, etc.) will be to no avail. To control such ports from your application, you'll need to use the WinIo library which executes in ring 0 and bypasses Windows port trapping mechanism.
Under Windows NT/2000, user mode applications are completely prohibited from accessing I/O ports. Any attempt to access an I/O port from a ring 3 application is terminated with a protection fault. Thus, the only way to overcome this limitation is by using a kernel-mode device driver, such as the one supplied with the WinIo library.Q. I'm having difficulties using the WinIo library with C++ Builder.
The problem is revealed during the link phase and is related to the fact that Microsoft and Borland use different file formats (COFF/OMF) for storing object files (including LIBs). This means that you cannot add the LIB files supplied with WinIo to your project and get things to work properly. The solution is to avoid the LIB files by using the LoadLibrary/GetProcAddress APIs to load and execute the functions within WinIo.dll.