IOW SDK has IOWarrior wrapper class to simplify working with IO-Warrior.


--------------------------------------------------------------------------------
IOWarrior class functions.

BOOLEAN IOWarrior::SetLegacyOpenMode(ULONG openMode)
Set legacy open mode.

This function sets legacy IO-Warrior devices open mode.
openMode specifies which open mode to use.
IOW_OPEN_SIMPLE - open simple endpoints only.
IOW_OPEN_COMPLEX - open complex endpoints only.
SetLegacyOpenMode() returns TRUE if given open mode can be set
and FALSE otherwise.
By default IOW SDK opens only simple endpoints, so if you want to open complex
endpoints, you should call SetLegacyOpenMode(IOW_OPEN_COMPLEX) before
calling Open().
Note that because SDK opens only one endpoint for each device, there will
always be 1 endpipe for each device, thus you should use 0 as numPipe in calls
to IowKitRead/Write() functions.
Legacy open mode doesn't affect new IO-Warrior chips which have serial number
support, IOW SDK opens all endpoints for new IOWs.


--------------------------------------------------------------------------------
BOOLEAN IOWarrior::Open(void)
Enumerate and open IO-Warrior devices.

This function opens IO-Warrior devices.
It returns TRUE on success and FALSE otherwise.


--------------------------------------------------------------------------------
void IOWarrior::Close(void)
Close IO-Warrior devices.

This functions closes IO-Warrior devices.
Use this function only for the main IOWarrior device, it will do nothing for
child devices.


--------------------------------------------------------------------------------
void IOWarrior::SetHandle(IOWKIT_HANDLE devHandle)
Set new IO-Warrior handle.

This functions saves new handle in internal IOWarrior class variable.
All subsequent Read()/Write()s will work with new IOWarrior handle.


--------------------------------------------------------------------------------
USHORT IOWarrior::GetProductId(void)
Get product ID.

This functions returns IO-Warrior product ID or zero in case of error.
Currently there are 2 IO-Warrior product IDs - 0x1500 (IOW40)
and 0x1501 (IOW24).
You can use this function to determine what kind of IO-Warrior you're using.


--------------------------------------------------------------------------------
BOOLEAN IOWarrior::GetSerialNumber(PWCHAR buffer)
Get serial number.

This function returns serial number string or empty string if IO-Warrior doesn't
have serial number. It returns TRUE on success and FALSE otherwise.
Serial number is 8 characters string, so buffer must point to WCHAR[9] array.
Useful for distinguishing between many IO-Warrior devices with different
hardware attached.


--------------------------------------------------------------------------------
ULONG IOWarrior::Read(ULONG numPipe, PCHAR buffer, ULONG nbytes)
Read data from IO-Warrior.

This function reads length bytes from IO-Warrior and returns the number of bytes
read if successful.
Note that you must specify the number of the interface (see IO-Warrior specs)
to read from.

It returns number of bytes read, so you should always check if it reads correct 
number of bytes, you can use GetLastError() to get error details.

ATTENTION!
Note that this function blocks the current thread until something changes on
IO-Warrior (i.e. until user presses a button connected to an input pin,
or until IIC data arrives), so if you don't want your program to be blocked
you should use a separate thread for reading from IO-Warrior.
If you don't want a blocking read use ReadImmediate (see next).


--------------------------------------------------------------------------------
BOOLEAN IOWarrior::ReadImmediate(PDWORD buffer)
Return last value read from IO-Warrior.

This function returns the last value read from interface zero.
It returns TRUE if something has been read from interface zero, or
FALSE if nothing was read from interface zero.

There is no non-blocking read for interface 1 (Special Mode Functions).


--------------------------------------------------------------------------------
ULONG IOWarrior::Write(ULONG numPipe, PCHAR buffer, ULONG nbytes)
Write data to IO-Warrior.

This function writes length bytes value to IO-Warrior.
Note that you must specify number of the interface (see IO-Warrior specs)
to write to.

It returns the number of bytes written, so you should always check if it writes
the correct number of bytes, Use GetLastError() to get error information in case
of an error.

Writing to IO-Warrior is used to set up its pins for input/output and to do
other stuff.

Sample writing to interface zero:
DWORD value consists of 32 bits, which correspond to 32 IO-Warrior pins
and each bit has the following meaning:
To use a pin as an input, set it to 1.
To use a pin as an output, set it to 0.
For example, writing 0 (all 32 bits are zero) to IO-Warrior
sets all pins as outputs driving low (so if you have LEDs connected to
them they will be on).

Writing 0xfffffffful (value in hex, all 32 bits set) sets all pins as inputs.
Note that if you want to use a pin as an input, you must first set it up as
input, in other words, you must write a 1 to it.


--------------------------------------------------------------------------------
BOOLEAN IOWarrior::WriteSimple(DWORD value)
Write DWORD value to interface zero (simple endpoint).

This functions writes DWORD value (32 bits) to simple endpoint.
Note it works for both IOW40 and IOW24 (it truncates high bits for IOW24).


--------------------------------------------------------------------------------
BOOLEAN IOWarrior::SetTimeout(ULONG timeout)
Set I/O timeout (in milliseconds).

This function sets read I/O timeout value for IO-Warrior.

USB bus can lose USB (HID?) device reports, when used in some hardware
configurations (for example, where there is some data generating
USB device plugged in the same HUB with IO-Warrior).

When applications doesn't get expected report (for example, reply to
IO-Warrior I2C transaction) it blocks until report is received.
Since report has already been lost, this will make app stuck and wait forever.
If you experience such problems you can use SetTimeout() function to handle
"lost reports" problem.

When you set timeout to non-zero value, IowKitRead() will timeout if it
didn't read anything in specified period of time.
If IowKitRead() times out, you have to restart any pending transaction
(for example, I2C write or read transaction) from the beginning.

It's recommended to use 1 second (1000) or bigger timeout values.


--------------------------------------------------------------------------------
Using the wrapper class.

Simply include iowclass.h to use IOWarrior class in your program.

Here is little sample:
// Sample class wrapper program
#include "stdafx.h"
// IOWarrior wrapper class include
#include "iowclass.h"

int main(int argc, char **argv)
{
	// IO-Warrior device
	IOWarrior iow;
	// Serial number string
	WCHAR sn[9];

	// Open IOW
	if (!iow.Open()) {
		printf("open failed\n");
		goto out;
	}
	// OK, we opened IOW, now get some info and write something
	iow.GetSerialNumber(sn);
	printf("IO-Warrior PID %x, S/N \"%ws\"\n", iow.GetProductId(),
		&sn);
	iow.WriteSimple(0);
out:

	return 0;
}

See ioblink sources for more detailed sample of using IOWarrior class.
