예제 #1
1
파일: client.c 프로젝트: ndubey/vmulti
BOOLEAN
CheckIfOurDevice(
    HANDLE file,
    USAGE myUsagePage,
    USAGE myUsage)
{
    PHIDP_PREPARSED_DATA Ppd = NULL; // The opaque parser info describing this device
    HIDD_ATTRIBUTES                 Attributes; // The Attributes of this hid device.
    HIDP_CAPS                       Caps; // The Capabilities of this hid device.
    BOOLEAN                         result = FALSE;

    if (!HidD_GetPreparsedData (file, &Ppd))
    {
        printf("Error: HidD_GetPreparsedData failed \n");
        goto cleanup;
    }

    if (!HidD_GetAttributes(file, &Attributes))
    {
        printf("Error: HidD_GetAttributes failed \n");
        goto cleanup;
    }

    if (Attributes.VendorID == VMULTI_VID && Attributes.ProductID == VMULTI_PID)
    {
        if (!HidP_GetCaps (Ppd, &Caps))
        {
            printf("Error: HidP_GetCaps failed \n");
            goto cleanup;
        }

        if ((Caps.UsagePage == myUsagePage) && (Caps.Usage == myUsage))
        {
            printf("Success: Found my device.. \n");
            result = TRUE;
        }
    }

cleanup:

    if (Ppd != NULL)
    {
        HidD_FreePreparsedData (Ppd);
    }

    return result;
}
예제 #2
0
void CUSBDevice::setDetail(TCHAR *path){
	HANDLE temp;
	PHIDP_PREPARSED_DATA PreparsedData;
	delete[] m_pPath;
	m_pPath = new TCHAR[strlen(path) * sizeof(TCHAR) + 1];
	strcpy(m_pPath, path);
	TRACE("received at addr %x %s\r\n", m_pPath, m_pPath);
	temp = CreateFile(m_pPath,
		0,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, 
		OPEN_EXISTING,
		0,
		NULL);
	HidD_GetPreparsedData(temp, &PreparsedData);
	HidP_GetCaps(PreparsedData, &m_Capabilities);
}
예제 #3
0
bool HIDDeviceManager::initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const
{
    bool                 result = false;
    HIDP_CAPS            caps;
    HIDP_PREPARSED_DATA* preparsedData = 0;

    if (!HidD_GetPreparsedData(hidDev, &preparsedData))
        return false;

    if (HidP_GetCaps(preparsedData, &caps) == HIDP_STATUS_SUCCESS)
    {
        desc->Usage                  = caps.Usage;
        desc->UsagePage              = caps.UsagePage;
        result = true;
    }
    HidD_FreePreparsedData(preparsedData);
    return result;
}
예제 #4
0
파일: device.cpp 프로젝트: ousttrue/hidloop
bool Device::open(boost::asio::io_service &io_service, std::shared_ptr<ICallback> callback)
{
    auto handle = CreateFile(m_path.c_str(), GENERIC_READ|GENERIC_WRITE,
            FILE_SHARE_READ,
            NULL, OPEN_EXISTING,
            FILE_FLAG_OVERLAPPED, NULL);
    if(handle == INVALID_HANDLE_VALUE) {
        return false;
    }
    m_handle=std::shared_ptr<void>(handle, &::CloseHandle);

    // get hid caps
    {
        HIDP_PREPARSED_DATA* preparsedData=0;
        if (!HidD_GetPreparsedData(handle, &preparsedData)){
            return false;
        }
        std::shared_ptr<HIDP_PREPARSED_DATA> parsed(
                preparsedData, HidD_FreePreparsedData);

        HIDP_CAPS caps;
        if (HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS)
        {
            return false;
        }
        std::cout << "Usage: " << caps.Usage << std::endl;
        std::cout << "UsagePage: " <<  caps.UsagePage << std::endl;
        std::cout << "InputReportByteLength: " 
            << caps.InputReportByteLength << std::endl;
        std::cout << "OutputReportByteLength: " 
            <<  caps.OutputReportByteLength << std::endl;
        std::cout << "FeatureReportByteLength: "
            <<  caps.FeatureReportByteLength << std::endl;
    }

    // setup stream
    m_stream=std::make_shared<boost::asio::windows::stream_handle>(io_service, handle);
    m_callback=callback;

    beginRead();
    m_callback->onConnect(this);

    return true;
}
예제 #5
0
BOOLEAN SwitchCSR(__in LPTSTR lpDongleName, __in HANDLE hHidDevice, __in BOOL toHID)
{
	PHIDP_PREPARSED_DATA PreparsedData;

	if (!HidD_GetPreparsedData(hHidDevice, &PreparsedData))
	{
		LbtReportFunctionError(TEXT("HidD_GetPreparsedData"));
		return FALSE;
	}

	HIDP_CAPS       HidCaps;

	if (!HidP_GetCaps(PreparsedData, &HidCaps))
	{
		LbtReportFunctionError(TEXT("HidP_GetCaps"));
		HidD_FreePreparsedData(PreparsedData);
		return FALSE;
	}

	if (HidCaps.UsagePage != 0xFF00 || HidCaps.Usage != 0x0001)
	{
//		HidD_FreePreparsedData(PreparsedData);
//		return FALSE;
	}

	if (HidCaps.FeatureReportByteLength != sizeof(ToHCICSRReports))
	{
//		HidD_FreePreparsedData(PreparsedData);
//		return FALSE;
	}

	CHAR ReportBuffer[sizeof(ToHCICSRReports)];
	RtlCopyMemory(ReportBuffer, ToHCICSRReports, sizeof(ToHCICSRReports));
	if (!HidD_SetFeature(hHidDevice, ReportBuffer, HidCaps.FeatureReportByteLength))
	{
		LbtReportFunctionError(TEXT("HidD_SetOutputReport"));
		HidD_FreePreparsedData(PreparsedData);
		return FALSE;
	}

	HidD_FreePreparsedData(PreparsedData);
	LbtReportDongleSwitch(lpDongleName, toHID);
	return TRUE;
}
예제 #6
0
파일: hid_printer.c 프로젝트: zgwmike/TWPS
/**
 * constructor
 */
