예제 #1
0
파일: hid.c 프로젝트: bagong/hidapi
int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	BOOL res;

	res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * maxlen);
	if (!res) {
		register_error(dev, "HidD_GetManufacturerString");
		return -1;
	}

	return 0;
}
예제 #2
0
void HIDDeviceManager::initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const
{
    // Documentation mentions 126 as being the max for USB.
    wchar_t strBuffer[196];

    // HidD_Get*String functions return nothing in buffer on failure,
    // so it's ok to do this without further error checking.
    strBuffer[0] = 0;
    HidD_GetManufacturerString(hidDev, strBuffer, sizeof(strBuffer));
    desc->Manufacturer = strBuffer;

    strBuffer[0] = 0;
    HidD_GetProductString(hidDev, strBuffer, sizeof(strBuffer));
    desc->Product = strBuffer;

    strBuffer[0] = 0;
    HidD_GetSerialNumberString(hidDev, strBuffer, sizeof(strBuffer));
    desc->SerialNumber = strBuffer;
}
예제 #3
0
int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs)
{
GUID                                hidGuid;        /* GUID for HID driver */
HDEVINFO                            deviceInfoList;
SP_DEVICE_INTERFACE_DATA            deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA     *deviceDetails = NULL;
DWORD                               size;
int                                 i, openFlag = 0;  /* may be FILE_FLAG_OVERLAPPED */
int                                 errorCode = USB_ERROR_NOTFOUND;
HANDLE                              handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES                     deviceAttributes;
				
    HidD_GetHidGuid(&hidGuid);
    deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
    deviceInfo.cbSize = sizeof(deviceInfo);
    for(i=0;;i++){
        if(handle != INVALID_HANDLE_VALUE){
            CloseHandle(handle);
            handle = INVALID_HANDLE_VALUE;
        }
        if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
            break;  /* no more entries */
        /* first do a dummy call just to determine the actual size required */
        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
        if(deviceDetails != NULL)
            free(deviceDetails);
        deviceDetails = malloc(size);
        deviceDetails->cbSize = sizeof(*deviceDetails);
        /* this call is for real: */
        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL);
        DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
        /* attempt opening for R/W -- we don't care about devices which can't be accessed */
        handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);
        if(handle == INVALID_HANDLE_VALUE){
            DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
            /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
            continue;
        }
        deviceAttributes.Size = sizeof(deviceAttributes);
        HidD_GetAttributes(handle, &deviceAttributes);
        DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID));
        if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
            continue;   /* ignore this device */
        errorCode = USB_ERROR_NOTFOUND;
        if(vendorName != NULL && productName != NULL){
            char    buffer[512];
            if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
                DEBUG_PRINT(("error obtaining vendor name\n"));
                errorCode = USB_ERROR_IO;
                continue;
            }
            convertUniToAscii(buffer);
            DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
            if(strcmp(vendorName, buffer) != 0)
                continue;
            if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
                DEBUG_PRINT(("error obtaining product name\n"));
                errorCode = USB_ERROR_IO;
                continue;
            }
            convertUniToAscii(buffer);
            DEBUG_PRINT(("productName = \"%s\"\n", buffer));
            if(strcmp(productName, buffer) != 0)
                continue;
        }
        break;  /* we have found the device we are looking for! */
    }
    SetupDiDestroyDeviceInfoList(deviceInfoList);
    if(deviceDetails != NULL)
        free(deviceDetails);
    if(handle != INVALID_HANDLE_VALUE){
        *device = (usbDevice_t *)handle;
        errorCode = 0;
    }
    return errorCode;
}
예제 #4
0
파일: hid.cpp 프로젝트: rombust/UICore
	BOOLEAN Hid::GetManufacturerString(HANDLE HidDeviceObject, void *Buffer, ULONG BufferLength)
	{
		return HidD_GetManufacturerString(HidDeviceObject, Buffer, BufferLength);
	}
