All commands, instructions and data transfer to and from the PortIO95 VxD are done through the Windows95 32 bit DeviceIoControl() call. This call is the standard way a 32 bit application works with a 32 bit VxD. The DeviceIoControl() call is a Windows 95 convention and is not specific to the PortIO95 VxD. This means that any 32 bit compiler which can operate under Windows 95 should be able to call the PortIO95 VxD.
The documentation of the function calls in the Reference Section shows C calling examples. The compiler used to test these code fragments was Microsoft Visual C++ V4.0. If you are using a different C compiler, the calls should be much the same. If you are using another language you will need look up the DeviceIoControl() call in your software's help menu (it is sure to be there) in order to convert the calls. Here is the function prototype for the Visual C++ 4.0 DeviceIoControl() call;
BOOL DeviceIoControl( HANDLE hDevice, // handle to device of interest DWORD dwIoControlCode, // control code of operation to perform LPVOID lpInBuffer, // ptr to buffer to supply input data DWORD nInBufferSize, // size of input buffer LPVOID lpOutBuffer, // ptr to buffer to receive output data DWORD nOutBufferSize, // size of output buffer LPDWORD lpBytesReturned, // ptr to var to get output byte count LPOVERLAPPED lpOverlapped // ptr to overlapped struc for asynch op );
The PortIO95 VxD needs an hDevice and dwIoControlCode parameter on every call. The hDevice parameter is obtained after the VxD is loaded (see the previous section in this chapter entitled Loading the PortIO95 VxD) the dwControlCode parameter is specified by the application. Depending on the dwIoControlCode either the lpInBuffer or the lpOutBuffer parameters (and associated size fields) may be required. PortIO95 never uses the lpBytesReturned or the lpOverlapped fields. The In and Out part of the names in the above function prototype are always viewed from the VxD perspective. Thus lpInBuffer supplies data IN to the VxD and OUT from the application. Similarly, if the application needs to receive data from the PortIO95 VxD (perhaps by reading a byte) the lpOutBuffer and nOutBufferSize fields are used and must be supplied.
Note that the DeviceIoControl() call returns a boolean value (i.e. true or false). In this case a return value of 0 means fail and non-zero means success. Typically the actual return value is meaningless - even on success. If an error occurs, further information has to be determined by a second call to the Windows 95 function GetLastError(). See the Error Section for a list of all PortIO95 VxD error return codes.
The dwIoControlCode parameter supplied on the DeviceIoControl() call determines the action that the PortIO95 VxD will take when it receives the call. The dwIoControlCode parameter is a hexadecimal number defined by the PortIO95 VxD. Rather than require the programmer to enter numbers like 0x100C these values are given names like PORTIO_SEND_BYTE_TO_PINS2_TO_9 which is a lot simpler and a lot more self explanatory. The file that performs this mapping (for C programs) is called portio95.h and can be found in the C source directory.
Specific dwIoControlCode parameters may require certain of the other DeviceIoControl() parameters to be supplied. Typically these parameters are used to transfer information in (i.e. a byte to write) or out (i.e. a byte that has been read) of the VxD. Further information on each control code can be found in the Control Code Reference Section in this document.