boca_hid_printer_t *boca_hid_new(const char *device_path) {
    boca_hid_printer_t *self = (boca_hid_printer_t *) calloc(1, sizeof(boca_hid_printer_t));
    if (!self) return NULL;
    self->device_path = strdup(device_path);
#ifdef __WIN32__
    HANDLE handle;
    handle = CreateFile(device_path,
                        0,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);
    if (handle != INVALID_HANDLE_VALUE) {
        PHIDP_PREPARSED_DATA preparsed_data;
        if (HidD_GetPreparsedData(handle, &preparsed_data)) {
            HIDP_CAPS capabilities;
            NTSTATUS ret = HidP_GetCaps(preparsed_data, &capabilities);
            if (ret == HIDP_STATUS_SUCCESS) {
                self->input_length = capabilities.InputReportByteLength;
                self->output_length = capabilities.OutputReportByteLength;
                self->feature_length = capabilities.FeatureReportByteLength;
                zsys_info("hid printer: input length %d output length %d feature length %d", self->input_length,
                          self->output_length, self->feature_length);
            } else {
                zsys_warning("hid printer: can not get hid printer capabilities.");
            }
        } else {
            zsys_warning("hid printer: can not get hid prepared data");
        }
        CloseHandle(handle);
    } else {
        zsys_warning("hid printer: can not open hid device code %d", GetLastError());
    }
#endif
    self->device = hid_open_path(self->device_path);
    if (self->device == NULL) {
        zsys_error("hid printer: could not create device from path %s", device_path);
        boca_hid_destroy(&self);
        return NULL;
    }
    return self;
}
예제 #7
0
int RawInputPad::Open()
{
	PHIDP_PREPARSED_DATA pPreparsedData = NULL;

	//TODO Better place?
	LoadMappings(mapVector);

	memset(&this->ovl, 0, sizeof(OVERLAPPED));
	memset(&this->ovlW, 0, sizeof(OVERLAPPED));

	//this->padState.initStage = 0;
	this->doPassthrough = !!conf.DFPPass;//TODO per player
	this->usbHandle = INVALID_HANDLE_VALUE;
	std::wstring path;
	{
		CONFIGVARIANT var(N_JOYSTICK, CONFIG_TYPE_WCHAR);
		if (LoadSetting(mPort, APINAME, var))
			path = var.wstrValue;
		else
			return 1;
	}

	this->usbHandle = CreateFileW(path.c_str(), GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

	if(this->usbHandle != INVALID_HANDLE_VALUE)
	{
		this->ovl.hEvent = CreateEvent(0, 0, 0, 0);
		this->ovlW.hEvent = CreateEvent(0, 0, 0, 0);

		HidD_GetAttributes(this->usbHandle, &(this->attr));
		HidD_GetPreparsedData(this->usbHandle, &pPreparsedData);
		HidP_GetCaps(pPreparsedData, &(this->caps));
		HidD_FreePreparsedData(pPreparsedData);
		return 0;
	}
	else
		fwprintf(stderr, L"Could not open device '%s'.\nPassthrough and FFB will not work.\n", path.c_str());

	return 1;
}
예제 #8
0
// 获取设备一些能力信息
USBHIDDLL_API void __stdcall USBHIDGetDeviceCapabilities(USBHANDLE handle, PHIDD_ATTRIBUTES attributes, PHIDP_CAPS caps)
{
    if (handle != INVALID_HANDLE_VALUE)
    {
        HidD_GetAttributes(handle, attributes);

        //Get the Capabilities structure for the device.

        PHIDP_PREPARSED_DATA	PreparsedData;

        /*
        API function: HidD_GetPreparsedData
        Returns: a pointer to a buffer containing the information about the device's capabilities.
        Requires: A handle returned by CreateFile.
        There's no need to access the buffer directly,
        but HidP_GetCaps and other API functions require a pointer to the buffer.
        */

        HidD_GetPreparsedData (handle, &PreparsedData);
        //DisplayLastError("HidD_GetPreparsedData: ");

        /*
        API function: HidP_GetCaps
        Learn the device's capabilities.
        For standard devices such as joysticks, you can find out the specific
        capabilities of the device.
        For a custom device, the software will probably know what the device is capable of,
        and the call only verifies the information.
        Requires: the pointer to the buffer returned by HidD_GetPreparsedData.
        Returns: a Capabilities structure containing the information.
        */

        HidP_GetCaps (PreparsedData, caps);

        //No need for PreparsedData any more, so free the memory it's using.
        HidD_FreePreparsedData(PreparsedData);
        //DisplayLastError("HidD_FreePreparsedData: ") ;
    }
}
예제 #9
0
파일: hidasync.c 프로젝트: NoPublic/GIMX
int open_path(const char * path, int print) {

  int device = async_open_path(path, print);
  if(device >= 0) {
    HIDD_ATTRIBUTES attributes = { .Size = sizeof(HIDD_ATTRIBUTES) };
    if(HidD_GetAttributes(devices[device].handle, &attributes) == TRUE) {
        PHIDP_PREPARSED_DATA preparsedData;
        HIDP_CAPS hidCapabilities;
        if(HidD_GetPreparsedData(devices[device].handle, &preparsedData) == TRUE) {
            if(HidP_GetCaps(preparsedData, &hidCapabilities) == HIDP_STATUS_SUCCESS ) {
                devices[device].write.size = hidCapabilities.OutputReportByteLength;
                async_set_read_size(device, hidCapabilities.InputReportByteLength);
                devices[device].hidInfo.vendor_id = attributes.VendorID;
                devices[device].hidInfo.product_id = attributes.ProductID;
                devices[device].hidInfo.bcdDevice = attributes.VersionNumber;
            }
            else {
                ASYNC_PRINT_ERROR("HidP_GetCaps")
                async_close(device);
                device = -1;
            }
            HidD_FreePreparsedData(preparsedData);
        }
        else {
            ASYNC_PRINT_ERROR("HidD_GetPreparsedData")
            async_close(device);
            device = -1;
        }
    }
    else {
        ASYNC_PRINT_ERROR("HidD_GetAttributes")
        async_close(device);
        device = -1;
    }
  }
  return device;
}
예제 #10
0
void parse_info_from_path(hid_event* event, char* device_path) {
	auto write_handle = open_device(device_path, TRUE);

	/* Check validity of write_handle. */
	if (write_handle == INVALID_HANDLE_VALUE) {
		/* Unable to open the device. */
		//register_error(dev, "CreateFile");
		//goto cont_close;
		return;
	}

	//TODO: clean this shit up

	HIDD_ATTRIBUTES attrib;
	attrib.Size = sizeof(HIDD_ATTRIBUTES);

	HidD_GetAttributes(write_handle, &attrib);

	event->device_info->product_id = attrib.ProductID;
	event->device_info->vendor_id = attrib.VendorID;
	event->device_info->release_number = attrib.VersionNumber;

	PHIDP_PREPARSED_DATA pp_data = NULL;
	auto res = HidD_GetPreparsedData(write_handle, &pp_data);
	if (res) {
		HIDP_CAPS caps;
		auto nt_res = HidP_GetCaps(pp_data, &caps);
		if (nt_res == HIDP_STATUS_SUCCESS) {
			event->device_info->usage_page = caps.UsagePage;
			event->device_info->usage = caps.Usage;
		}

		HidD_FreePreparsedData(pp_data);
	}

	CloseHandle(write_handle);
}
예제 #11
0
bool Controller::registerController(int pDeviceId)
{
	
	//Required variables to iterate over the device interface
	DWORD result = 0;
	LPGUID hidguid = (LPGUID)malloc(sizeof(GUID));
	HDEVINFO deviceset;
	PSP_DEVICE_INTERFACE_DATA deviceInterfaceData = nullptr;
	PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceInfo = nullptr;
	DWORD buffersize = 0;
	
	//malloc check
	CHECK_NULL(hidguid, SETUP_ERROR);

	//get hid guid
	HidD_GetHidGuid(hidguid);

	//get device list
	deviceset = SetupDiGetClassDevs(hidguid, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (deviceset == INVALID_HANDLE_VALUE)
	{
		goto SETUP_ERROR;
	}

	int deviceindex = 0;
	deviceInterfaceData = (PSP_DEVICE_INTERFACE_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DATA));
	//malloc check
	CHECK_NULL(deviceInterfaceData, SETUP_ERROR);
	deviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	//iterate through devices
	while (SetupDiEnumDeviceInterfaces(deviceset, nullptr, hidguid, deviceindex, deviceInterfaceData))
	{
		//this should fail originally in order to get buffer size
		if (deviceInterfaceInfo != nullptr)
		{
			free(deviceInterfaceInfo);
			deviceInterfaceInfo = 0;
		}
		if (SetupDiGetDeviceInterfaceDetail(deviceset, deviceInterfaceData, nullptr, 0, (PDWORD)&buffersize, nullptr) ||
			GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			goto SETUP_ERROR;
		}
		deviceInterfaceInfo = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(buffersize);
		//malloc check
		CHECK_NULL(deviceInterfaceInfo, SETUP_ERROR);
		deviceInterfaceInfo->cbSize = sizeof(*deviceInterfaceInfo);
		
		//device info buffer allocated, get details
		if (!SetupDiGetDeviceInterfaceDetail(deviceset, deviceInterfaceData, deviceInterfaceInfo, buffersize, (PDWORD)&buffersize, nullptr))
		{
			goto SETUP_ERROR;
		}
		
		//you must pass in the device id of the hid client to read from
		if (deviceindex == pDeviceId)
		{
			_controllerHandle = CreateFile(
				deviceInterfaceInfo->DevicePath,
				GENERIC_READ | GENERIC_WRITE,
				0,
				nullptr,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				nullptr
				);
			if (_controllerHandle == INVALID_HANDLE_VALUE)
			{
				Log(L"Error opening HID Device: Error No: %d", GetLastError());
				goto HID_SETUP_FAILURE;
			}
			else
			{

		    	//get preparsed data
				if (HidD_GetPreparsedData(_controllerHandle, &_pPreparsedData) == FALSE)
				{
					goto HID_SETUP_FAILURE;
				}

				//get device capabilities
				_pCaps = (PHIDP_CAPS)(malloc(sizeof(HIDP_CAPS)));
				//malloc check
				CHECK_NULL(_pCaps, HID_SETUP_FAILURE);
				_succ = HidP_GetCaps(_pPreparsedData, _pCaps);
				CHECK_HID(_succ, HID_SETUP_FAILURE);


				//get button capabilities
				_pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS)* _pCaps->NumberInputButtonCaps);
				//malloc check
				CHECK_NULL(_pButtonCaps, HID_SETUP_FAILURE);
				USHORT numInputButtonCaps = _pCaps->NumberInputButtonCaps;

				_succ = HidP_GetButtonCaps(HidP_Input, _pButtonCaps, &numInputButtonCaps, _pPreparsedData);
				CHECK_HID(_succ, HID_SETUP_FAILURE);

				//prep the button usage data structs
				_pButtonUsages = (PUSAGE)malloc(sizeof(USAGE)*(_pButtonCaps->Range.DataIndexMax - _pButtonCaps->Range.DataIndexMin + 1));
				//malloc check
				CHECK_NULL(_pButtonUsages, HID_SETUP_FAILURE);
				ULONG numButtonUsages = _pButtonCaps->Range.UsageMax - _pButtonCaps->Range.UsageMin + 1;

				//get max data length
				_pInputReport = (PCHAR)malloc(_pCaps->InputReportByteLength);
				//malloc check
				CHECK_NULL(_pInputReport, HID_SETUP_FAILURE);
				DWORD readbytecount = 0;

				//get value caps
				_pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS)* _pCaps->NumberInputValueCaps);
				//malloc check
				CHECK_NULL(_pValueCaps, HID_SETUP_FAILURE);
				USHORT numInputValueCaps = _pCaps->NumberInputValueCaps;

				_succ = HidP_GetValueCaps(HidP_Input, _pValueCaps, &numInputValueCaps, _pPreparsedData);
				CHECK_HID(_succ, HID_SETUP_FAILURE);

				goto SETUP_DONE;


			HID_SETUP_FAILURE:
				clearHidStructures();
				return false;
			}
		}


		deviceindex++;
		deviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	}

	goto SETUP_DONE;

