text: #include "OISConfig.h"
  #ifdef OIS_WIN32_WIIMOTE_SUPPORT
  //cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
  //This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
  //This was based in part on Alan Macek <www.alanmacek.com>'s USB interface library
  
  //Edited for Toshiba Stack support (hopefully also all others) by 
  //Sean Stellingwerff (http://sean.stellingwerff.com) using information
  //gathered from http://www.lvr.com/hidpage.htm (Thanks a million! :D) 
  
  //#include "stdafx.h"
  #include "hiddevice.h"
  
  extern "C" 
  {
  	#include "hidsdi.h"
  	#include <Setupapi.h>
  }
  #pragma comment(lib, "setupapi.lib")
  #pragma comment(lib, "hid.lib")
  
  HIDP_CAPS							Capabilities;
  PSP_DEVICE_INTERFACE_DETAIL_DATA	detailData;
  
  cHIDDevice::cHIDDevice() : mConnected(false), mHandle(NULL), mEvent(NULL)
  {
  }
  
  
  cHIDDevice::~cHIDDevice()
  {
  	if (mConnected)
  	{
  		Disconnect();
  	}
  }
  
  bool cHIDDevice::Disconnect()
  {
  	bool retval = false;
  	if (mConnected)
  	{
  		retval = (CloseHandle(mHandle) == TRUE && CloseHandle(mEvent) == TRUE);
  	
  		mConnected = false;
  	}
  
  	return retval;
  }
  
  bool cHIDDevice::Connect(unsigned short device_id, unsigned short vendor_id, int index)
  {
  	if (mConnected)
  	{
  		if (!Disconnect())
  		{
  			return false;
  		}
  	}
  
  	// Find the wiimote(s)
  	//for (int i = 0; i <= index; i++)
  	OpenDevice( device_id, vendor_id, index );
  
  	return mConnected;
  }
  
  bool cHIDDevice::OpenDevice(unsigned short device_id, unsigned short vendor_id, int index)
  {
  	//Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
  	HIDD_ATTRIBUTES						Attributes;
  	SP_DEVICE_INTERFACE_DATA			devInfoData;
  	bool								LastDevice = FALSE;
  	bool								MyDeviceDetected = FALSE; 
  	int									MemberIndex = 0;
  	int									MembersFound = 0;
  	GUID								HidGuid;
  	ULONG								Length;
  	LONG								Result;
  	HANDLE								hDevInfo;
  	ULONG								Required;
  
  	Length = 0;
  	detailData = NULL;
  	mHandle=NULL;
  
  	HidD_GetHidGuid(&HidGuid);	
  	hDevInfo=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
  		
  	devInfoData.cbSize = sizeof(devInfoData);
  
  	MemberIndex = 0;
  	MembersFound = 0;
  	LastDevice = FALSE;
  
  	do
  	{
  		Result=SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
  		if (Result != 0)
  		{
  			Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
  
  			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
  			detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  			Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL);
  
  			mHandle=CreateFile(detailData->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
  			Attributes.Size = sizeof(Attributes);
  
  			Result = HidD_GetAttributes(mHandle, &Attributes);
  			//Is it the desired device?
  
  			MyDeviceDetected = FALSE;
  
  			if (Attributes.VendorID == vendor_id)
  			{
  				if (Attributes.ProductID == device_id)
  				{
  					if (MembersFound == index)
  					{
  						//Both the Vendor ID and Product ID match.
  						//printf("Wiimote found!\n");
  						mConnected = true;
  						GetCapabilities();
  
  						WriteHandle=CreateFile(detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
  						MyDeviceDetected = TRUE;
  
  						PrepareForOverlappedTransfer();
  
  						mEvent = CreateEvent(NULL, TRUE, TRUE, "");
  						mOverlapped.Offset = 0;
  						mOverlapped.OffsetHigh = 0;
  						mOverlapped.hEvent = mEvent;
  					
  					} else { 
  						//The Product ID doesn't match.
  						CloseHandle(mHandle);
  					}
  
  					MembersFound++;
  				}
  			} else {
  				CloseHandle(mHandle);
  			}
  			free(detailData);
  		} else {
  			LastDevice=TRUE;
  		}
  		MemberIndex = MemberIndex + 1;
  	} while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
  
  	SetupDiDestroyDeviceInfoList(hDevInfo);
  	return MyDeviceDetected;
  }
  
  bool cHIDDevice::WriteToDevice(unsigned const char * OutputReport, int num_bytes)
  {
  	bool retval = false;
  	if (mConnected)
  	{
  		DWORD bytes_written;
  		retval = (WriteFile( WriteHandle, OutputReport, num_bytes, &bytes_written, &mOverlapped) == TRUE); 
  		retval = retval && bytes_written == num_bytes;
  	}
  	return retval;
  }
  
  void cHIDDevice::PrepareForOverlappedTransfer()
  {
  	//Get a handle to the device for the overlapped ReadFiles.
  	ReadHandle=CreateFile(detailData->DevicePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  }
  
  void cHIDDevice::GetCapabilities()
  {
  	//Get the Capabilities structure for the device.
  	PHIDP_PREPARSED_DATA PreparsedData;
  	HidD_GetPreparsedData(mHandle, &PreparsedData);
  	HidP_GetCaps(PreparsedData, &Capabilities);
  
  	//No need for PreparsedData any more, so free the memory it's using.
  	HidD_FreePreparsedData(PreparsedData);
  }
  
  bool cHIDDevice::ReadFromDevice(unsigned const char * buffer, int max_bytes, int & bytes_read, int timeout)
  {
  	bool retval = false;
  	if (mConnected)
  	{
  		ReadFile( ReadHandle, (LPVOID)buffer,max_bytes,(LPDWORD)&bytes_read,(LPOVERLAPPED) &mOverlapped); 
  		DWORD Result = WaitForSingleObject(mEvent, timeout);
  		if (Result == WAIT_OBJECT_0) 
  		{		
  			retval = true;
  		}
  		else 
  		{
  			CancelIo(mHandle);			
  		}
  		ResetEvent(mEvent);
  	}
  	return retval;
  }
  #endif
  