예제 #5
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;

}
예제 #6
0
파일: dbg_win.c 프로젝트: nandojve/edbg
//-----------------------------------------------------------------------------
int dbg_enumerate(debugger_t *debuggers, int size)
{
  GUID hid_guid;
  HDEVINFO hid_dev_info;
  HIDD_ATTRIBUTES hid_attr;
  SP_DEVICE_INTERFACE_DATA dev_info_data;
  PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data;
  DWORD detail_size;
  HANDLE handle;
  int rsize = 0;

  HidD_GetHidGuid(&hid_guid);

  hid_dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

  dev_info_data.cbSize = sizeof(dev_info_data);

  for (int i = 0; i < size; i++)
  {
    if (FALSE == SetupDiEnumDeviceInterfaces(hid_dev_info, 0, &hid_guid, i, &dev_info_data))
      break;

    SetupDiGetDeviceInterfaceDetail(hid_dev_info, &dev_info_data, NULL, 0,
        &detail_size, NULL);

    detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buf_alloc(detail_size);
    detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    SetupDiGetDeviceInterfaceDetail(hid_dev_info, &dev_info_data, detail_data,
        detail_size, NULL, NULL);

    handle = CreateFile(detail_data->DevicePath, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

    if (INVALID_HANDLE_VALUE != handle)
    {
      hid_attr.Size = sizeof(hid_attr);
      HidD_GetAttributes(handle, &hid_attr);

      if (DBG_VID == hid_attr.VendorID && DBG_PID == hid_attr.ProductID)
      {
        wchar_t wstr[MAX_STRING_SIZE];
        char str[MAX_STRING_SIZE];

        debuggers[rsize].path = strdup(detail_data->DevicePath);

        HidD_GetSerialNumberString(handle, (PVOID)wstr, MAX_STRING_SIZE);
        wcstombs(str, wstr, MAX_STRING_SIZE);
        debuggers[rsize].serial = strdup(str);

        HidD_GetManufacturerString(handle, (PVOID)wstr, MAX_STRING_SIZE);
        wcstombs(str, wstr, MAX_STRING_SIZE);
        debuggers[rsize].manufacturer = strdup(str);

        HidD_GetProductString(handle, (PVOID)wstr, MAX_STRING_SIZE);
        wcstombs(str, wstr, MAX_STRING_SIZE);
        debuggers[rsize].product = strdup(str);

        rsize++;
      }

      CloseHandle(handle);
    }

    buf_free(detail_data);
  }

  SetupDiDestroyDeviceInfoList(hid_dev_info);

  return rsize;
}
예제 #7
0
//------------------------------------------------------------------------------
HANDLE DNAUSB::openDevice( const int vid, const int pid, const char* vendor, char* product )
{
	HANDLE handle = INVALID_HANDLE_VALUE;

	// from DDK
	const GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };

	for( int tries = 0; (tries < 10) && (handle == INVALID_HANDLE_VALUE) ; tries++ )
	{
		HANDLE deviceSet = SetupDiGetClassDevs( &GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );

		if ( deviceSet == INVALID_HANDLE_VALUE )    
		{
			break;
		}    

		SP_INTERFACE_DEVICE_DATA interfaceInfo;    
		SP_DEVINFO_DATA deviceInfoData;
		interfaceInfo.cbSize = sizeof( interfaceInfo );
		deviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA );
		BYTE buf[1024];
		DWORD size;

		int i=0;
		if( SetupDiEnumDeviceInfo(deviceSet, i++, &deviceInfoData) )
		{
			DWORD interfaceNumber = 0;
			while ( SetupDiEnumDeviceInterfaces( deviceSet,
												 0, 
												 &GUID_DEVINTERFACE_HID,
												 interfaceNumber++,
												 &interfaceInfo) )
			{
				SP_DEVICE_INTERFACE_DETAIL_DATA *details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)buf;
				details->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);

				size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;

				if ( !SetupDiGetDeviceInterfaceDetail( deviceSet, 
													   &interfaceInfo,
													   details,
													   size,
													   0,
													   0 ) )
				{
					Log( "SetupDiGetDeviceInterfaceDetail failed [%d]", GetLastError() );
					continue;
				}

				Cstr temp;
				temp.toChar( details->DevicePath );
				temp.toLower();
				Log( "Considering [%s]", temp.c_str() );

				const char* vidStr = strstr( temp.c_str(), "vid" );
				if ( !vidStr )
				{
					Log( "vid not found [%s]", temp.c_str() );
					continue;
				}
				vidStr += 3;

				for( ; *vidStr && !isxdigit(*vidStr); vidStr++ );

				if ( !vidStr )
				{
					Log( "could not find valid vid [%s]", temp.c_str() );
					continue;
				}

				if ( strtol(vidStr, 0, 16) != vid )
				{
					continue;
				}

				const char* pidStr = strstr( temp.c_str(), "pid" );
				if ( !pidStr )
				{
					Log( "pid not found [%s]", temp.c_str() );
					continue;
				}
				pidStr += 3;

				for( ; *pidStr && !isxdigit(*pidStr); pidStr++ );

				if ( !pidStr )
				{
					Log( "could not find valid pid [%s]", temp.c_str() );
					continue;
				}

				if ( strtol(pidStr, 0, 16) != pid )
				{
					continue;
				}

				int openFlag = 0;  // may be FILE_FLAG_OVERLAPPED
				handle = CreateFile( details->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL );
				if ( handle == INVALID_HANDLE_VALUE )
				{
					Log( "could not open device" );
					continue;
				}

				if( !HidD_GetManufacturerString(handle, buf, 1024) )
				{
					CloseHandle( handle );
					handle = INVALID_HANDLE_VALUE;
					Log( "could not fetch manufacturer string" );
					continue;
				}

				temp.toChar( (wchar_t*)buf );
				Log( "manufacturer [%s]", temp.c_str() );

				if ( !temp.isMatch(vendor, false) )
				{
					CloseHandle( handle );
					handle = INVALID_HANDLE_VALUE;
					continue;
				}

				Sleep(10);

				if ( product )
				{
					HidD_GetProductString( handle, buf, 1024 );
					temp.toChar( (wchar_t*)buf );
					strcpy( product, temp.c_str() );
				}

				break;
			}
		}

		SetupDiDestroyDeviceInfoList( deviceSet );

		if ( handle == INVALID_HANDLE_VALUE )
		{
			Arch::sleep( 2000 );
		}
	}

	return handle;
}