SETUP_ERROR:
	int err = GetLastError();
	return false;
SETUP_DONE:
	if (deviceset != INVALID_HANDLE_VALUE && deviceset != nullptr)
	{
		SetupDiDestroyDeviceInfoList(deviceset);
	}

	if (hidguid != nullptr)
	{
		free(hidguid);
	}

	if (deviceInterfaceData != nullptr)
	{
		free(deviceInterfaceData);
	}

	if (deviceInterfaceInfo != nullptr)
	{
		free(deviceInterfaceInfo);
	}


	return true;
}
예제 #12
0
static void ParseRawInputHID(PRAWINPUT pRawInput)
{
	PHIDP_PREPARSED_DATA pPreparsedData = NULL;
	HIDP_CAPS            Caps;
	PHIDP_BUTTON_CAPS    pButtonCaps = NULL;
	PHIDP_VALUE_CAPS     pValueCaps = NULL;
	UINT                 bufferSize;
	ULONG                usageLength, value;
	TCHAR                name[1024] = {0};
	UINT                 nameSize = 1024;
	RID_DEVICE_INFO      devInfo = {0};
	std::wstring         devName;
	USHORT               capsLength = 0;
	USAGE                usage[MAX_BUTTONS] = {0};
	Mappings             *mapping = NULL;
	MapVector::iterator  it;

	GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, name, &nameSize);

	devName = name;
	std::transform(devName.begin(), devName.end(), devName.begin(), ::toupper);

	for(it = mapVector.begin(); it != mapVector.end(); it++)
	{
		if((*it).hidPath == devName)
		{
			mapping = &(*it);
			break;
		}
	}

	if(mapping == NULL)
		return;

	CHECK( GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0 );
	CHECK( pPreparsedData = (PHIDP_PREPARSED_DATA)malloc(bufferSize) );
	CHECK( (int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0 );
	CHECK( HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS );
	//pSize = sizeof(devInfo);
	//GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &devInfo, &pSize);

	//Unset buttons/axes mapped to this device
	//ResetData(&mapping->data[0]);
	//ResetData(&mapping->data[1]);
	memset(&mapping->data[0], 0xFF, sizeof(wheel_data_t));
	memset(&mapping->data[1], 0xFF, sizeof(wheel_data_t));
	mapping->data[0].buttons = 0;
	mapping->data[1].buttons = 0;
	mapping->data[0].hatswitch = 0x8;
	mapping->data[1].hatswitch = 0x8;

	//Get pressed buttons
	CHECK( pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * Caps.NumberInputButtonCaps) );
	//If fails, maybe wheel only has axes
	capsLength = Caps.NumberInputButtonCaps;
	HidP_GetButtonCaps(HidP_Input, pButtonCaps, &capsLength, pPreparsedData);

	int numberOfButtons = pButtonCaps->Range.UsageMax - pButtonCaps->Range.UsageMin + 1;
	usageLength = numberOfButtons;
	NTSTATUS stat;
	if((stat = HidP_GetUsages(
			HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
			(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid)) == HIDP_STATUS_SUCCESS )
	{
		for(uint32_t i = 0; i < usageLength; i++)
		{
			uint16_t btn = mapping->btnMap[usage[i] - pButtonCaps->Range.UsageMin];
			for(int j=0; j<2; j++)
			{
				PS2WheelTypes wt = (PS2WheelTypes)conf.WheelType[j];
				if(PLY_IS_MAPPED(j, btn))
				{
					uint32_t wtbtn = (1 << convert_wt_btn(wt, PLY_GET_VALUE(j, btn))) & 0xFFF; //12bit mask
					mapping->data[j].buttons |= wtbtn;
				}
			}
		}
	}

	/// Get axes' values
	CHECK( pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps) );
	capsLength = Caps.NumberInputValueCaps;
	if(HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )
	{
		for(USHORT i = 0; i < capsLength; i++)
		{
			if(HidP_GetUsageValue(
					HidP_Input, pValueCaps[i].UsagePage, 0,
					pValueCaps[i].Range.UsageMin, &value, pPreparsedData,
					(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
				) != HIDP_STATUS_SUCCESS )
			{
				continue; // if here then maybe something is up with HIDP_CAPS.NumberInputValueCaps
			}

			//fprintf(stderr, "Min/max %d/%d\t", pValueCaps[i].LogicalMin, pValueCaps[i].LogicalMax);
			//TODO can be simpler?
			//Get mapped axis for physical axis
			uint16_t v = 0;
			switch(pValueCaps[i].Range.UsageMin)
			{
				// X-axis 0x30
				case HID_USAGE_GENERIC_X: 
					v = mapping->axisMap[0]; 
					break;
				// Y-axis
				case HID_USAGE_GENERIC_Y: 
					v = mapping->axisMap[1]; 
					break;
				// Z-axis
				case HID_USAGE_GENERIC_Z: 
					v = mapping->axisMap[2]; 
					break;
				// Rotate-X
				case HID_USAGE_GENERIC_RX: 
					v = mapping->axisMap[3]; 
					break;
				// Rotate-Y
				case HID_USAGE_GENERIC_RY: 
					v = mapping->axisMap[4]; 
					break;
				// Rotate-Z 0x35
				case HID_USAGE_GENERIC_RZ: 
					v = mapping->axisMap[5]; 
					break;
				case HID_USAGE_GENERIC_HATSWITCH:
					//fprintf(stderr, "Hat: %02X\n", value);
					v = mapping->axisMap[6];
					break;
			}

			int type = 0;
			for(int j=0; j<2; j++)
			{
				if(!PLY_IS_MAPPED(j, v))
					continue;

				type = conf.WheelType[j];

				switch(PLY_GET_VALUE(j, v))
				{
				case PAD_AXIS_X: // X-axis
					//fprintf(stderr, "X: %d\n", value);
					// Need for logical min too?
					//generic_data.axis_x = ((value - pValueCaps[i].LogicalMin) * 0x3FF) / (pValueCaps[i].LogicalMax - pValueCaps[i].LogicalMin);
					if(type == WT_DRIVING_FORCE_PRO)
						mapping->data[j].steering = (value * 0x3FFF) / pValueCaps[i].LogicalMax;
					else
						//XXX Limit value range to 0..1023 if using 'generic' wheel descriptor
						mapping->data[j].steering = (value * 0x3FF) / pValueCaps[i].LogicalMax;
					break;

				case PAD_AXIS_Y: // Y-axis
					if(!(devInfo.hid.dwVendorId == 0x046D && devInfo.hid.dwProductId == 0xCA03))
						//XXX Limit value range to 0..255
						mapping->data[j].clutch = (value * 0xFF) / pValueCaps[i].LogicalMax;
					break;

				case PAD_AXIS_Z: // Z-axis
					//fprintf(stderr, "Z: %d\n", value);
					//XXX Limit value range to 0..255
					mapping->data[j].throttle = (value * 0xFF) / pValueCaps[i].LogicalMax;
					break;

				case PAD_AXIS_RZ: // Rotate-Z
					//fprintf(stderr, "Rz: %d\n", value);
					//XXX Limit value range to 0..255
					mapping->data[j].brake = (value * 0xFF) / pValueCaps[i].LogicalMax;
					break;

				case PAD_AXIS_HAT: // TODO Hat Switch
					//fprintf(stderr, "Hat: %02X\n", value);
					//TODO 4 vs 8 direction hat switch
					if(pValueCaps[i].LogicalMax == 4 && value < 4)
						mapping->data[j].hatswitch = HATS_8TO4[value];
					else
						mapping->data[j].hatswitch = value;
					break;
				}
			}
		}
	}

	Error:
	SAFE_FREE(pPreparsedData);
	SAFE_FREE(pButtonCaps);
	SAFE_FREE(pValueCaps);
}
예제 #13
0
static void ParseRawInputHID(PRAWINPUT pRawInput, HIDState *hs)
{
	PHIDP_PREPARSED_DATA pPreparsedData = NULL;
	HIDP_CAPS            Caps;
	PHIDP_BUTTON_CAPS    pButtonCaps = NULL;
	PHIDP_VALUE_CAPS     pValueCaps = NULL;
	UINT                 bufferSize = 0;
	ULONG                usageLength, value;
	TCHAR                name[1024] = {0};
	UINT                 nameSize = 1024;
	RID_DEVICE_INFO      devInfo = {0};
	std::wstring         devName;
	USHORT               capsLength = 0;
	USAGE                usage[32] = {0};
	int                  numberOfButtons;

	GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, name, &nameSize);

	devName = name;
	std::transform(devName.begin(), devName.end(), devName.begin(), ::toupper);

	CHECK( GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0 );
	CHECK( pPreparsedData = (PHIDP_PREPARSED_DATA)malloc(bufferSize) );
	CHECK( (int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0 );
	CHECK( HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS );

	//Get pressed buttons
	CHECK( pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * Caps.NumberInputButtonCaps) );
	//If fails, maybe wheel only has axes
	capsLength = Caps.NumberInputButtonCaps;
	HidP_GetButtonCaps(HidP_Input, pButtonCaps, &capsLength, pPreparsedData);

	numberOfButtons = pButtonCaps->Range.UsageMax - pButtonCaps->Range.UsageMin + 1;
	usageLength = countof(usage);//numberOfButtons;

	NTSTATUS stat;
	if((stat = HidP_GetUsages(
			HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
			(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid)) == HIDP_STATUS_SUCCESS )
	{
		for(uint32_t i = 0; i < usageLength; i++)
		{
			uint16_t btn = usage[i] - pButtonCaps->Range.UsageMin;
		}
	}

	/// Get axes' values
	CHECK( pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps) );
	capsLength = Caps.NumberInputValueCaps;
	if(HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )
	{
		for(USHORT i = 0; i < capsLength; i++)
		{
			if(HidP_GetUsageValue(
					HidP_Input, pValueCaps[i].UsagePage, 0,
					pValueCaps[i].Range.UsageMin, &value, pPreparsedData,
					(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
				) != HIDP_STATUS_SUCCESS )
			{
				continue; // if here then maybe something is up with HIDP_CAPS.NumberInputValueCaps
			}

			switch(pValueCaps[i].Range.UsageMin)
			{
				case HID_USAGE_GENERIC_X: //0x30
				case HID_USAGE_GENERIC_Y:
				case HID_USAGE_GENERIC_Z:
				case HID_USAGE_GENERIC_RX:
				case HID_USAGE_GENERIC_RY:
				case HID_USAGE_GENERIC_RZ: //0x35
					//int axis = (value * 0x3FFF) / pValueCaps[i].LogicalMax;
					break;
				case HID_USAGE_GENERIC_HATSWITCH:
					//fprintf(stderr, "Hat: %02X\n", value);
					break;
			}
		}
	}

	Error:
	SAFE_FREE(pPreparsedData);
	SAFE_FREE(pButtonCaps);
	SAFE_FREE(pValueCaps);
}
예제 #14
0
파일: USBHID.c 프로젝트: agb861/ddd
/*********************************************************************
*
*       _AddConnection
*
*  Function description
*    Checks the information about the queried device, if complying with
*    out vendor page information, add the device to the connection list.
*
*     
*  Return value:
*   1    - O.K., HID device added.
*   0    - HID device not compatible.
*    
*/
static int _AddConnection(HANDLE hDevList, SP_DEVICE_INTERFACE_DATA * pDevData, CONN_INFO * pConnInfo) {
  SP_INTERFACE_DEVICE_DETAIL_DATA * pDevDetail;
  DWORD                             ReqLen;
  BOOL                              succ;
  HANDLE                            hDevice;
  int                               r;

  r          = 0;
  ReqLen     = 0;
  pDevDetail = NULL;
  // Get length of INTERFACE_DEVICE_DETAIL_DATA, allocate buffer
  // This function call returns the system error "buffer too small" (code 122).
  // We ignore this return code.
  SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, NULL, ReqLen, &ReqLen, NULL);
  pDevDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(ReqLen);
  if (pDevDetail == NULL ) {
    // Memory allocation failed
    return 0;
  }
  // Now get the INTERFACE_DEVICE_DETAIL_DATA struct
  ZeroMemory(pDevDetail,ReqLen);
  pDevDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
  succ = SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, pDevDetail, ReqLen, &ReqLen, NULL);
  if (succ == FALSE) {
    //
    // Could not retrieve information about the device
    //
    free(pDevDetail);
    return 0;
  }
  //
  //  Open a device handle to the HID device and retriece HID information
  //
  hDevice = CreateFile(pDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  if (hDevice != INVALID_HANDLE_VALUE) {
    PHIDP_PREPARSED_DATA  pPreparsedData;
    HIDP_CAPS             Capabilities;

    //
    //  Parse the information from HID device
    //
    HidD_GetPreparsedData(hDevice, &pPreparsedData);
    HidP_GetCaps(pPreparsedData, &Capabilities);
    //
    //  Does the device match the Vendor specific page implementation?
    //
    if (Capabilities.UsagePage == _VendorPage) {
      HIDD_ATTRIBUTES  Attributes;

      memset(&Attributes, 0, sizeof(Attributes));
      Attributes.Size = sizeof(Attributes);
      HidD_GetAttributes(hDevice, &Attributes); 
      strcpy(pConnInfo->acDevicePath, pDevDetail->DevicePath);
      pConnInfo->InputReportByteLength  = Capabilities.InputReportByteLength;
      pConnInfo->OutputReportByteLength = Capabilities.OutputReportByteLength;
      pConnInfo->ProductId              = Attributes.ProductID;
      pConnInfo->VendorId               = Attributes.VendorID;
      r = 1;
    }
    CloseHandle(hDevice);
  }
  free(pDevDetail);
  return r;
}
예제 #15
0
//  rawhid_open - open 1 or more devices
//
//    Inputs:
//	max = maximum number of devices to open
//	vid = Vendor ID, or -1 if any
//	pid = Product ID, or -1 if any
//	usage_page = top level usage page, or -1 if any
//	usage = top level usage number, or -1 if any
//    Output:
//	actual number of devices opened
//
int rawhid_open(int max, int vid, int pid, int usage_page, int usage)
{
        GUID guid;
        HDEVINFO info;
        DWORD index=0, reqd_size;
        SP_DEVICE_INTERFACE_DATA iface;
        SP_DEVICE_INTERFACE_DETAIL_DATA *details;
        HIDD_ATTRIBUTES attrib;
        PHIDP_PREPARSED_DATA hid_data;
        HIDP_CAPS capabilities;
        HANDLE h;
        BOOL ret;
	hid_t *hid;
	int count=0;

	if (first_hid) free_all_hid();
	if (max < 1) return 0;
	if (!rx_event) {
		rx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
		tx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
		InitializeCriticalSection(&rx_mutex);
		InitializeCriticalSection(&tx_mutex);
	}
	HidD_GetHidGuid(&guid);
	info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (info == INVALID_HANDLE_VALUE) return 0;
	for (index=0; 1 ;index++) {
		iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface);
		if (!ret) return count;
		SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL);
		details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(reqd_size);
		if (details == NULL) continue;

		memset(details, 0, reqd_size);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details,
			reqd_size, NULL, NULL);
		if (!ret) {
			free(details);
			continue;
		}
		h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE,
			FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
		free(details);
		if (h == INVALID_HANDLE_VALUE) continue;
		attrib.Size = sizeof(HIDD_ATTRIBUTES);
		ret = HidD_GetAttributes(h, &attrib);
		//printf("vid: %4x\n", attrib.VendorID);
		if (!ret || (vid > 0 && attrib.VendorID != vid) ||
		  (pid > 0 && attrib.ProductID != pid) ||
		  !HidD_GetPreparsedData(h, &hid_data)) {
			CloseHandle(h);
			continue;
		}
		if (!HidP_GetCaps(hid_data, &capabilities) ||
		  (usage_page > 0 && capabilities.UsagePage != usage_page) ||
		  (usage > 0 && capabilities.Usage != usage)) {
			HidD_FreePreparsedData(hid_data);
			CloseHandle(h);
			continue;
		}
		HidD_FreePreparsedData(hid_data);
		hid = (struct hid_struct *)malloc(sizeof(struct hid_struct));
		if (!hid) {
			CloseHandle(h);
			continue;
		}
		hid->handle = h;
		hid->open = 1;
		add_hid(hid);
		count++;
		if (count >= max) return count;
	}
	return count;
}
예제 #16
0
파일: pnp.c 프로젝트: cxjlante/at91sam3s
BOOLEAN
OpenHidDevice (
    IN       PCHAR          DevicePath,
    IN       BOOL           HasReadAccess,
    IN       BOOL           HasWriteAccess,
    IN       BOOL           IsOverlapped,
    IN       BOOL           IsExclusive,
    IN OUT   PHID_DEVICE    HidDevice
)
/*++
RoutineDescription:
    Given the HardwareDeviceInfo, representing a handle to the plug and
    play information, and deviceInfoData, representing a specific hid device,
    open that device and fill in all the relivant information in the given
    HID_DEVICE structure.

    return if the open and initialization was successfull or not.

--*/
{
    DWORD   accessFlags = 0;
    DWORD   sharingFlags = 0;
    BOOLEAN bSuccess;
    INT     iDevicePathSize;
	HRESULT stringReturn;

    iDevicePathSize = strlen(DevicePath) + 1;
    
    HidDevice -> DevicePath = malloc(iDevicePathSize);

    if (NULL == HidDevice -> DevicePath) 
    {
        return (FALSE);
    }

    stringReturn = StringCbCopy(HidDevice -> DevicePath, iDevicePathSize, DevicePath);
    
    if (HasReadAccess)
    {
        accessFlags |= GENERIC_READ;
    }

    if (HasWriteAccess)
    {
        accessFlags |= GENERIC_WRITE;
    }

    if (!IsExclusive)
    {
        sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
    }
    
    //
	//  The hid.dll api's do not pass the overlapped structure into deviceiocontrol
	//  so to use them we must have a non overlapped device.  If the request is for
	//  an overlapped device we will close the device below and get a handle to an
	//  overlapped device
	//
	
	HidDevice->HidDevice = CreateFile (DevicePath,
                                       accessFlags,
                                       sharingFlags,
                                       NULL,        // no SECURITY_ATTRIBUTES structure
                                       OPEN_EXISTING, // No special create flags
                                       0,   // Open device as non-overlapped so we can get data
                                       NULL);       // No template file

    if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) 
    {
        free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = INVALID_HANDLE_VALUE ;
        return FALSE;
    }

    HidDevice -> OpenedForRead = HasReadAccess;
    HidDevice -> OpenedForWrite = HasWriteAccess;
    HidDevice -> OpenedOverlapped = IsOverlapped;
    HidDevice -> OpenedExclusive = IsExclusive;
    
    //
    // If the device was not opened as overlapped, then fill in the rest of the
    //  HidDevice structure.  However, if opened as overlapped, this handle cannot
    //  be used in the calls to the HidD_ exported functions since each of these
    //  functions does synchronous I/O.
    //

	if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) 
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL ;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE ;
		return FALSE;
	}

	if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes)) 
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
		HidD_FreePreparsedData (HidDevice->Ppd);
		HidDevice->Ppd = NULL;

		return FALSE;
	}

	if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps))
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
		HidD_FreePreparsedData (HidDevice->Ppd);
		HidDevice->Ppd = NULL;

		return FALSE;
	}

	//
	// At this point the client has a choice.  It may chose to look at the
	// Usage and Page of the top level collection found in the HIDP_CAPS
	// structure.  In this way it could just use the usages it knows about.
	// If either HidP_GetUsages or HidP_GetUsageValue return an error then
	// that particular usage does not exist in the report.
	// This is most likely the preferred method as the application can only
	// use usages of which it already knows.
	// In this case the app need not even call GetButtonCaps or GetValueCaps.
	//
	// In this example, however, we will call FillDeviceInfo to look for all
	//    of the usages in the device.
	//

	bSuccess = FillDeviceInfo(HidDevice);

	if (FALSE == bSuccess)
	{
		CloseHidDevice(HidDevice);
		return (FALSE);
	}
    
	if (IsOverlapped)
	{
		CloseHandle(HidDevice->HidDevice);

	    HidDevice->HidDevice = CreateFile (DevicePath,
                                       accessFlags,
                                       sharingFlags,
                                       NULL,        // no SECURITY_ATTRIBUTES structure
                                       OPEN_EXISTING, // No special create flags
                                       FILE_FLAG_OVERLAPPED, // Now we open the device as overlapped
                                       NULL);       // No template file
	
	    if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) 
		{
			CloseHidDevice(HidDevice);
			return FALSE;
		}
	}

    return (TRUE);
}
예제 #17
0
파일: Device.cpp 프로젝트: Realhram/wdk81
HRESULT
CMyDevice::GetHidCapabilities(
	void
	)
