Esempio n. 1
0
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 {
                if (print) {
                    ASYNC_PRINT_ERROR("HidP_GetCaps")
                }
                async_close(device);
                device = -1;
            }
            HidD_FreePreparsedData(preparsedData);
        }
        else {
            if (print) {
                ASYNC_PRINT_ERROR("HidD_GetPreparsedData")
            }
            async_close(device);
            device = -1;
        }
    }
void GetDeviceCapabilities(HANDLE DeviceHandle)
{
	//Get the Capabilities structure for the 

	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
		(DeviceHandle,
		 &PreparsedData);

	/*
	  API function: HidP_GetCaps
	  Learn the device's capabilities.
	  For standard devices such as joysticks, you can find out the specific
	  capabilities of the 
	  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,
		 &Capabilities);

	HidD_FreePreparsedData(PreparsedData);
}
Esempio n. 3
0
int hs_hid_parse_descriptor(hs_handle *h, hs_hid_descriptor *rdesc)
{
    assert(h);
    assert(h->dev->type == HS_DEVICE_TYPE_HID);
    assert(rdesc);

    // semi-hidden Hungarian pointers? Really , Microsoft?
    PHIDP_PREPARSED_DATA pp;
    HIDP_CAPS caps;
    LONG ret;

    ret = HidD_GetPreparsedData(h->handle, &pp);
    if (!ret)
        return hs_error(HS_ERROR_SYSTEM, "HidD_GetPreparsedData() failed");

    // NTSTATUS and BOOL are both defined as LONG
    ret = HidP_GetCaps(pp, &caps);
    HidD_FreePreparsedData(pp);
    if (ret != HIDP_STATUS_SUCCESS)
        return hs_error(HS_ERROR_SYSTEM, "Invalid HID descriptor");

    rdesc->usage_page = caps.UsagePage;
    rdesc->usage = caps.Usage;

    return 0;
}
USBHIDDLL_API			 bool bWrite_ToHIDDevice(PHANDLE pWriteHandle, LPBYTE lpWriteBuff){

				 DWORD			dwNumberOfBytesWrite;
				 HIDP_CAPS		Capabilities;
				 PHIDP_PREPARSED_DATA		HidParsedData;

				 BOOL bResult = false;

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

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

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

					 bResult = WriteFile(*pWriteHandle, 
						 lpWriteBuff, 
						 Capabilities.OutputReportByteLength, 
						 &dwNumberOfBytesWrite,
						 NULL);


				 }
				 return bResult;

			 }
Esempio n. 5
0
File: hid.c Progetto: bagong/hidapi
HID_API_EXPORT hid_device* HID_API_CALL hid_open_path(const char *path)
{
	hid_device *dev;
	HIDP_CAPS caps;
	PHIDP_PREPARSED_DATA pp_data = NULL;
	BOOLEAN res;
	NTSTATUS nt_res;

	if (hid_init() < 0) {
		return NULL;
	}

	dev = new_hid_device();

	/* Open a handle to the device */
	dev->device_handle = open_device(path, FALSE);

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

	/* Set the Input Report buffer size to 64 reports. */
	res = HidD_SetNumInputBuffers(dev->device_handle, 64);
	if (!res) {
		register_error(dev, "HidD_SetNumInputBuffers");
		goto err;
	}

	/* Get the Input Report length for the device. */
	res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
	if (!res) {
		register_error(dev, "HidD_GetPreparsedData");
		goto err;
	}

	nt_res = HidP_GetCaps(pp_data, &caps);
	if (nt_res != HIDP_STATUS_SUCCESS) {
		register_error(dev, "HidP_GetCaps");
		goto err_pp_data;
	}
	dev->output_report_length = caps.OutputReportByteLength;
	dev->input_report_length = caps.InputReportByteLength;
	HidD_FreePreparsedData(pp_data);

	dev->read_buf = (char*) malloc(dev->input_report_length);

	return dev;

err_pp_data:
		HidD_FreePreparsedData(pp_data);
err:
		free_hid_device(dev);
		return NULL;
}
Esempio n. 6
0
BOOLEAN SwitchLogitech( __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.OutputReportByteLength != sizeof(ToHCIReports[0]) )
	{
		HidD_FreePreparsedData(PreparsedData);
		return FALSE;
	}

	DWORD noReports = toHID ? sizeof(ToHCIReports) / sizeof(ToHCIReports[0]) :
		sizeof(ToHIDReports) / sizeof(ToHIDReports[0]);

	for (DWORD i = 0; i < noReports; i++ )
	{
		CHAR ReportBuffer[sizeof(ToHCIReports[0])];
		RtlCopyMemory( ReportBuffer, toHID ? ToHCIReports[i] : ToHIDReports[i], sizeof( ToHCIReports[0] ) );
		if (!HidD_SetOutputReport( hHidDevice, ReportBuffer, HidCaps.OutputReportByteLength ) )
		{
			LbtReportFunctionError( TEXT("HidD_SetOutputReport") );
			HidD_FreePreparsedData(PreparsedData);
			return FALSE;
		}
	}

	HidD_FreePreparsedData(PreparsedData);
	LbtReportDongleSwitch( lpDongleName, toHID );
	return TRUE;
}
Esempio n. 7
0
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 == vmultib_VID && Attributes.ProductID == vmultib_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;
}
Esempio n. 8
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);
}
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
/**
 * 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;
}
Esempio n. 13
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;
}
Esempio n. 14
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: ") ;
    }
}
Esempio n. 15
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);
}
Esempio n. 16
0
File: hid.c Progetto: 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;

}
Esempio n. 17
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;
}
Esempio n. 18
0
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);
}
Esempio n. 19
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;
}
Esempio n. 20
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;
}
Esempio n. 21
0
File: USBHID.c Progetto: 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;
}
Esempio n. 22
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;
			 }