Getting USB device name

Category: windows hardware wdk and driver development

Question

Rooney808 on Thu, 17 Jan 2019 08:52:02


What is 'devicename' format I need to put in the device name field?  Where do I find it?  I understand there are VID and PID numbers but what is the format?  I have the following code but keep getting an error.  I have spent hours researching this and have not yet come up with success.  

procedure OpenWinUSBDevice(deviceName: String);
var hDevice: THandle;
begin
    Info('Trying to open '+deviceName);
    hDevice := CreateFile(
      PChar(deviceName),
      GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
      nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0);
    if hDevice = INVALID_HANDLE_VALUE then begin
      Info('Cannot get a handle for the device. Perhaps it''s not attached.');
      Exit;
    end else begin
      Info('Device opened. Device handle is $'+inttohex(Integer(hDevice),8));
    end;
    Info('Obtaining WinUSB handle based on the device handle...');
    if WinUsb_Initialize(hDevice, hWinUsbHandle) then begin
      Info('WinUSB Init Ok. WinUSB handle is $'+inttohex(Integer(hWinUsbHandle),8));
    end else begin
      Info('WinUSB Init Failed.');
      Exit;
    end;

Replies

Don Burn [Windrvr] on Thu, 17 Jan 2019 13:19:39


You typically use the setup calls for a specific device GUID to get the data you need.   For instance, I used the code below on several projects.

static HRESULT GetDeviceHandle( __in LPGUID DeviceGuid )
{
	HRESULT								result;
	HDEVINFO							deviceInfo;
	SP_DEVINFO_DATA						deviceInfoData;
	SP_DEVICE_INTERFACE_DATA			deviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA	interfaceDetailData;
	ULONG								requiredLength;
	LPTSTR								devicePath;
	size_t								length;

	result = S_OK;
	interfaceDetailData = NULL;
	requiredLength = 0;
	devicePath = NULL;

	deviceInfo = SetupDiGetClassDevs( DeviceGuid, NULL,
		NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );

	if (deviceInfo == INVALID_HANDLE_VALUE)
	{
		result = E_HANDLE;
	}

	if (SUCCEEDED( result ))
	{
		// Check that a query for a second interface fails, but that the
		// first interface succeeds
		deviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA );
		if (!SetupDiEnumDeviceInfo( deviceInfo, 1, &deviceInfoData ) &&
			SetupDiEnumDeviceInfo( deviceInfo, 0, &deviceInfoData ))
		{

			// Get the specific device interface
			deviceInterfaceData.cbSize = sizeof( SP_INTERFACE_DEVICE_DATA );
			if (!SetupDiEnumDeviceInterfaces( deviceInfo, &deviceInfoData,
				DeviceGuid, 0, &deviceInterfaceData ))
			{
				DebugError( "FAILURE: SetupDiEnumDeviceInterfaces failed " );
				result = HRESULT_FROM_WIN32( GetLastError( ) );
			}

			// Check the size needed for the device interface details and 
			// allocate the data needed to get the details
			if (SUCCEEDED( result ) &&
				!SetupDiGetDeviceInterfaceDetail( deviceInfo,
				&deviceInterfaceData, NULL, 0, &requiredLength, NULL ))
			{
				if (GetLastError( ) == ERROR_INSUFFICIENT_BUFFER &&
					requiredLength > 0)
				{
					interfaceDetailData =
						(PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc( LPTR, (SIZE_T) requiredLength );
					if (interfaceDetailData == NULL)
					{
						result = E_OUTOFMEMORY;
					}
					else
					{
						result = S_OK;
					}
				}
				else
				{
					result = HRESULT_FROM_WIN32( GetLastError( ) );
				}
			}

			// Get the device interface details
			if (SUCCEEDED( result ) && interfaceDetailData != NULL)
			{
				interfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );
				if (!SetupDiGetDeviceInterfaceDetail( deviceInfo,
					&deviceInterfaceData, interfaceDetailData,
					requiredLength, NULL, &deviceInfoData ))
				{
					DebugError( "FAILURE: SetupDiGetDeviceInterfaceDetail failed" );
					result = HRESULT_FROM_WIN32( GetLastError( ) );
				}
			}
			if (SUCCEEDED( result ) && interfaceDetailData != NULL)
			{
				// Build the null terminated device path for the device
				length = _tcslen( interfaceDetailData->DevicePath ) + 1;
				devicePath = (TCHAR *)
					LocalAlloc( LPTR, length * sizeof( TCHAR ) );
				if (devicePath != NULL)
				{
					StringCchCopy( devicePath, length,
						interfaceDetailData->DevicePath );
					devicePath[ length - 1 ] = 0;
				}
				else
				{
					result = E_OUTOFMEMORY;
				}
			}
		}
	}

	if (SUCCEEDED( result ) && devicePath != NULL)
	{
		// Open the device handle
		DeviceHandle = CreateFile( devicePath, GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
		if (DeviceHandle == INVALID_HANDLE_VALUE)
		{
			DebugError( "FAILURE: CreateFile failed" );
			result = HRESULT_FROM_WIN32( GetLastError( ) );
		}
	}

	// Perform cleanup of the allocated data
	if (devicePath != NULL)
	{
		LocalFree( devicePath );
	}
	if (interfaceDetailData != NULL)
	{
		LocalFree( interfaceDetailData );
	}
	if (deviceInfo != INVALID_HANDLE_VALUE)
	{
		(void) SetupDiDestroyDeviceInfoList( deviceInfo );
	}
	return result;
}

Where DeviceHandle is a global that gets the handle you are looking for.