/*++

Routine Description:

	This routine gets the capabilities and attributes from the HID collection

Arguments:

	None.

Return Value:

	HRESULT

--*/
{
	HID_COLLECTION_INFORMATION info;
	HRESULT hr = S_OK;

	ZeroMemory((BYTE *)&info, sizeof(info));
	hr = CreateAndSendIoctlRequest(NULL, 0, (BYTE*)(&info), sizeof(info), IOCTL_HID_GET_COLLECTION_INFORMATION);

	if (SUCCEEDED(hr))
	{
		m_Ppd = (PHIDP_PREPARSED_DATA)(new BYTE[info.DescriptorSize]);

		if (m_Ppd == NULL)
		{
			hr = E_OUTOFMEMORY;

			TraceEvents(TRACE_LEVEL_ERROR, 
						TEST_TRACE_DEVICE, 
						"%!FUNC! Out of memory"
						);
		}
	}

	if (SUCCEEDED(hr))
	{
		ZeroMemory((BYTE*)m_Ppd, info.DescriptorSize);
		hr = CreateAndSendIoctlRequest(NULL, 0, (BYTE*)m_Ppd, info.DescriptorSize, IOCTL_HID_GET_COLLECTION_DESCRIPTOR);
	}


	if (SUCCEEDED(hr))
	{
		ZeroMemory(&m_Caps, sizeof (m_Caps));

		hr = HidP_GetCaps (m_Ppd, &m_Caps);

		if (FAILED(hr))
		{
			TraceEvents(TRACE_LEVEL_ERROR, 
						TEST_TRACE_DEVICE, 
						"%!FUNC! HidP_GetCaps failed %!HRESULT!",
						hr
						);
		}
	}

	if (SUCCEEDED(hr))
	{
		//
		// Validate the capabilities.
		//
		if (m_Caps.UsagePage != 0xff00 ||
			m_Caps.FeatureReportByteLength != 2)
		{
			hr = E_UNEXPECTED;

			TraceEvents(TRACE_LEVEL_ERROR, 
						TEST_TRACE_DEVICE, 
						"%!FUNC! Capabilities don't match expected usage page 0x%x and feature report length %d %!HRESULT!",
						m_Caps.UsagePage,
						m_Caps.FeatureReportByteLength,
						hr
						);

		}
	}

	return hr;
}
예제 #18
0
//  open - open 1 or more devices
//
//    Inputs:
//      max = maximum number of devices to open
//      vid = Vendor ID, or -1 if any
//      pid = Product ID, or -1 if any
//      usage_page = top level usage page, or -1 if any
//      usage = top level usage number, or -1 if any
//    Output:
//      actual number of devices opened
//
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
{
        GUID guid;
        HDEVINFO info;
        DWORD index=0, reqd_size;
        SP_DEVICE_INTERFACE_DATA iface;
        SP_DEVICE_INTERFACE_DETAIL_DATA *details;
        HIDD_ATTRIBUTES attrib;
        PHIDP_PREPARSED_DATA hid_data;
        HIDP_CAPS capabilities;
        HANDLE h;
        BOOL ret;
        hid_t *hid;

        int count=0;

        if (first_hid) free_all_hid();

        if (max < 1) return 0;

        if (!rx_event)
        {
                rx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
                tx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
                InitializeCriticalSection(&rx_mutex);
                InitializeCriticalSection(&tx_mutex);
    }

        HidD_GetHidGuid(&guid);

        info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
        if (info == INVALID_HANDLE_VALUE) return 0;

        for (index=0; 1 ;index++)
        {
                iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
                ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface);
                if (!ret) return count;

                SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL);
                details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(reqd_size);
                if (details == NULL) continue;

                memset(details, 0, reqd_size);
                details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
                ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL);
                if (!ret)
                {
                        free(details);
                        continue;
                }

                h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                if (h == INVALID_HANDLE_VALUE)
                {
                        DWORD err = GetLastError();

                        // I get ERROR_ACCESS_DENIED with most/all my input devices (mice/trackballs/tablet).
                        // Let's not log it :)
                        if (err == ERROR_ACCESS_DENIED)
                        {
                                free(details);
                                continue;
                        }

                        // qDebug wipes the GetLastError() it seems, so do that after print_win32_err().
                        print_win32_err(err);
                        qDebug() << "Problem opening handle, path: " << QString().fromWCharArray(details->DevicePath);

                        free(details);
                        continue;
                }

                free(details);

                attrib.Size = sizeof(HIDD_ATTRIBUTES);
                ret = HidD_GetAttributes(h, &attrib);
                //printf("vid: %4x\n", attrib.VendorID);
                if (!ret || (vid > 0 && attrib.VendorID != vid) ||
              (pid > 0 && attrib.ProductID != pid) ||
                          !HidD_GetPreparsedData(h, &hid_data))
                {
                        CloseHandle(h);
                        continue;
                }

                if (!HidP_GetCaps(hid_data, &capabilities) ||
              (usage_page > 0 && capabilities.UsagePage != usage_page) ||
                          (usage > 0 && capabilities.Usage != usage))
                {
                        HidD_FreePreparsedData(hid_data);
                        CloseHandle(h);
                        continue;
                }

                HidD_FreePreparsedData(hid_data);

                hid = (struct hid_struct *)malloc(sizeof(struct hid_struct));
                if (!hid)
                {
                        CloseHandle(h);
                        continue;
                }

//              COMMTIMEOUTS CommTimeouts;
//              CommTimeouts.ReadIntervalTimeout = 100;                 // 100ms
//              CommTimeouts.ReadTotalTimeoutConstant = 5;              // ms
//              CommTimeouts.ReadTotalTimeoutMultiplier = 1;    //
//              CommTimeouts.WriteTotalTimeoutConstant = 5;             // ms
//              CommTimeouts.WriteTotalTimeoutMultiplier = 1;   //
//              if (!SetCommTimeouts(h, &CommTimeouts))
//              {
////                    DWORD err = GetLastError();
//
//              }

                qDebug("Open: Handle address: %li for num: %i", (long int) h, count);

                hid->handle = h;
                add_hid(hid);

                count++;
                if (count >= max) return count;
        }

        return count;
}
USBHIDDLL_API			 DWORD dwRead_FromHIDDevice(PHANDLE pReadHandle, BYTE byReadBuff[], DWORD len){

				 DWORD			dwNumberOfBytesRead;
				 DWORD			dwResponseSW = 0;
				 HIDP_CAPS		Capabilities;
				 PHIDP_PREPARSED_DATA		HidParsedData;
				 OVERLAPPED		HidOverlapped;
				 HANDLE			hEvent;

				 LPBYTE	 lpReadBuff = (LPBYTE)malloc(0x21);


				 /* Create a new event for report capture */
				 hEvent = CreateEvent(NULL, TRUE, TRUE, "");

				 /* fill the HidOverlapped structure so that Windows knows which
				 event to cause when the device sends an IN report */
				 HidOverlapped.hEvent = hEvent;
				 HidOverlapped.Offset = 0;
				 HidOverlapped.OffsetHigh = 0;

				 BOOL bResult = false;

				 //			LPCOMMTIMEOUTS lpCommitTimes = (LPCOMMTIMEOUTS)malloc(sizeof(LPCOMMTIMEOUTS));

				 if(*pReadHandle != NULL){
					 HidD_GetPreparsedData(*pReadHandle, &HidParsedData);

					 /* extract the capabilities info */
					 HidP_GetCaps( HidParsedData ,&Capabilities);

					 /* Free the memory allocated when getting the preparsed data */
					 HidD_FreePreparsedData(HidParsedData);

					 bResult = ReadFile(*pReadHandle, 
						 lpReadBuff, 
						 Capabilities.InputReportByteLength,
						 &dwNumberOfBytesRead,
						 (LPOVERLAPPED)&HidOverlapped);


					 if ( bResult == 0 )
					 {
						 // 读取错误信息
						 DWORD dwResult = GetLastError();

						 // I/O端口繁忙
						 if ( dwResult == ERROR_IO_PENDING )
						 {

							 // 需挂起等待
							 dwResult = WaitForSingleObject ( HidOverlapped.hEvent, INFINITE );

							 // I/O端口正常
							 if ( dwResult == WAIT_OBJECT_0 )
							 {
								 // 去读取数据的正常返回值
								 GetOverlappedResult ( *pReadHandle, &HidOverlapped, &dwNumberOfBytesRead, FALSE );
							 }
							 else
							 {
								 //							BOOL bGetTime = GetCommTimeouts(*pReadHandle, lpCommitTimes);
								 free(lpReadBuff);
								 CloseHandle(hEvent);
								 return -1;	// 等待超时
							 }

						 }
						 else
						 {
							 return -1;	// 不明错误
						 }
					 }
				 }
				 for(int i = 0; i < (len + 2); i ++){
					 byReadBuff[i] = *(lpReadBuff + i + 1);
				 }
				 dwResponseSW |= byReadBuff[len];

				 dwResponseSW = (dwResponseSW << 8) | (byReadBuff[len + 1]);
				 free(lpReadBuff);
				 CloseHandle(hEvent);
				 return	dwResponseSW;
			 }
예제 #20
0
bool CLCDConnectionLogitech::HIDInit()
{
	if (GetConnectionState() != CONNECTED ||
		m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
		return false;

	// Logitech G15 
	int VendorID = 0x046d;
	int ProductID = 0xc222;

	//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;
	int									MemberIndex = 0;
	LONG								Result;

	DWORD Length = 0;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
	HANDLE hDevInfo = NULL;
	GUID HidGuid;
	ULONG Required = 0;

	bool MyDeviceDetected = false;

	/*
	API function: HidD_GetHidGuid
	Get the GUID for all system HIDs.
	Returns: the GUID in HidGuid.
	*/

	HidD_GetHidGuid(&HidGuid);

	/*
	API function: SetupDiGetClassDevs
	Returns: a handle to a device information set for all installed devices.
	Requires: the GUID returned by GetHidGuid.
	*/

	hDevInfo = SetupDiGetClassDevs
		(&HidGuid,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	devInfoData.cbSize = sizeof(devInfoData);

	//Step through the available devices looking for the one we want. 
	//Quit on detecting the desired device or checking all available devices without success.

	MemberIndex = 0;
	LastDevice = FALSE;

	do
	{
		/*
		API function: SetupDiEnumDeviceInterfaces
		On return, MyDeviceInterfaceData contains the handle to a
		SP_DEVICE_INTERFACE_DATA structure for a detected device.
		Requires:
		The DeviceInfoSet returned in SetupDiGetClassDevs.
		The HidGuid returned in GetHidGuid.
		An index to specify a device.
		*/

		Result = SetupDiEnumDeviceInterfaces
			(hDevInfo,
			0,
			&HidGuid,
			MemberIndex,
			&devInfoData);

		if (Result != 0)
		{
			//A device has been detected, so get more information about it.

			/*
			API function: SetupDiGetDeviceInterfaceDetail
			Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
			containing information about a device.
			To retrieve the information, call this function twice.
			The first time returns the size of the structure in Length.
			The second time returns a pointer to the data in DeviceInfoSet.
			Requires:
			A DeviceInfoSet returned by SetupDiGetClassDevs
			The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

			The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
			This application doesn't retrieve or use the structure.
			If retrieving the structure, set
			MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
			and pass the structure's address.
			*/

			//Get the Length value.
			//The call will return with a "buffer too small" error which can be ignored.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				NULL,
				0,
				&Length,
				NULL);

			//Allocate memory for the hDevInfo structure, using the returned Length.

			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

			//Set cbSize in the detailData structure.

			detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			//Call the function again, this time passing it the returned buffer size.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				detailData,
				Length,
				&Required,
				NULL);

			// Open a handle to the device.
			// To enable retrieving information about a system mouse or keyboard,
			// don't request Read or Write access for this handle.

			/*
			API function: CreateFile
			Returns: a handle that enables reading and writing to the device.
			Requires:
			The DevicePath in the detailData structure
			returned by SetupDiGetDeviceInterfaceDetail.
			*/

			m_hHIDDeviceHandle = CreateFile
				(detailData->DevicePath,
				FILE_GENERIC_READ | FILE_GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				(LPSECURITY_ATTRIBUTES)NULL,
				OPEN_EXISTING,
				FILE_FLAG_OVERLAPPED,
				NULL);

			/*
			API function: HidD_GetAttributes
			Requests information from the device.
			Requires: the handle returned by CreateFile.
			Returns: a HIDD_ATTRIBUTES structure containing
			the Vendor ID, Product ID, and Product Version Number.
			Use this information to decide if the detected device is
			the one we're looking for.
			*/

			//Set the Size to the number of bytes in the structure.

			Attributes.Size = sizeof(Attributes);

			Result = HidD_GetAttributes
				(m_hHIDDeviceHandle,
				&Attributes);

			//Is it the desired device?
			MyDeviceDetected = FALSE;

			if (Attributes.VendorID == VendorID)
			{
				if (Attributes.ProductID == ProductID)
				{
					//Both the Vendor ID and Product ID match.
					MyDeviceDetected = TRUE;
				}
				else
					CloseHandle(m_hHIDDeviceHandle);

			}
			else
				CloseHandle(m_hHIDDeviceHandle);

			//Free the memory used by the detailData structure (no longer needed).
			free(detailData);
		}

		else
			LastDevice = TRUE;

		MemberIndex = MemberIndex + 1;
	} //do
	while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));

	if (MyDeviceDetected)
	{
		PHIDP_PREPARSED_DATA	PreparsedData;

		HidD_GetPreparsedData
			(m_hHIDDeviceHandle,
			&PreparsedData);

		HidP_GetCaps
			(PreparsedData,
			&m_HIDCapabilities);

		HidD_FreePreparsedData(PreparsedData);
	}
	//Free the memory reserved for hDevInfo by SetupDiClassDevs.

	SetupDiDestroyDeviceInfoList(hDevInfo);

	return MyDeviceDetected;
}
예제 #21
0
파일: hid.c 프로젝트: bagong/hidapi
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	BOOL res;
	struct hid_device_info *root = NULL; /* return object */
	struct hid_device_info *cur_dev = NULL;

	/* Windows objects for interacting with the driver. */
	GUID InterfaceClassGuid;
	HidD_GetHidGuid(&InterfaceClassGuid);
	SP_DEVINFO_DATA devinfo_data;
	SP_DEVICE_INTERFACE_DATA device_interface_data;
	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
	int device_index = 0;
	int i;

	if (hid_init() < 0)
		return NULL;

	/* Initialize the Windows objects. */
	memset(&devinfo_data, 0x0, sizeof(devinfo_data));
	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	/* Get information for all the devices belonging to the HID class. */
	device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	/* Iterate over each device in the HID class, looking for the right one. */

	for (;;) {
		HANDLE write_handle = INVALID_HANDLE_VALUE;
		DWORD required_size = 0;
		HIDD_ATTRIBUTES attrib;

		res = SetupDiEnumDeviceInterfaces(device_info_set,
			NULL,
			&InterfaceClassGuid,
			device_index,
			&device_interface_data);

		if (!res) {
			/* A return of FALSE from this function means that
			   there are no more devices. */
			break;
		}

		/* Call with 0-sized detail size, and let the function
		   tell us how long the detail struct needs to be. The
		   size is put in &required_size. */
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			NULL,
			0,
			&required_size,
			NULL);

		/* Allocate a long enough structure for device_interface_detail_data. */
		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

		/* Get the detailed data for this device. The detail data gives us
		   the device path for this device, which is then passed into
		   CreateFile() to get a handle to the device. */
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			device_interface_detail_data,
			required_size,
			NULL,
			NULL);

		if (!res) {
			/* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
			   Continue to the next device. */
			goto cont;
		}

		/* Make sure this device is of Setup Class "HIDClass" and has a
		   driver bound to it. */
		for (i = 0; ; i++) {
			char driver_name[256];

			/* Populate devinfo_data. This function will return failure
			   when there are no more interfaces left. */
			res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
			if (!res)
				goto cont;

			res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
			               SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
			if (!res)
				goto cont;

			if (strcmp(driver_name, "HIDClass") == 0) {
				/* See if there's a driver bound. */
				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
				           SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
				if (res)
					break;
			}
		}

		//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);

		/* Open a handle to the device */
		write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);

		/* Check validity of write_handle. */
		if (write_handle == INVALID_HANDLE_VALUE) {
			/* Unable to open the device. */
			//register_error(dev, "CreateFile");
			goto cont_close;
		}


		/* Get the Vendor ID and Product ID for this device. */
		attrib.Size = sizeof(HIDD_ATTRIBUTES);
		HidD_GetAttributes(write_handle, &attrib);
		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);

		/* Check the VID/PID to see if we should add this
		   device to the enumeration list. */
		if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
		    (product_id == 0x0 || attrib.ProductID == product_id)) {

			#define WSTR_LEN 512
			const char *str;
			struct hid_device_info *tmp;
			PHIDP_PREPARSED_DATA pp_data = NULL;
			HIDP_CAPS caps;
			BOOLEAN res;
			NTSTATUS nt_res;
			wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
			size_t len;

			/* VID/PID match. Create the record. */
			tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;

			/* Get the Usage Page and Usage for this device. */
			res = HidD_GetPreparsedData(write_handle, &pp_data);
			if (res) {
				nt_res = HidP_GetCaps(pp_data, &caps);
				if (nt_res == HIDP_STATUS_SUCCESS) {
					cur_dev->usage_page = caps.UsagePage;
					cur_dev->usage = caps.Usage;
				}

				HidD_FreePreparsedData(pp_data);
			}

			/* Fill out the record */
			cur_dev->next = NULL;
			str = device_interface_detail_data->DevicePath;
			if (str) {
				len = strlen(str);
				cur_dev->path = (char*) calloc(len+1, sizeof(char));
				strncpy(cur_dev->path, str, len+1);
				cur_dev->path[len] = '\0';
			}
			else
				cur_dev->path = NULL;

			/* Serial Number */
			res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->serial_number = _wcsdup(wstr);
			}

			/* Manufacturer String */
			res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->manufacturer_string = _wcsdup(wstr);
			}

			/* Product String */
			res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->product_string = _wcsdup(wstr);
			}

			/* VID/PID */
			cur_dev->vendor_id = attrib.VendorID;
			cur_dev->product_id = attrib.ProductID;

			/* Release Number */
			cur_dev->release_number = attrib.VersionNumber;

			/* Interface Number. It can sometimes be parsed out of the path
			   on Windows if a device has multiple interfaces. See
			   http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
			   search for "Hardware IDs for HID Devices" at MSDN. If it's not
			   in the path, it's set to -1. */
			cur_dev->interface_number = -1;
			if (cur_dev->path) {
				char *interface_component = strstr(cur_dev->path, "&mi_");
				if (interface_component) {
					char *hex_str = interface_component + 4;
					char *endptr = NULL;
					cur_dev->interface_number = strtol(hex_str, &endptr, 16);
					if (endptr == hex_str) {
						/* The parsing failed. Set interface_number to -1. */
						cur_dev->interface_number = -1;
					}
				}
			}
		}

cont_close:
		CloseHandle(write_handle);
cont:
		/* We no longer need the detail data. It can be freed */
		free(device_interface_detail_data);

		device_index++;

	}

	/* Close the device information handle. */
	SetupDiDestroyDeviceInfoList(device_info_set);

	return root;

}
static void ParseRawInput(PRAWINPUT pRawInput)
{
    //IwDebugTraceLinePrintf("%s(%d): Parsing raw input\n", __FUNCTION__, __LINE__);
    PHIDP_PREPARSED_DATA pPreparsedData;
    HIDP_CAPS            Caps;
    PHIDP_BUTTON_CAPS    pButtonCaps;
    PHIDP_VALUE_CAPS     pValueCaps;
    USHORT               capsLength;
    UINT                 bufferSize;
    HANDLE               hHeap;
    USAGE                usage[MAX_BUTTONS];
    ULONG                i, usageLength, value;

    pPreparsedData = NULL;
    pButtonCaps    = NULL;
    pValueCaps     = NULL;
    hHeap          = GetProcessHeap();

    //
    // Get the preparsed data block
    //

    CHECK( GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0 );
    CHECK( pPreparsedData = (PHIDP_PREPARSED_DATA)HeapAlloc(hHeap, 0, bufferSize) );
    CHECK( (int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0 );

    //
    // Get the joystick's capabilities
    //

    // Button caps
    CHECK( HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS )
        CHECK( pButtonCaps = (PHIDP_BUTTON_CAPS)HeapAlloc(hHeap, 0, sizeof(HIDP_BUTTON_CAPS) * Caps.NumberInputButtonCaps) );

    capsLength = Caps.NumberInputButtonCaps;
    CHECK( HidP_GetButtonCaps(HidP_Input, pButtonCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )
        g_NumberOfButtons = pButtonCaps->Range.UsageMax - pButtonCaps->Range.UsageMin + 1;

    // Value caps
    CHECK( pValueCaps = (PHIDP_VALUE_CAPS)HeapAlloc(hHeap, 0, sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps) );
    capsLength = Caps.NumberInputValueCaps;
    CHECK( HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )

    //
    // Get the pressed buttons
    //

    usageLength = g_NumberOfButtons;
    CHECK(
        HidP_GetUsages(
        HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
        (PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
        ) == HIDP_STATUS_SUCCESS );

    ZeroMemory(bButtonStates, sizeof(bButtonStates));
    for(i = 0; i < usageLength; i++)
        bButtonStates[usage[i] - pButtonCaps->Range.UsageMin] = TRUE;

    //
    // Get the state of discrete-valued-controls
    //
//#define VALUES_DEBUG
#ifdef VALUES_DEBUG
    char str[512] = "";
#endif

    for(i = 0; i < Caps.NumberInputValueCaps; i++)
    {
        CHECK(
            HidP_GetUsageValue(
            HidP_Input, pValueCaps[i].UsagePage, 0, pValueCaps[i].Range.UsageMin, &value, pPreparsedData,
            (PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
            ) == HIDP_STATUS_SUCCESS );

        // NOTE: These values are only correct for the Xbox 360 controller 
        // and for the PS3 Controller (via MotioninJoy '360 Emulation' mode)
        switch(pValueCaps[i].Range.UsageMin)
        {
        case 0x30:	// X-axis (L-Stick Horizontal)
            lAxisX = (LONG)value;
            break;

        case 0x31:	// Y-axis (L-Stick Vertical)
            lAxisY = (LONG)value;
            break;

        case 0x32: // Z-axis (L-Trigger: 32K-65K, R-Trigger: 0K-32K)
            lAxisZ = (LONG)value;
            break;

        case 0x33: // U-axis (R-Stick Horizontal)
            lAxisU = (LONG)value;
            break;

        case 0x34: // R-axis (R-Stick Vertical)
            lAxisR = (LONG)value;
            break;

        // POV Hat Switch (DPAD:
        // 1: Up
        // 2: UP/RIGHT
        // 3: RIGHT
        // 4: RIGHT/DOWN
        // 5: DOWN
        // 6: DOWN/LEFT
        // 7: LEFT
        // 8: LEFT/UP
        case 0x39:
            lDPad = (LONG)value;
            break;
        }

#ifdef VALUES_DEBUG
        char s[128];
        _snprintf(s, 128, "[Usage=0x%2X, Val=%4u] ", pValueCaps[i].Range.UsageMin, value);
        strcat(str, s);
#endif
    }


    //
    // Clean up
    //

Error:
    SAFE_FREE(pPreparsedData);
    SAFE_FREE(pButtonCaps);
    SAFE_FREE(pValueCaps);
}
예제 #23
0
파일: hid.cpp 프로젝트: rombust/UICore
	NTSTATUS Hid::GetCaps(void *PreparsedData, CAPS *caps)
	{
		return HidP_GetCaps(PreparsedData, caps);
	}
예제 #24
0
bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
	MSG *msg = static_cast<MSG *>(message);
	if (msg->message == WM_INPUT && false)
	{
		UINT dwSize;

		GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, NULL, &dwSize,
			sizeof(RAWINPUTHEADER));
		LPBYTE lpb = new BYTE[dwSize];
		if (lpb == NULL)
		{
			return 0;
		}

		if (GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, lpb, &dwSize,
			sizeof(RAWINPUTHEADER)) != dwSize)
			OutputDebugString(TEXT("GetRawInputData does not return correct size !\n"));

		RAWINPUT* raw = (RAWINPUT*)lpb;

		if (raw->header.dwType == RIM_TYPEKEYBOARD)
		{
			MessageBox(NULL, L"Test", L"Test", MB_OK);
		}
		if (raw->header.dwType == RIM_TYPEHID)
		{
			UINT bufferSize;
			GetRawInputDeviceInfo(raw->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize);
			LPBYTE deviceInfo = new BYTE[bufferSize];

			//Add check for allocation


			//Get the HID preparsed data
			GetRawInputDeviceInfo(raw->header.hDevice, RIDI_PREPARSEDDATA, deviceInfo, &bufferSize);
			PHIDP_PREPARSED_DATA deviceInfoData = (PHIDP_PREPARSED_DATA)deviceInfo;
			HIDP_CAPS caps;
			HidP_GetCaps(deviceInfoData, &caps);

			LPBYTE ButtonCapsBuf = new BYTE[sizeof(HIDP_BUTTON_CAPS) * caps.NumberInputButtonCaps];
			//Add check for allocation

			//Get the button capabilities from HID
			PHIDP_BUTTON_CAPS ButtonCaps = (PHIDP_BUTTON_CAPS)ButtonCapsBuf;
			USHORT capsLength = caps.NumberInputButtonCaps;
			HidP_GetButtonCaps(HidP_Input, ButtonCaps, &capsLength, deviceInfoData);


			LPBYTE ValCapsBuf = new BYTE[sizeof(HIDP_BUTTON_CAPS) * caps.NumberInputValueCaps];

			//Find the current button usage data from HID device
			USAGE usage[128];
			ULONG usageLength = ButtonCaps->Range.UsageMax - ButtonCaps->Range.UsageMin + 1;
			HidP_GetUsages(HidP_Input, ButtonCaps->UsagePage, 0, usage, &usageLength, deviceInfoData, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);


			GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, NULL, &bufferSize);
			LPBYTE deviceNameInfoBuf = new BYTE[sizeof(wchar_t) * bufferSize];

			//Add check for allocation


			//Get the HID Name
			GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, deviceNameInfoBuf, &bufferSize);

			wchar_t DeviceName[127];
			HANDLE HIDHandle = CreateFile((LPCWSTR)deviceNameInfoBuf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
			if (HIDHandle)
			{
				HidD_GetProductString(HIDHandle, DeviceName, sizeof(wchar_t) * 126);
				CloseHandle(HIDHandle);
				for (int i = 0; i < usageLength; i++)
				{
					MessageBox(NULL, boost::lexical_cast<std::wstring>(usage[i] - ButtonCaps->Range.UsageMin).c_str(), std::wstring(DeviceName).c_str(), MB_OK);
				}
			}


			//Clean up byte arrays;
			delete[] deviceNameInfoBuf;
			delete[] ValCapsBuf;
			delete[] ButtonCapsBuf;
			delete[] deviceInfo;
		}

		//Clean up byte arrays;
		delete[] lpb;
		return true;
	}

	return false;
}
예제 #25
0
파일: vfeature.c 프로젝트: kcrazy/winekit
NTSTATUS
FireflySetFeature(
    IN  PDEVICE_CONTEXT DeviceContext,
    IN  UCHAR           PageId,
    IN  USHORT          FeatureId,
    IN  BOOLEAN         EnableFeature
    )
/*++

Routine Description:

    This routine sets the HID feature by sending HID ioctls to our device.
    These IOCTLs will be handled by HIDUSB and converted into USB requests
    and send to the device.

Arguments:

    DeviceContext - Context for our device

    PageID  - UsagePage of the light control feature.

    FeatureId - Usage ID of the feature.

    EnanbleFeature - True to turn the light on, Falst to turn if off.


Return Value:

    NT Status code

--*/
{
    WDF_MEMORY_DESCRIPTOR       inputDescriptor, outputDescriptor;
    NTSTATUS                    status;
    HID_COLLECTION_INFORMATION  collectionInformation = {0};
    PHIDP_PREPARSED_DATA        preparsedData;
    HIDP_CAPS                   caps;
    USAGE                       usage;
    ULONG                       usageLength;
    PCHAR                       report;
    WDFIOTARGET                 hidTarget;
    WDF_IO_TARGET_OPEN_PARAMS   openParams;

    PAGED_CODE();

    //
    // Preinit for error.
    //
    preparsedData = NULL;
    report = NULL;
    hidTarget = NULL;
    
    status = WdfIoTargetCreate(WdfObjectContextGetObject(DeviceContext), 
                            WDF_NO_OBJECT_ATTRIBUTES, 
                            &hidTarget);    
    if (!NT_SUCCESS(status)) {
        KdPrint(("FireFly: WdfIoTargetCreate failed 0x%x\n", status));        
        return status;
    }

    //
    // Open it up, write access only!
    //
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
                                    &openParams,
                                    &DeviceContext->PdoName,
                                    FILE_WRITE_ACCESS);

    //
    // We will let the framework to respond automatically to the pnp
    // state changes of the target by closing and opening the handle.
    //
    openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ;

    status = WdfIoTargetOpen(hidTarget, &openParams);
    if (!NT_SUCCESS(status)) {
        KdPrint(("FireFly: WdfIoTargetOpen failed 0x%x\n", status));                
        goto ExitAndFree;
    }
    

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor,
                                      (PVOID) &collectionInformation,
                                      sizeof(HID_COLLECTION_INFORMATION));

    //
    // Now get the collection information for this device
    //
    status = WdfIoTargetSendIoctlSynchronously(hidTarget,
                                  NULL,
                                  IOCTL_HID_GET_COLLECTION_INFORMATION,
                                  NULL,
                                  &outputDescriptor,
                                  NULL,
                                  NULL);

    if (!NT_SUCCESS(status)) {
        KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status));                
        goto ExitAndFree;
    }

    preparsedData = (PHIDP_PREPARSED_DATA) ExAllocatePoolWithTag(
        NonPagedPool, collectionInformation.DescriptorSize, 'ffly');

    if (preparsedData == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto ExitAndFree;
    }

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor,
                                      (PVOID) preparsedData,
                                      collectionInformation.DescriptorSize);

    status = WdfIoTargetSendIoctlSynchronously(hidTarget,
                                  NULL,
                                  IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
                                  NULL,
                                  &outputDescriptor,
                                  NULL,
                                  NULL);

    if (!NT_SUCCESS(status)) {
        KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status));                
        goto ExitAndFree;
    }

    //
    // Now get the capabilities.
    //
    RtlZeroMemory(&caps, sizeof(HIDP_CAPS));

    status = HidP_GetCaps(preparsedData, &caps);

    if (!NT_SUCCESS(status)) {

        goto ExitAndFree;
    }

    //
    // Create a report to send to the device.
    //
    report = (PCHAR) ExAllocatePoolWithTag(
        NonPagedPool, caps.FeatureReportByteLength, 'ffly');

    if (report == NULL) {
        goto ExitAndFree;
    }

    //
    // Start with a zeroed report. If we are disabling the feature, this might
    // be all we need to do.
    //
    RtlZeroMemory(report, caps.FeatureReportByteLength);
    status = STATUS_SUCCESS;

    if (EnableFeature) {

        //
        // Edit the report to reflect the enabled feature
        //
        usage = FeatureId;
        usageLength = 1;

        status = HidP_SetUsages(
            HidP_Feature,
            PageId,
            0,
            &usage, // pointer to the usage list
            &usageLength, // number of usages in the usage list
            preparsedData,
            report,
            caps.FeatureReportByteLength
            );
        if (!NT_SUCCESS(status)) {
            KdPrint(("FireFly: HidP_SetUsages failed 0x%x\n", status));                
            goto ExitAndFree;
        }
    }

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDescriptor,
                                      report,
                                      caps.FeatureReportByteLength);
    status = WdfIoTargetSendIoctlSynchronously(hidTarget,
                                  NULL,
                                  IOCTL_HID_SET_FEATURE,
                                  &inputDescriptor,
                                  NULL,
                                  NULL,
                                  NULL);
    if (!NT_SUCCESS(status)) {
        KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status));                
        goto ExitAndFree;
    }

ExitAndFree:

    if (preparsedData != NULL) {
        ExFreePool(preparsedData);
        preparsedData = NULL;
    }

    if (report != NULL) {
        ExFreePool(report);
        report = NULL;
    }

    if (hidTarget != NULL) {
        WdfObjectDelete(hidTarget);
    }

    return status;
}