示例#1
1
bool getDeviceProperty(HDEVINFO devices, SP_DEVINFO_DATA& device_info, DWORD property, std::wstring& value)
{
	DWORD size = 8192;

	try
	{
		DWORD data_type;
		DWORD requested_size;
		LPTSTR buffer = new TCHAR[(size / sizeof(TCHAR)) + 1];
		memset(buffer, 0x00, (size / sizeof(TCHAR)) + 1);

		if (buffer)
		{
			bool success = true;

			while (!SetupDiGetDeviceRegistryProperty(devices, &device_info, property, &data_type, reinterpret_cast<LPBYTE>(buffer), size, &requested_size))
			{
				if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
				{
					success = false;
					break;
				}

				if (data_type != REG_SZ)
				{
					success = false;
					break;
				}

				size = requested_size;
				delete[] buffer;
				buffer = new TCHAR[(size / sizeof(TCHAR)) + 1];
				memset(buffer, 0x00, (size / sizeof(TCHAR)) + 1);

				if (!buffer)
				{
					success = false;
					break;
				}
			}

			if (success)
			{
				value = std::wstring(buffer);
			}

			delete[] buffer;

			return true;
		}
	}
	catch (...)
	{
		std::wcerr << "Allocation error. This is serious !" << std::endl;
	}

	return false;
}
void vm_sys_info_get_vga_card(vm_char *vga_card)
{
    SP_DEVINFO_DATA sp_dev_info;
    HDEVINFO DeviceInfoSet;
    vm_char string1[] = VM_STRING("Display");
    Ipp32u dwIndex = 0;
    vm_char data[_MAX_LEN] = {0,};

    /* check error(s) */
    if (NULL == vga_card)
        return;

    ZeroMemory(&sp_dev_info, sizeof(SP_DEVINFO_DATA));
    ZeroMemory(&DeviceInfoSet, sizeof(HDEVINFO));

    DeviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    sp_dev_info.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    while (SetupDiEnumDeviceInfo(DeviceInfoSet, dwIndex, &sp_dev_info))
    {
        SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
                                         &sp_dev_info,
                                         SPDRP_CLASS,
                                         NULL,
                                         (Ipp8u *) data,
                                         _MAX_LEN,
                                         NULL);
        if (!vm_string_strcmp((vm_char*)data, string1))
        {
            SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
                                             &sp_dev_info,
                                             SPDRP_DEVICEDESC,
                                             NULL,
                                             (PBYTE) vga_card,
                                             _MAX_LEN,
                                             NULL);
            break;
        }
        dwIndex++;
    }
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);

} /* void vm_sys_info_get_vga_card(vm_char *vga_card) */
BOOL ComPortDiscovery::QueryDeviceDescription(HDEVINFO hDevInfoSet, SP_DEVINFO_DATA& devInfo, ATL::CHeapPtr<BYTE>& byFriendlyName)
{
	DWORD dwType = 0;
	DWORD dwSize = 0;
	//Query initially to get the buffer size required
	if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, NULL, 0, &dwSize))
	{
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			return FALSE;
	}

#pragma warning(suppress: 6102)
	if (!byFriendlyName.Allocate(dwSize))
	{
		SetLastError(ERROR_OUTOFMEMORY);
		return FALSE;
	}

	return SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, byFriendlyName.m_pData, dwSize, &dwSize) && (dwType == REG_SZ);
}
示例#4
0
static BOOL GetDeviceRegistryProperty( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDeviceInfoData, DWORD dwProperty, CString& strProperty )
{
    BOOL bRet = TRUE;
    DWORD dwDataType = 0;
    LPTSTR pszBuf = NULL;
    DWORD dwBuffersize = 0;

    while ( !SetupDiGetDeviceRegistryProperty( hDevInfo, pDeviceInfoData, dwProperty, &dwDataType, ( PBYTE )pszBuf, dwBuffersize, &dwBuffersize ) )
    {
        if ( ERROR_INVALID_DATA == GetLastError() )
        {
            // 不存在 Device desc
            bRet = FALSE;
            break;
        }
        else if ( ERROR_INSUFFICIENT_BUFFER == GetLastError() )
        {
            // buffer size 不对
            if ( NULL != pszBuf )
            {
                LocalFree( LocalHandle( pszBuf ) );
                pszBuf = NULL;
            }

            pszBuf = ( LPTSTR )LocalAlloc( LPTR, dwBuffersize );
            if ( NULL == pszBuf )
            {
                bRet = FALSE;
                break;
            }
        }
        else
        {
            // 未知错误
            bRet = FALSE;
            break;
        }
    }

    if ( bRet )
    {
        strProperty = pszBuf;
    }

    if ( NULL != pszBuf )
    {
        LocalFree( LocalHandle( pszBuf ) );
        pszBuf = NULL;
    }

    return bRet;
}
示例#5
0
DWORD
GetDeviceConfigFlags(
    _In_ HDEVINFO         DeviceInfoSet,
    _In_ PSP_DEVINFO_DATA DeviceInfoData
    )
    
/*++

Routine Description:

    This routine retrieves the ConfigFlags registry property for the specified
    device info element, or zero if the property cannot be retrieved (e.g.,
    because ConfigFlags haven't yet been set by Found New Hardware process).

Arguments:

    DeviceInfoSet - Supplies a handle to the device information set containing
        the device of interest.
        
    DeviceInfoData - Supplies context of a device info element for which
        ConfigFlags is to be retrieved.

Return Value:

    If device's REG_DWORD ConfigFlags property can be retrieved, it is returned.
    Otherwise, zero is returned.

--*/

{
    DWORD ConfigFlags, RegDataType;
    
    if(!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
                                         DeviceInfoData,
                                         SPDRP_CONFIGFLAGS,
                                         &RegDataType,
                                         (PBYTE)&ConfigFlags,
                                         sizeof(ConfigFlags),
                                         NULL)
       || (RegDataType != REG_DWORD))
    {
        //
        // It's possible that this property isn't there, although we should
        // never enounter other problems like wrong datatype or data length
        // longer than sizeof(DWORD).  In any event, just return zero.
        //
        ConfigFlags = 0;
    }
    
    return ConfigFlags;
}
示例#6
0
BOOL CDeviceSetup::GetDevRegProperty(DWORD property, DWORD *ret)
{

	BOOL status=SetupDiGetDeviceRegistryProperty(m_hDevList,
												&m_devInfoData,
												property,
												0,
												(UCHAR *) ret,
												sizeof(DWORD),
												0);

	return status;
	
}
// 用于查找HID设备
USBHIDDLL_API bool __stdcall USBHIDFindUSBHIDDevice()
{
    GUID Guid;
    HidD_GetHidGuid(&Guid);

    void* info;
    info=SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
    if (info!=INVALID_HANDLE_VALUE) 
    {
        DWORD devIndex;
        SP_INTERFACE_DEVICE_DATA ifData;
        ifData.cbSize=sizeof(ifData);

        for (devIndex=0;SetupDiEnumDeviceInterfaces(info, NULL, &Guid, devIndex, &ifData);++devIndex)
        {
            DWORD needed;

            SetupDiGetDeviceInterfaceDetail(info, &ifData, NULL, 0, &needed, NULL);

            PSP_INTERFACE_DEVICE_DETAIL_DATA detail=(PSP_INTERFACE_DEVICE_DETAIL_DATA)new BYTE[needed];
            detail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
            SP_DEVINFO_DATA did={sizeof(SP_DEVINFO_DATA)};

            if (SetupDiGetDeviceInterfaceDetail(info, &ifData, detail, needed, NULL, &did))
            {
                // 查找特定设备 查到后则返回。
                if(strstr(detail->DevicePath, "vid_0483") != NULL)
                {
                    memset(GlobalUSBHIDDevicePath, '\0', sizeof(GlobalUSBHIDDevicePath));                 
                   memcpy(GlobalUSBHIDDevicePath, detail->DevicePath, strlen(detail->DevicePath));

                   if (!SetupDiGetDeviceRegistryProperty(info, &did, SPDRP_DEVICEDESC, NULL, 
                       (PBYTE)GlobalUSBHIDDeviceName, sizeof(GlobalUSBHIDDeviceName), NULL))
                   {
                       memset(GlobalUSBHIDDeviceName, '\0', sizeof(GlobalUSBHIDDeviceName));
                       char* hint = "(Unnamed HID device)";
                       memcpy(GlobalUSBHIDDeviceName,  hint, strlen(hint));
                   }

                   delete[] (PBYTE)detail;
                   SetupDiDestroyDeviceInfoList(info);    
                   return true;
                }
            }
            delete[] (PBYTE)detail; 
        }
        SetupDiDestroyDeviceInfoList(info);
    }
    return false;
}
示例#8
0
VOID EnumerateDiskDrives(
    _In_ PPH_DISK_ENUM_CALLBACK DiskEnumCallback,
    _In_opt_ PVOID Context
)
{
    HDEVINFO deviceInfoHandle;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = NULL;
    ULONG deviceInfoLength = 0;
    HANDLE ret_handle = NULL;

    if ((deviceInfoHandle = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE)
        return;

    for (ULONG i = 0; i < 1000; i++)
    {
        if (!SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData))
            break;

        if (SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterfaceData, 0, 0, &deviceInfoLength, &deviceInfoData) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            continue;

        deviceInterfaceDetail = PhAllocate(deviceInfoLength);
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        if (SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterfaceData, deviceInterfaceDetail, deviceInfoLength, &deviceInfoLength, &deviceInfoData))
        {
            WCHAR diskFriendlyName[MAX_PATH] = L"";

            SetupDiGetDeviceRegistryProperty(
                deviceInfoHandle,
                &deviceInfoData,
                SPDRP_FRIENDLYNAME,
                NULL,
                (PBYTE)diskFriendlyName,
                ARRAYSIZE(diskFriendlyName),
                NULL
            );

            DiskEnumCallback(deviceInterfaceDetail->DevicePath, diskFriendlyName, Context);
        }

        PhFree(deviceInterfaceDetail);
        deviceInterfaceDetail = NULL;
    }

    SetupDiDestroyDeviceInfoList(deviceInfoHandle);
}
示例#9
0
文件: cygwin_tap.c 项目: 0x0d/lrc
/* XXX */
static int ti_is_us(struct tip_cygwin *priv, HDEVINFO *hdi,
		    SP_DEVINFO_DATA *did)
{
	char buf[256];
	DWORD len = sizeof(buf), dt;

	if (priv) {} /* XXX unused */

	if (!SetupDiGetDeviceRegistryProperty(*hdi, did, SPDRP_DEVICEDESC, &dt,
					      (unsigned char*)buf, len, &len))
		return 0;

	if (dt != REG_SZ)
		return 0;

	return strstr(buf, "TAP-Win32") != NULL;
}
示例#10
0
文件: test1.c 项目: Kerd/tests
LPTSTR get_str_property(HDEVINFO hDevInfo, SP_DEVINFO_DATA* DeviceInfoData, DWORD prop)
{
        DWORD DataT;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;
        
        //
        // Call function with null to begin with, 
        // then use the returned buffer size (doubled)
        // to Alloc the buffer. Keep calling until
        // success or an unknown failure.
        //
        //  Double the returned buffersize to correct
        //  for underlying legacy CM functions that 
        //  return an incorrect buffersize value on 
        //  DBCS/MBCS systems.
        // 
        while (!SetupDiGetDeviceRegistryProperty(hDevInfo, DeviceInfoData,
            prop, &DataT,
            (PBYTE)buffer,
            buffersize,
            &buffersize))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                // Change the buffer size.
                if (buffer) LocalFree(buffer);
                // Double the size to avoid problems on 
                // W2k MBCS systems per KB 888609. 
                buffer = LocalAlloc(LPTR,buffersize * 2);

		if (!buffer)
		    return NULL;
            }
            else
            {
                // Insert error handling here.
		win32perror("SetupDiGetDeviceRegistryProperty()");
                if (buffer) LocalFree(buffer);
		return NULL;
            }
        }

	return buffer;
}
示例#11
0
bool WinNetCard::GetRegistryProperty(HDEVINFO DeviceInfoSet,   
	PSP_DEVINFO_DATA DeviceInfoData, 
	ULONG Property, 
	PVOID Buffer,
	PULONG Length)   
{   
	while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,   
		DeviceInfoData, Property, NULL, (BYTE *)*(TCHAR **)Buffer, *Length, Length))   
	{   
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)   
		{   
			if (*(LPTSTR *)Buffer) LocalFree(Buffer);   
			*(PCHAR *)Buffer = (PCHAR)LocalAlloc(LPTR,*Length);   
		}   
		else return false;   
	}   
	return (*(LPTSTR *)Buffer)[0];
}
示例#12
0
BOOL CDeviceSetup::GetDevRegProperty(DWORD property, std::string& ret)
{
	
	UCHAR buf[1024];
	BOOL status=SetupDiGetDeviceRegistryProperty(m_hDevList,
												&m_devInfoData,
												property,
												0,
												buf,
												sizeof(buf),
												0);

	if(status==0)
	{
		DWORD err=GetLastError();
		return 0;
	}
	
	ret=(const char*) buf;
	return 1;
}
示例#13
0
文件: winutil.c 项目: Eksmo/calibre
static LPTSTR
get_registry_property(HDEVINFO hDevInfo, DWORD index, DWORD property, BOOL *iterate) {
    /* Get a the property specified by `property` from the registry for the
     * device enumerated by `index` in the collection `hDevInfo`. `iterate`
     * will be set to `FALSE` if `index` points outside `hDevInfo`.
     * :return: A string allocated on the heap containing the property or
     *          `NULL` if an error occurred.
     */
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD DataT;
    LPTSTR buffer = NULL;
    DWORD buffersize = 0;
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) {
        *iterate = FALSE;
        return NULL;
    }

    while(!SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &DeviceInfoData,
            property,
            &DataT,
            (PBYTE)buffer,
            buffersize,
            &buffersize)) {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                buffer = (LPTSTR)PyMem_Malloc(2*buffersize); // Twice for bug in Win2k
            } else {
            	PyMem_Free(buffer);
            	PyErr_SetFromWindowsErr(0);
                buffer = NULL;
                break;
            }
    } //while

    return buffer;
}
示例#14
0
static wxString GetDiPropStr(HDEVINFO h, SP_DEVINFO_DATA *data, const wxString& key)
{
    wxString val;

    WCHAR buf[4096];
    DWORD size = sizeof(buf);
    DWORD proptype;
    if (SetupDiGetDeviceRegistryProperty(h, data, SPDRP_DRIVER, &proptype, (PBYTE)&buf[0], size, &size))
    {
        wxRegKey k(wxString("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\") + buf);
        if (!QueryValue(k, key, val))
        {
            Debug.AddLine("SSAG failed to get " + key + " driver property value");
        }
    }
    else
    {
        Debug.AddLine("SSAG failed to get SDRP_DRIVER registry property for SSAG");
    }

    return val;
}
示例#15
0
文件: system.cpp 项目: zfhrp6/rockbox
/** @brief detect devices based on usb pid / vid.
 *  @return list with usb VID / PID values.
 */
QMap<uint32_t, QString> System::listUsbDevices(void)
{
    QMap<uint32_t, QString> usbids;
    // usb pid detection
    LOG_INFO() << "Searching for USB devices";
#if defined(Q_OS_LINUX)
#if defined(LIBUSB1)
    libusb_device **devs;
    if(libusb_init(NULL) != 0) {
        LOG_ERROR() << "Initializing libusb-1 failed.";
        return usbids;
    }

    if(libusb_get_device_list(NULL, &devs) < 1) {
        LOG_ERROR() << "Error getting device list.";
        return usbids;
    }
    libusb_device *dev;
    int i = 0;
    while((dev = devs[i++]) != NULL) {
        QString name;
        unsigned char buf[256];
        uint32_t id;
        struct libusb_device_descriptor descriptor;
        if(libusb_get_device_descriptor(dev, &descriptor) == 0) {
            id = descriptor.idVendor << 16 | descriptor.idProduct;

            libusb_device_handle *dh;
            if(libusb_open(dev, &dh) == 0) {
                libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256);
                name += QString::fromLatin1((char*)buf) + " ";
                libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256);
                name += QString::fromLatin1((char*)buf);
                libusb_close(dh);
            }
            if(name.isEmpty())
                name = tr("(no description available)");
            if(id) {
                usbids.insertMulti(id, name);
                LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data());
            }
        }
    }

    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);
#else
    usb_init();
    usb_find_busses();
    usb_find_devices();
    struct usb_bus *b;
    b = usb_busses;

    while(b) {
        if(b->devices) {
            struct usb_device *u;
            u = b->devices;
            while(u) {
                uint32_t id;
                id = u->descriptor.idVendor << 16 | u->descriptor.idProduct;
                // get identification strings
                usb_dev_handle *dev;
                QString name;
                char string[256];
                int res;
                dev = usb_open(u);
                if(dev) {
                    if(u->descriptor.iManufacturer) {
                        res = usb_get_string_simple(dev, u->descriptor.iManufacturer,
                                                    string, sizeof(string));
                        if(res > 0)
                            name += QString::fromLatin1(string) + " ";
                    }
                    if(u->descriptor.iProduct) {
                        res = usb_get_string_simple(dev, u->descriptor.iProduct,
                                                    string, sizeof(string));
                        if(res > 0)
                            name += QString::fromLatin1(string);
                    }
                    usb_close(dev);
                }
                if(name.isEmpty()) name = tr("(no description available)");

                if(id) {
                    usbids.insertMulti(id, name);
                    LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name;
                }
                u = u->next;
            }
        }
        b = b->next;
    }
#endif
#endif

#if defined(Q_OS_MACX)
    kern_return_t result = KERN_FAILURE;
    CFMutableDictionaryRef usb_matching_dictionary;
    io_iterator_t usb_iterator = IO_OBJECT_NULL;
    usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName);
    result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary,
                                          &usb_iterator);
    if(result) {
        LOG_ERROR() << "USB: IOKit: Could not get matching services.";
        return usbids;
    }

    io_object_t usbCurrentObj;
    while((usbCurrentObj = IOIteratorNext(usb_iterator))) {
        uint32_t id;
        QString name;
        /* get vendor ID */
        CFTypeRef vidref = NULL;
        int vid = 0;
        vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"),
                                kCFAllocatorDefault, 0);
        CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid);
        CFRelease(vidref);

        /* get product ID */
        CFTypeRef pidref = NULL;
        int pid = 0;
        pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"),
                                kCFAllocatorDefault, 0);
        CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid);
        CFRelease(pidref);
        id = vid << 16 | pid;

        /* get product vendor */
        char vendor_buf[256];
        CFIndex vendor_buflen = 256;
        CFTypeRef vendor_name_ref = NULL;

        vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
                                 kIOServicePlane, CFSTR("USB Vendor Name"),
                                 kCFAllocatorDefault, 0);
        if(vendor_name_ref != NULL) {
            CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen,
                               kCFStringEncodingUTF8);
            name += QString::fromUtf8(vendor_buf) + " ";
            CFRelease(vendor_name_ref);
        }
        else {
            name += QObject::tr("(unknown vendor name) ");
        }

        /* get product name */
        char product_buf[256];
        CFIndex product_buflen = 256;
        CFTypeRef product_name_ref = NULL;

        product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
                                kIOServicePlane, CFSTR("USB Product Name"),
                                kCFAllocatorDefault, 0);
        if(product_name_ref != NULL) {
            CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen,
                               kCFStringEncodingUTF8);
            name += QString::fromUtf8(product_buf);
            CFRelease(product_name_ref);
        }
        else {
            name += QObject::tr("(unknown product name)");
        }

        if(id) {
            usbids.insertMulti(id, name);
            LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name;
        }

    }
    IOObjectRelease(usb_iterator);
#endif

#if defined(Q_OS_WIN32)
    HDEVINFO deviceInfo;
    SP_DEVINFO_DATA infoData;
    DWORD i;

    // Iterate over all devices
    // by doing it this way it's unneccessary to use GUIDs which might be not
    // present in current MinGW. It also seemed to be more reliably than using
    // a GUID.
    // See KB259695 for an example.
    deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);

    infoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) {
        DWORD data;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;
        QString description;

        // get device descriptor first
        // for some reason not doing so results in bad things (tm)
        while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
            SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) {
            if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                if(buffer) free(buffer);
                // double buffer size to avoid problems as per KB888609
                buffer = (LPTSTR)malloc(buffersize * 2);
            }
            else {
                break;
            }
        }
        if(!buffer) {
            LOG_WARNING() << "Got no device description"
                          << "(SetupDiGetDeviceRegistryProperty), item" << i;
            continue;
        }
        description = QString::fromWCharArray(buffer);

        // now get the hardware id, which contains PID and VID.
        while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
            SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) {
            if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                if(buffer) free(buffer);
                // double buffer size to avoid problems as per KB888609
                buffer = (LPTSTR)malloc(buffersize * 2);
            }
            else {
                break;
            }
        }

        if(buffer) {
            // convert buffer text to upper case to avoid depending on the case of
            // the keys (W7 uses different casing than XP at least), in addition
            // XP may use "Vid_" and "Pid_".
            QString data = QString::fromWCharArray(buffer).toUpper();
            QRegExp rex("USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4}).*");
            if(rex.indexIn(data) >= 0) {
                uint32_t id;
                id = rex.cap(1).toUInt(0, 16) << 16 | rex.cap(2).toUInt(0, 16);
                usbids.insert(id, description);
                LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16);
            }
            free(buffer);
        }
    }
    SetupDiDestroyDeviceInfoList(deviceInfo);

#endif
    return usbids;
}
示例#16
0
void EnumSerialPortsWindows(std::vector<SerialPortInfo> &serialports)
{
	// Create a device information set that will be the container for 
	// the device interfaces.
	GUID *guidDev = (GUID*)&GUID_CLASS_COMPORT;

	HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
	SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;

	try {
		hDevInfo = SetupDiGetClassDevs(guidDev,
			NULL,
			NULL,
			DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
			);

		if (hDevInfo == INVALID_HANDLE_VALUE)
		{
			return;
		}

		// Enumerate the serial ports
		BOOL bOk = TRUE;
		SP_DEVICE_INTERFACE_DATA ifcData;
		DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
		pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
		// This is required, according to the documentation. Yes,
		// it's weird.
		ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		for (DWORD ii = 0; bOk; ii++) {
			bOk = SetupDiEnumDeviceInterfaces(hDevInfo,
				NULL, guidDev, ii, &ifcData);
			if (bOk) {
				// Got a device. Get the details.
				SP_DEVINFO_DATA devdata = { sizeof(SP_DEVINFO_DATA) };
				bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
					&ifcData, pDetData, dwDetDataSize, NULL, &devdata);
				if (bOk) {
					std::string strDevPath(pDetData->DevicePath);
					// Got a path to the device. Try to get some more info.
					TCHAR fname[256];
					TCHAR desc[256];
					BOOL bSuccess = SetupDiGetDeviceRegistryProperty(
						hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
						(PBYTE)fname, sizeof(fname), NULL);
					bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(
						hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
						(PBYTE)desc, sizeof(desc), NULL);
					BOOL bUsbDevice = FALSE;
					TCHAR locinfo[256];
					if (SetupDiGetDeviceRegistryProperty(
						hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,
						(PBYTE)locinfo, sizeof(locinfo), NULL))
					{
						// Just check the first three characters to determine
						// if the port is connected to the USB bus. This isn't
						// an infallible method; it would be better to use the
						// BUS GUID. Currently, Windows doesn't let you query
						// that though (SPDRP_BUSTYPEGUID seems to exist in
						// documentation only).
						bUsbDevice = (strncmp(locinfo, "USB", 3) == 0);
					}
					// Open device parameters reg key - Added after fact from post on CodeGuru - credit to Peter Wurmsdobler
					HKEY hKey = SetupDiOpenDevRegKey
						(hDevInfo, &devdata, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);

					TCHAR szPortName[MAX_PATH];
					if (hKey)
					{
						DWORD dwType = REG_SZ;
						DWORD dwReqSize = sizeof(szPortName);

						// Query for portname
						long lRet = RegQueryValueEx
							(hKey, "PortName", 0, &dwType, (LPBYTE)&szPortName, &dwReqSize);
						if (lRet == ERROR_SUCCESS)
							bSuccess &= TRUE;
						else
							bSuccess &= FALSE;
					}
					else
						bSuccess &= FALSE;

					if (bSuccess) {
						// Add an entry to the array
						SerialPortInfo si;
						si.szDevPath = strDevPath;
						si.szFriendlyName = fname;
						si.szPortName = szPortName;
						si.szPortDesc = desc;
						si.bUsbDevice = (bUsbDevice==TRUE);
						serialports.push_back(si);
					}

				}
				else {
					return;
				}
			}
			else {
				DWORD err = GetLastError();
				if (err != ERROR_NO_MORE_ITEMS) {
					return;
				}
			}
		}
	}
	catch (...)
	{
	}

	if (pDetData != NULL)
		delete[](char*)pDetData;
	if (hDevInfo != INVALID_HANDLE_VALUE)
		SetupDiDestroyDeviceInfoList(hDevInfo);
}
示例#17
0
static unsigned int GetSSAGDriverVersion()
{
    // check to see if the SSAG driver is v2 ("1.2.0.0") or v4 ("3.0.0.0")

    Debug.AddLine("Checking SSAG driver version");

    bool found = false;
    unsigned int driverVersion = 2; // assume v2

    HDEVINFO h = SetupDiGetClassDevs(NULL, L"USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (h != INVALID_HANDLE_VALUE)
    {
        DWORD idx = 0;
        SP_DEVINFO_DATA data;
        memset(&data, 0, sizeof(data));
        data.cbSize = sizeof(data);

        while (SetupDiEnumDeviceInfo(h, idx, &data))
        {
#if DONE_SUPPORTING_XP
            WCHAR buf[4096];

            if (GetDiPropStr(h, &data, DEVPKEY_Device_InstanceId, buf, sizeof(buf)) &&
                (wcsncmp(buf, L"USB\\VID_1856&PID_0012\\", 22) == 0) ||
                (wcsncmp(buf, L"USB\\VID_1856&PID_0011\\", 22) == 0))
            {
                Debug.AddLine(wxString::Format("Found SSAG device %s", buf));
                if (GetDiPropStr(h, &data, DEVPKEY_Device_DriverVersion, buf, sizeof(buf)))
                {
                    Debug.AddLine(wxString::Format("SSAG driver version is %s", wxString(buf)));
                    int v;
                    if (swscanf(buf, L"%d", &v) == 1 && v >= 3)
                    {
                        driverVersion = 4;
                    }
                }
                found = true;
                break;
            }
#else
            WCHAR buf[4096];
            DWORD size = sizeof(buf);
            DWORD proptype;

            if (SetupDiGetDeviceRegistryProperty(h, &data, SPDRP_HARDWAREID, &proptype, (PBYTE)&buf[0], size, &size) &&
                (wcsncmp(buf, L"USB\\VID_1856&PID_0012", 21) == 0 ||
                 wcsncmp(buf, L"USB\\VID_1856&PID_0011", 21) == 0))
            {
                Debug.AddLine(wxString::Format("Found SSAG device %s", buf));
                wxString ver = GetDiPropStr(h, &data, "DriverVersion");
                if (ver.Length())
                {
                    Debug.AddLine(wxString::Format("SSAG driver version is %s", ver));
                    int v;
                    if (wxSscanf(ver, "%d", &v) == 1 && v >= 3)
                    {
                        driverVersion = 4;
                    }
                }
                found = true;
                break;
            }
#endif // XP

            ++idx;
        }

        SetupDiDestroyDeviceInfoList(h);
    }

    if (!found)
        Debug.AddLine("No SSAG device was found");

    return driverVersion;
}
示例#18
0
/**
 * Install the VBox video driver.
 *
 * @returns TRUE on success.
 * @returns FALSE on failure.
 * @param   szDriverDir     The base directory where we find the INF.
 */
BOOL installVideoDriver(TCHAR* szDriverDir)
{
  HDEVINFO hDevInfo;
  SP_DEVINSTALL_PARAMS DeviceInstallParams={0};
  SP_DRVINFO_DATA drvInfoData={0};
  SP_DRVINFO_DETAIL_DATA DriverInfoDetailData={0};

  DWORD cbReqSize;

  /* Vars used for reading the INF */
  HINF hInf;
  TCHAR szServiceSection[LINE_LEN];
  INFCONTEXT serviceContext;
  TCHAR szServiceData[LINE_LEN];
  TCHAR deviceRegStr[1000];//I'm lazy here. 1000 ought to be enough for everybody...

  SP_DEVINFO_DATA deviceInfoData;
  DWORD configFlags;

  HKEY hkey;
  DWORD disp;
  TCHAR regKeyName[LINE_LEN];

  BOOL rc;

  /* Create an empty list */
  hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DEVCLASS_DISPLAY,
                                         NULL);

  if (hDevInfo == INVALID_HANDLE_VALUE)
    return FALSE;

  memset(&DeviceInstallParams, 0, sizeof(SP_DEVINSTALL_PARAMS));
  DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

  rc=SetupDiGetDeviceInstallParams(hDevInfo,
                                   NULL,
                                   &DeviceInstallParams);

  if(!rc)
    return FALSE;

  DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  DeviceInstallParams.Flags |= DI_NOFILECOPY | /* We did our own file copying */
    DI_DONOTCALLCONFIGMG |
    DI_ENUMSINGLEINF; /* .DriverPath specifies an inf file */


  /* Path to inf file */
  wsprintf(DeviceInstallParams.DriverPath,
           TEXT("%ws\\%ws"),
           szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));

  rc=SetupDiSetDeviceInstallParams(hDevInfo,
                                   NULL,
                                   &DeviceInstallParams);
  if(!rc)
    return FALSE;

  /* Read the drivers from the inf file */
  if (!SetupDiBuildDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER))
    {
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  /* Get the first found driver.
     Our Inf file only contains one so this is fine  */
  drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  if(FALSE==SetupDiEnumDriverInfo(hDevInfo, NULL, SPDIT_CLASSDRIVER,
                                  0, &drvInfoData)){
    SetupDiDestroyDeviceInfoList(hDevInfo);
    return FALSE;
  }

  /* Get necessary driver details */
  DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  if (!(!SetupDiGetDriverInfoDetail(hDevInfo,
                                    NULL,
                                    &drvInfoData,
                                    &DriverInfoDetailData,
                                    DriverInfoDetailData.cbSize,
                                    &cbReqSize)
        &&GetLastError()== ERROR_INSUFFICIENT_BUFFER) )
    {
      SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
                          NULL, INF_STYLE_WIN4, NULL);

  if (hInf == INVALID_HANDLE_VALUE)
    {
      SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  /* First install the service */
  wsprintf(szServiceSection, TEXT("%ws.Services"),
           DriverInfoDetailData.SectionName);

  if(!SetupFindFirstLine(hInf, szServiceSection, NULL, &serviceContext))
    {
      /* No service line?? Can't be... */
      closeAndDestroy(hDevInfo, hInf);
      return FALSE;
    }

  /* Get the name */
  SetupGetStringField(&serviceContext,
                      1,
                      szServiceData,
                      sizeof(szServiceData),
                      NULL);

  wsprintf(deviceRegStr, TEXT("Root\\LEGACY_%ws\\0000"), szServiceData);

  memset(&deviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
  deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

  if (SetupDiOpenDeviceInfo(hDevInfo, deviceRegStr, NULL, 0, &deviceInfoData) //Check for existing
      ||(SetupDiCreateDeviceInfo(hDevInfo, deviceRegStr,                      //Create new
                                 (LPGUID) &GUID_DEVCLASS_DISPLAY,
                                 NULL, //Do we need a description here?
                                 NULL, //No user interface
                                 0,
                                 &deviceInfoData) &&
         SetupDiRegisterDeviceInfo(hDevInfo,
                                   &deviceInfoData,
                                   0,
                                   NULL,
                                   NULL,
                                   NULL)) )
    {
      /* We created a new key in the registry */

      memset(&DeviceInstallParams, 0,sizeof(SP_DEVINSTALL_PARAMS));
      DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

      SetupDiGetDeviceInstallParams(hDevInfo,
                                    &deviceInfoData,
                                    &DeviceInstallParams);

      DeviceInstallParams.Flags |= DI_NOFILECOPY | //We already copied the files
        DI_DONOTCALLCONFIGMG |
        DI_ENUMSINGLEINF; //Use our INF file only

      /* Path to inf file */
      wsprintf(DeviceInstallParams.DriverPath,
               TEXT("%ws\\%ws"),
               szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));

      SetupDiSetDeviceInstallParams(hDevInfo,
                                    &deviceInfoData,
                                    &DeviceInstallParams);


      if(!SetupDiBuildDriverInfoList(hDevInfo,
                                     &deviceInfoData,
                                     SPDIT_CLASSDRIVER))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
      if (!SetupDiEnumDriverInfo(hDevInfo,
                                 &deviceInfoData,
                                 SPDIT_CLASSDRIVER,
                                 0,
                                 &drvInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      if(!SetupDiSetSelectedDriver(hDevInfo,
                                   &deviceInfoData,
                                   &drvInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      if(!SetupDiInstallDevice(hDevInfo,
                               &deviceInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }
    }

  /* Make sure the device is enabled */
  if (SetupDiGetDeviceRegistryProperty(hDevInfo,
                                       &deviceInfoData, SPDRP_CONFIGFLAGS,
                                       NULL, (LPBYTE) &configFlags,
                                       sizeof(DWORD),
                                       NULL)
      && (configFlags & CONFIGFLAG_DISABLED))
    {
      configFlags &= ~CONFIGFLAG_DISABLED;

      SetupDiSetDeviceRegistryProperty(hDevInfo,
                                       &deviceInfoData,
                                       SPDRP_CONFIGFLAGS,
                                       (LPBYTE) &configFlags,
                                       sizeof(DWORD));
    }

  wsprintf(regKeyName,
           TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"),
           szServiceData, 0); //We only have one device

  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     regKeyName,
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      /* Insert description */
      RegSetValueEx(hkey,
                    TEXT("Device Description"),
                    0,
                    REG_SZ,
                    (LPBYTE) DriverInfoDetailData.DrvDescription,
                    (lstrlen(DriverInfoDetailData.DrvDescription) + 1) *
                    sizeof(TCHAR) );

      TCHAR szSoftwareSection[LINE_LEN];

      wsprintf(szSoftwareSection,
               TEXT("%ws.SoftwareSettings"),
               szServiceData);

      if (!SetupInstallFromInfSection(NULL,
                                      hInf,
                                      szSoftwareSection,
                                      SPINST_REGISTRY,
                                      hkey,
                                      NULL,
                                      0,
                                      NULL,
                                      NULL,
                                      NULL,
                                      NULL))
        {
          RegCloseKey(hkey);
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      RegCloseKey(hkey);
    }

  /* Install OpenGL stuff */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      /* Do installation here if ever necessary. Currently there is no OpenGL stuff */

      RegCloseKey(hkey);
    }


  /* Cleanup */
  closeAndDestroy(hDevInfo, hInf);

#if 0
  /* If this key is inserted into the registry, windows will show the desktop
     applet on next boot. We decide in the installer if we want that so the code
     is disabled here. */
  /* Set registry keys so windows picks up the changes */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\NewDisplay"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      RegCloseKey(hkey);
    }
#endif

  /* We must reboot at some point */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\RebootNecessary"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      RegCloseKey(hkey);
    }

  return TRUE;
}
示例#19
0
int removeNetworkInterface(MSIHANDLE hModule, const WCHAR *pwszGUID)
{
    int rc = 1;
    do
    {
        WCHAR wszPnPInstanceId[512] = {0};

        /* We have to find the device instance ID through a registry search */

        HKEY hkeyNetwork = 0;
        HKEY hkeyConnection = 0;

        do /* break-loop */
        {
            WCHAR wszRegLocation[256];
            swprintf(wszRegLocation,
                     L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
                     pwszGUID);
            LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegLocation, 0, KEY_READ, &hkeyNetwork);
            if ((lStatus != ERROR_SUCCESS) || !hkeyNetwork)
                SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]", wszRegLocation));

            lStatus = RegOpenKeyExW(hkeyNetwork, L"Connection", 0, KEY_READ, &hkeyConnection);
            if ((lStatus != ERROR_SUCCESS) || !hkeyConnection)
                SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]", wszRegLocation));

            DWORD len = sizeof(wszPnPInstanceId);
            DWORD dwKeyType;
            lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL,
                                       &dwKeyType, (LPBYTE)&wszPnPInstanceId[0], &len);
            if ((lStatus != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
                SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]", wszRegLocation));
        }
        while (0);

        if (hkeyConnection)
            RegCloseKey(hkeyConnection);
        if (hkeyNetwork)
            RegCloseKey(hkeyNetwork);

        /*
         * Now we are going to enumerate all network devices and
         * wait until we encounter the right device instance ID
         */

        HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
        BOOL fResult;

        do
        {
            DWORD ret = 0;
            GUID netGuid;
            SP_DEVINFO_DATA DeviceInfoData;
            DWORD index = 0;
            DWORD size = 0;

            /* initialize the structure size */
            DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

            /* copy the net class GUID */
            memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));

            /* return a device info set contains all installed devices of the Net class */
            hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT);
            if (hDeviceInfo == INVALID_HANDLE_VALUE)
            {
                logStringW(hModule, L"VBox HostInterfaces: SetupDiGetClassDevs failed (0x%08X)!", GetLastError());
                SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!");
            }

            BOOL fFoundDevice = FALSE;

            /* enumerate the driver info list */
            while (TRUE)
            {
                WCHAR *pwszDeviceHwid;

                fResult = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData);
                if (!fResult)
                {
                    if (GetLastError() == ERROR_NO_MORE_ITEMS)
                        break;
                    else
                    {
                        index++;
                        continue;
                    }
                }

                /* try to get the hardware ID registry property */
                fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
                                                           &DeviceInfoData,
                                                           SPDRP_HARDWAREID,
                                                           NULL,
                                                           NULL,
                                                           0,
                                                           &size);
                if (!fResult)
                {
                    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                    {
                        index++;
                        continue;
                    }

                    pwszDeviceHwid = (WCHAR *)malloc(size);
                    if (pwszDeviceHwid)
                    {
                        fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
                                                                   &DeviceInfoData,
                                                                   SPDRP_HARDWAREID,
                                                                   NULL,
                                                                   (PBYTE)pwszDeviceHwid,
                                                                   size,
                                                                   NULL);
                        if (!fResult)
                        {
                            free(pwszDeviceHwid);
                            pwszDeviceHwid = NULL;
                            index++;
                            continue;
                        }
                    }
                }
                else
                {
                    /* something is wrong.  This shouldn't have worked with a NULL buffer */
                    index++;
                    continue;
                }

                for (WCHAR *t = pwszDeviceHwid;
                     t && *t && t < &pwszDeviceHwid[size / sizeof(WCHAR)];
                     t += wcslen(t) + 1)
                {
                    if (!_wcsicmp(L"vboxtap", t))
                    {
                          /* get the device instance ID */
                          WCHAR wszDevID[MAX_DEVICE_ID_LEN];
                          if (CM_Get_Device_IDW(DeviceInfoData.DevInst,
                                                wszDevID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
                          {
                              /* compare to what we determined before */
                              if (!wcscmp(wszDevID, wszPnPInstanceId))
                              {
                                  fFoundDevice = TRUE;
                                  break;
                              }
                          }
                    }
                }

                if (pwszDeviceHwid)
                {
                    free(pwszDeviceHwid);
                    pwszDeviceHwid = NULL;
                }

                if (fFoundDevice)
                    break;

                index++;
            }

            if (fFoundDevice)
            {
                fResult = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
                if (!fResult)
                {
                    logStringW(hModule, L"VBox HostInterfaces: SetupDiSetSelectedDevice failed (0x%08X)!", GetLastError());
                    SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!");
                }

                fResult = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
                if (!fResult)
                {
                    logStringW(hModule, L"VBox HostInterfaces: SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)!", GetLastError());
                    SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!");
                }
            }
            else
                SetErrBreak(L"VBox HostInterfaces: Host interface network device not found!");
        }
        while (0);

        /* clean up the device info set */
        if (hDeviceInfo != INVALID_HANDLE_VALUE)
            SetupDiDestroyDeviceInfoList(hDeviceInfo);
    }
    while (0);
    return rc;
}
VOID FindDiskDrives(
    _In_ PDV_DISK_OPTIONS_CONTEXT Context
    )
{
    PPH_LIST deviceList;
    HDEVINFO deviceInfoHandle;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail;
    ULONG deviceInfoLength = 0;

    if ((deviceInfoHandle = SetupDiGetClassDevs(
        &GUID_DEVINTERFACE_DISK,
        NULL,
        NULL,
        DIGCF_DEVICEINTERFACE
        )) == INVALID_HANDLE_VALUE)
    {
        return;
    }

    deviceList = PH_AUTO(PhCreateList(1));

    for (ULONG i = 0; SetupDiEnumDeviceInterfaces(deviceInfoHandle, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++)
    {
        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            0,
            0,
            &deviceInfoLength,
            &deviceInfoData
            ) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            continue;
        }

        deviceInterfaceDetail = PhAllocate(deviceInfoLength);
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            deviceInterfaceDetail,
            deviceInfoLength,
            &deviceInfoLength,
            &deviceInfoData
            ))
        {
            HANDLE deviceHandle;
            PDISK_ENUM_ENTRY diskEntry;
            WCHAR diskFriendlyName[MAX_PATH] = L"";

            // This crashes on XP with error 0xC06D007F
            //SetupDiGetDeviceProperty(
            //    deviceInfoHandle,
            //    &deviceInfoData,
            //    &DEVPKEY_Device_FriendlyName,
            //    &devicePropertyType,
            //    (PBYTE)diskFriendlyName,
            //    ARRAYSIZE(diskFriendlyName),
            //    NULL,
            //    0
            //    );

            if (!SetupDiGetDeviceRegistryProperty(
                deviceInfoHandle,
                &deviceInfoData,
                SPDRP_FRIENDLYNAME,
                NULL,
                (PBYTE)diskFriendlyName,
                ARRAYSIZE(diskFriendlyName),
                NULL
                ))
            {
                continue;
            }

            diskEntry = PhAllocate(sizeof(DISK_ENUM_ENTRY));
            memset(diskEntry, 0, sizeof(DISK_ENUM_ENTRY));

            diskEntry->DeviceIndex = ULONG_MAX; // Note: Do not initialize to zero.
            diskEntry->DeviceName = PhCreateString(diskFriendlyName);
            diskEntry->DevicePath = PhCreateString(deviceInterfaceDetail->DevicePath);

            if (NT_SUCCESS(DiskDriveCreateHandle(
                &deviceHandle,
                diskEntry->DevicePath
                )))
            {
                ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
                    deviceHandle,
                    &diskIndex,
                    NULL
                    )))
                {
                    PPH_STRING diskMountPoints = PH_AUTO_T(PH_STRING, DiskDriveQueryDosMountPoints(diskIndex));

                    diskEntry->DeviceIndex = diskIndex;
                    diskEntry->DevicePresent = TRUE;

                    if (!PhIsNullOrEmptyString(diskMountPoints))
                    {
                        diskEntry->DeviceMountPoints = PhFormatString(
                            L"Disk %lu (%s) [%s]",
                            diskIndex,
                            diskMountPoints->Buffer,
                            diskFriendlyName
                            );
                    }
                    else
                    {
                        diskEntry->DeviceMountPoints = PhFormatString(
                            L"Disk %lu [%s]",
                            diskIndex,
                            diskFriendlyName
                            );
                    }
                }

                NtClose(deviceHandle);
            }

            PhAddItemList(deviceList, diskEntry);
        }

        PhFree(deviceInterfaceDetail);
    }

    SetupDiDestroyDeviceInfoList(deviceInfoHandle);

    // Sort the entries
    qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), DiskEntryCompareFunction);

    Context->EnumeratingDisks = TRUE;
    PhAcquireQueuedLockShared(&DiskDrivesListLock);

    for (ULONG i = 0; i < deviceList->Count; i++)
    {
        PDISK_ENUM_ENTRY entry = deviceList->Items[i];

        AddDiskDriveToListView(
            Context,
            entry->DevicePresent,
            entry->DevicePath,
            entry->DeviceMountPoints ? entry->DeviceMountPoints : entry->DeviceName
            );

        if (entry->DeviceMountPoints)
            PhDereferenceObject(entry->DeviceMountPoints);
        if (entry->DeviceName)
            PhDereferenceObject(entry->DeviceName);
        // Note: DevicePath is disposed by WM_DESTROY.

        PhFree(entry);
    }

    PhReleaseQueuedLockShared(&DiskDrivesListLock);
    Context->EnumeratingDisks = FALSE;


    // HACK: Show all unknown devices.
    Context->EnumeratingDisks = TRUE;
    PhAcquireQueuedLockShared(&DiskDrivesListLock);

    for (ULONG i = 0; i < DiskDrivesList->Count; i++)
    {
        ULONG index = -1;
        BOOLEAN found = FALSE;
        PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);

        if (!entry)
            continue;

        while ((index = PhFindListViewItemByFlags(
            Context->ListViewHandle,
            index,
            LVNI_ALL
            )) != -1)
        {
            PDV_DISK_ID param;

            if (PhGetListViewItemParam(Context->ListViewHandle, index, &param))
            {
                if (EquivalentDiskId(param, &entry->Id))
                {
                    found = TRUE;
                }
            }
        }

        if (!found)
        {
            PPH_STRING description;

            if (description = PhCreateString(L"Unknown disk"))
            {
                AddDiskDriveToListView(
                    Context,
                    FALSE,
                    entry->Id.DevicePath,
                    description
                    );

                PhDereferenceObject(description);
            }
        }

        PhDereferenceObjectDeferDelete(entry);
    }

    PhReleaseQueuedLockShared(&DiskDrivesListLock);
    Context->EnumeratingDisks = FALSE;
}
示例#21
0
HDEVINFO
GetNonPresentDevices(
    _In_  LPCWSTR   Enumerator OPTIONAL,
    _In_  LPCWSTR   HardwareID
    )
    
/*++

Routine Description:

    This routine retrieves any non-present devices matching the specified 
    criteria, and returns them in a device information set.

Arguments:

    Enumerator - Optionally, supplies the name of the Enumerator under which 
        this device may be found.  If the device may show up under more than 
        one enumerator, the routine can be called with Enumerator specified as
        NULL, in which case all device instances in the registry are examined.
        
    HardwareID - Supplies the hardware ID to be searched for.  This will be
        compared against each of the hardware IDs for all device instances in
        the system (potentially filtered based on Enumerator), present or not.

Return Value:

    If any non-present devices are discovered, this routine returns a device
    information set containing those devices.  This set must be freed via
    SetupDiDestroyDeviceInfoList by the caller.
    
    If no such devices are encountered (or if an error occurs), the return
    value is INVALID_HANDLE_VALUE.  GetLastError will indicate the cause of
    failure.

--*/

{
    HDEVINFO AllDevs, ExistingNonPresentDevices;
    DWORD i, Err;
    SP_DEVINFO_DATA DeviceInfoData;
    LPWSTR HwIdBuffer, CurId;
    DWORD HwIdBufferLen, RegDataType, RequiredSize;
    BOOL bRet;
    ULONG Status, Problem;
    TCHAR DeviceInstanceId[MAX_DEVNODE_ID_LEN];

    ExistingNonPresentDevices = INVALID_HANDLE_VALUE;
    
    AllDevs = SetupDiGetClassDevs(NULL,
                                  Enumerator,
                                  NULL,
                                  DIGCF_ALLCLASSES
                                 );
                                 
    if(AllDevs == INVALID_HANDLE_VALUE) {
        //
        // last error has already been set during the above call.
        //
        return INVALID_HANDLE_VALUE;
    }
                                  
    //
    // Iterate through each device we found, comparing its hardware ID(s)
    // against the one we were passed in.
    //
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    
    HwIdBuffer = NULL;
    HwIdBufferLen = 0;
    Err = NO_ERROR;
    bRet = FALSE;
    
    i = 0;
        
    while(SetupDiEnumDeviceInfo(AllDevs, i, &DeviceInfoData)) {
        //
        // Retrieve the HardwareID property for this device info element
        //
        if(!SetupDiGetDeviceRegistryProperty(AllDevs,
                                             &DeviceInfoData,
                                             SPDRP_HARDWAREID,
                                             &RegDataType,
                                             (PBYTE)HwIdBuffer,
                                             HwIdBufferLen,
                                             &RequiredSize)) {
            //
            // If the failure was due to buffer-too-small, we can resize and
            // try again.
            //
            if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            
                if(HwIdBuffer) {
                    GlobalFree(HwIdBuffer);
                }
                
                HwIdBuffer = GlobalAlloc(0, RequiredSize);
                if(HwIdBuffer) {
                    HwIdBufferLen = RequiredSize;
                    //
                    // try again
                    //
                    continue;
                } else {
                    //
                    // We failed to allocate the buffer we needed.  This is
                    // considered a critical failure that should cause us to
                    // bail.
                    //
                    Err = ERROR_NOT_ENOUGH_MEMORY;
                    break;
                }
                
            } else {
                //
                // We failed to retrieve the property for some other reason.
                // Skip this device and move on to the next.
                //
                i++;
                continue;
            }
        }

        if((RegDataType != REG_MULTI_SZ) || (RequiredSize < sizeof(TCHAR))) {
            //
            // Data is invalid--this should never happen, but we'll skip the
            // device in this case...
            //
            i++;
            continue;
        }
        
        //
        // If we get to here, then we successfully retrieved the multi-sz
        // hardware id list for this device.  Compare each of those IDs with
        // the caller-supplied one.
        //
        for(CurId = HwIdBuffer; CurId && *CurId; CurId += (lstrlen(CurId) + 1)) {
        
            if(!lstrcmpi(CurId, HardwareID)) {
                //
                // We found a match!
                //
                bRet = TRUE;
                
                //
                // If the device isn't currently present (as indicated by
                // failure to retrieve its status), then add it to the list of
                // such devices to be returned to the caller.
                //
                if(CR_SUCCESS != CM_Get_DevNode_Status(&Status,
                                                       &Problem,
                                                       (DEVNODE)DeviceInfoData.DevInst,
                                                       0))
                {
                    if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) {
                        //
                        // This is the first non-present device we've 
                        // encountered--we need to create the HDEVINFO set.
                        //
                        ExistingNonPresentDevices = 
                            SetupDiCreateDeviceInfoList(NULL, NULL);
                        
                        if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) {
                            //
                            // Failure to create this set is a critical error!
                            //
                            Err = GetLastError();
                            bRet = FALSE;
                            break;
                        }
                    }
                        
                    //
                    // We need to get the device instance's name so we can
                    // open it up into our "non-present devices" list
                    //
                    if(!SetupDiGetDeviceInstanceId(AllDevs,
                                                   &DeviceInfoData,
                                                   DeviceInstanceId,
                                                   sizeof(DeviceInstanceId) / sizeof(TCHAR),
                                                   NULL)) {
                        //
                        // Should never fail, but considered critical if it
                        // does...
                        //
                        Err = GetLastError();
                        bRet = FALSE;
                        break;
                    }

                    //
                    // Now open up the non-present device into our list.
                    //
                    if(!SetupDiOpenDeviceInfo(ExistingNonPresentDevices,
                                              DeviceInstanceId,
                                              NULL,
                                              0,
                                              NULL)) {
                        //
                        // This failure is also considered critical!
                        //                          
                        Err = GetLastError();
                        bRet = FALSE;
                    }

                    break;
                }
            }
        }

        if(Err != NO_ERROR) {
            //
            // Critical error encountered--bail!
            //
            break;
        }

        //
        // Move onto the next device instance
        //
        i++;
    }
    
    if(HwIdBuffer) {
        GlobalFree(HwIdBuffer);
    }

    //
    // We can now destroy our temporary list of all devices under consideration
    //
    SetupDiDestroyDeviceInfoList(AllDevs);

    if((Err != NO_ERROR) && 
       (ExistingNonPresentDevices != INVALID_HANDLE_VALUE)) {
        //
        // We encountered a critical error, so we need to destroy the (partial)
        // list of non-present devices we'd built.
        //
        SetupDiDestroyDeviceInfoList(ExistingNonPresentDevices);
        ExistingNonPresentDevices = INVALID_HANDLE_VALUE;
    }

    SetLastError(Err);

    return ExistingNonPresentDevices;
}
示例#22
0
NDASDI_API BOOL WINAPI 
NdasDiRemoveLegacyDevice(
	IN HWND hwndParent,
	IN LPCTSTR ServiceName,
	IN BOOL PresentOnly,
	OUT LPDWORD pdwRemovedDeviceCount OPTIONAL,
	OUT LPBOOL pbRebootRequired OPTIONAL,
	IN NDASDIREMOVEDEVICEERRCALLBACKPROC ErrorCallbackProc OPTIONAL,
	IN LPVOID Context OPTIONAL)
{
	_ASSERTE(!IsBadStringPtr(ServiceName, LINE_LEN));
	_ASSERTE(NULL == pbRebootRequired || !IsBadWritePtr(pbRebootRequired, sizeof(BOOL)));
	_ASSERTE(NULL == ErrorCallbackProc || !IsBadCodePtr((FARPROC)ErrorCallbackProc));

	BOOL fReturn = FALSE;
	BOOL fSuccess = FALSE;

    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData = {0};
	DWORD Flags = DIGCF_ALLCLASSES;
	
	if (PresentOnly) {
		Flags |= DIGCF_PRESENT;
	}
	
    //
    // Create a Device Information Set with all present devices.
    //
    DeviceInfoSet = SetupDiGetClassDevs(
		NULL, // All Classes
        0,
        hwndParent, 
        Flags); // All devices present on system

    if (INVALID_HANDLE_VALUE == DeviceInfoSet) {
		goto cleanup;
    }
    
	if (NULL != pbRebootRequired) {
		*pbRebootRequired = FALSE;
	}

	//
    //  Enumerate through all Devices.
    //
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

	if (NULL != pdwRemovedDeviceCount) {
		*pdwRemovedDeviceCount = 0;
	}

	for (DWORD i = 0;
		SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);
		++i)
    {
        DWORD DataT;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;
        
        //
        // We won't know the size of the HardwareID buffer until we call
        // this function. So call it with a null to begin with, and then 
        // use the required buffer size to Alloc the nessicary space.
        // Keep calling we have success or an unknown failure.
        //
        while (TRUE) {

			fSuccess = SetupDiGetDeviceRegistryProperty(
				DeviceInfoSet,
				&DeviceInfoData,
				SPDRP_SERVICE,
				&DataT,
				(PBYTE)buffer,
				buffersize,
				&buffersize);
			
			if (fSuccess) {
				break;
			}

            if (ERROR_INVALID_DATA == GetLastError()) {
                //
                // May be a Legacy Device with no HardwareID. Continue.
                //
                break;
            } else if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
                //
                // We need to change the buffer size.
                //
                if (buffer) {
                    LocalFree(buffer);
				}
                buffer = (LPTSTR) LocalAlloc(LPTR,buffersize);

			} else {
                //
                // Unknown Failure.
                //
				if (ErrorCallbackProc) {
					BOOL fCont = ErrorCallbackProc(
						NDIRD_ERROR_GetDeviceRegistryProperty,
						DeviceInfoSet,
						&DeviceInfoData,
						GetLastError(),
						Context);
					if (fCont) {
					}
					fReturn = FALSE;
					goto cleanup;
				}
            }            
        }

		//
		// May be a Legacy Device with no HardwareID. Continue.
		//
        if (GetLastError() == ERROR_INVALID_DATA) {
            continue;
		}
        
        //
        // Service Name is REG_SZ (Not MultiSZ)
        //
		LPCTSTR p = buffer;
		DPNoise(_T("%s\n"), p);

		if (0 == lstrcmpi(ServiceName,p)) {

			DPNoise(_T("\n>>> %s <<<\n"), p);

			//
            // Worker function to remove device.
            //
				fSuccess = SetupDiCallClassInstaller(
				DIF_REMOVE, 
				DeviceInfoSet, 
				&DeviceInfoData);

			if (!fSuccess && ErrorCallbackProc) {
				BOOL fCont = ErrorCallbackProc(
					NDIRD_ERROR_CallRemoveToClassInstaller,
					DeviceInfoSet, 
					&DeviceInfoData, 
					GetLastError(), 
					Context);

				if (buffer) {
					LocalFree(buffer);
				}
				fReturn = FALSE;
				goto cleanup;
			}

			//
			// Get the installation param
			//
			if (NULL != pbRebootRequired) {

				SP_DEVINSTALL_PARAMS diParams = {0};
				diParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

				fSuccess = SetupDiGetDeviceInstallParams(
					DeviceInfoSet,
					&DeviceInfoData,
					&diParams);

				_ASSERTE(fSuccess);

				*pbRebootRequired |= 
					(diParams.Flags & DI_NEEDREBOOT) ||
					(diParams.Flags & DI_NEEDRESTART);

			}

			if (NULL != pdwRemovedDeviceCount) {
				++(*pdwRemovedDeviceCount);
			}

            break;

		}

        if (buffer) {
			LocalFree(buffer);
		}
    }

    if ((NO_ERROR != GetLastError()) && 
		(ERROR_NO_MORE_ITEMS != GetLastError())) 
	{
		fReturn = FALSE;
	} else {
		fReturn = TRUE;
	}
    
    //
    //  Cleanup.
    //    
cleanup:

    DWORD err = GetLastError();

	if (INVALID_HANDLE_VALUE != DeviceInfoSet) {
		SetupDiDestroyDeviceInfoList(DeviceInfoSet);
	}
	
	SetLastError(err);

	return fReturn;
}
示例#23
0
NDASDI_API
BOOL 
WINAPI
NdasDiFindExistingDevice(
	IN HWND hwndParent,
	IN LPCTSTR HardwareId,
	IN BOOL PresentOnly)
{
	BOOL Found = FALSE;
	BOOL fReturn = FALSE;
	BOOL fSuccess = FALSE;

	HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
	SP_DEVINFO_DATA DeviceInfoData = {0};
	DWORD Flags = DIGCF_ALLCLASSES;

	if (PresentOnly) {
		Flags |= DIGCF_PRESENT;
	}

	DeviceInfoSet = SetupDiGetClassDevs(
		NULL, 
		0, 
		hwndParent,
		Flags);

	if (INVALID_HANDLE_VALUE == DeviceInfoSet) {
		return FALSE;
	}

	for (DWORD i = 0; ; ++i) {
		
		DeviceInfoData.cbSize = sizeof(DeviceInfoData);
		fSuccess = SetupDiEnumDeviceInfo(
			DeviceInfoSet,
			i,
			&DeviceInfoData);

		if (!fSuccess) {
			break;
		}

		DWORD DataT;
		LPTSTR buffer = NULL;
		DWORD buffersize = 0;

		//
		// We won't know the size of the HardwareID buffer until we call
		// this function. So call it with a null to begin with, and then 
		// use the required buffer size to Alloc the nessicary space.
		// Keep calling we have success or an unknown failure.
		//
		while (TRUE) {

			fSuccess = SetupDiGetDeviceRegistryProperty(
				DeviceInfoSet,
				&DeviceInfoData,
				SPDRP_HARDWAREID,
				&DataT,
				(PBYTE)buffer,
				buffersize,
				&buffersize);

			if (fSuccess) {
				break;
			}

			if (ERROR_INVALID_DATA == GetLastError()) {
				//
				// May be a Legacy Device with no HardwareID. Continue.
				//
				break;
			} else if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
				//
				// We need to change the buffer size.
				//
				if (buffer) {
					LocalFree(buffer);
				}
				buffer = (LPTSTR) LocalAlloc(LPTR,buffersize);

			} else {
				//
				// Unknown Failure.
				//
				goto cleanup;
			}            
		}

		//
		// May be a Legacy Device with no HardwareID. Continue.
		//
		if (GetLastError() == ERROR_INVALID_DATA) {
			continue;
		}

		//
		// Compare each entry in the buffer multi-sz list with our HardwareID.
		//
		for (LPTSTR p = buffer; 
			*p && (p < & buffer[buffersize]);
			p += lstrlen(p) + 1) 
		{
			if (0 == lstrcmpi(HardwareId,p)) {
				Found = TRUE;
				break;
			}
		}

		if (buffer) {
			LocalFree(buffer);
		}

		if (Found) {
			break;
		}
	}

	if (Found) {
		SetLastError(ERROR_SUCCESS);
		fReturn = TRUE;
	}

cleanup:

	DWORD err = GetLastError();

	if (INVALID_HANDLE_VALUE != DeviceInfoSet) {
		(VOID) SetupDiDestroyDeviceInfoList(DeviceInfoSet);
	}

	SetLastError(err);
	return fReturn;
}
示例#24
0
extern "C" DWORD UnInstallLoopBack(void)
{
    BOOL ok;
    DWORD ret = 0;
    GUID netGuid;
    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD index = 0;
    BOOL found = FALSE;
    DWORD size = 0;

    // initialize the structure size
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    // copy the net class GUID
    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));

    // return a device info set contains all installed devices of the Net class
    hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT);

    if (hDeviceInfo == INVALID_HANDLE_VALUE)
        return GetLastError();

    // enumerate the driver info list
    while (TRUE)
    {
        TCHAR * deviceHwid;

        ok = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData);

	if(!ok) 
	{
	  if(GetLastError() == ERROR_NO_MORE_ITEMS)
	      break;
	  else 
	  {
   	      index++;
	      continue;
	  }
	}

        // try to get the DeviceDesc registry property
        ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, 
					      &DeviceInfoData,
                                              SPDRP_HARDWAREID,
                                              NULL,
					      NULL,
                                              0, 
					      &size);
        if (!ok)
        {
            ret = GetLastError();
            if (ret != ERROR_INSUFFICIENT_BUFFER) {
                index++;
                continue;
	    }

            deviceHwid = (TCHAR *)malloc(size);
            ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
                                                  &DeviceInfoData,
                                                  SPDRP_HARDWAREID,
                                                  NULL, 
						  (PBYTE)deviceHwid,
                                                  size, 
						  NULL);
            if (!ok) {
	        free(deviceHwid);
	        deviceHwid = NULL;
	        index++;
	        continue;
	    }
        } else {
	    // something is wrong.  This shouldn't have worked with a NULL buffer
	    ReportMessage(0, "GetDeviceRegistryProperty succeeded with a NULL buffer", NULL,  NULL, 0);
	    index++;
	    continue;
	}

	for (TCHAR *t = deviceHwid; t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; t += _tcslen(t) + 1)
	{
	    if(!_tcsicmp(DRIVERHWID, t)) {
	        found = TRUE;
		break;
	    }
	}

	if (deviceHwid) {
	    free(deviceHwid);
	    deviceHwid = NULL;
	}

	if (found)
            break;
	
        index++;
    }

    if (found == FALSE)
    {
        ret = GetLastError();
        ReportMessage(0,"Driver does not seem to be installed", DRIVER_DESC, NULL, ret);
        goto cleanup;
    }

    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    ret = 0;

cleanup:
    // clean up the device info set
    if (hDeviceInfo != INVALID_HANDLE_VALUE)
        SetupDiDestroyDeviceInfoList(hDeviceInfo);

    return ret;
}
示例#25
0
void PCUtils::GetPhysicalDisks( std::vector<PCUtils::DISK_DRIVE_INFORMATION>& OutVector )
{
#ifdef _WIN32
    unsigned i;
    DWORD dwSize, dwPropertyRegDataType = SPDRP_PHYSICAL_DEVICE_OBJECT_NAME;
    CONFIGRET r;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    SP_DEVICE_INTERFACE_DATA interfaceData;

    TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN];
    TCHAR szDesc[1024];

    GUID HddClass;
    HddClass = GUID_DEVINTERFACE_DISK;//GUID_DEVCLASS_DISKDRIVE;

    // List all connected disk drives
    hDevInfo = SetupDiGetClassDevs (&HddClass, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE)
        return;

    // Find the ones that are driverless
    for (i = 0; ; i++)
    {
        DeviceInfoData.cbSize = sizeof (DeviceInfoData);
        // Get the next device info
        if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
            break;
        interfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
        // Get the next device interface
        if (!SetupDiEnumInterfaceDevice(hDevInfo, NULL, &HddClass, i, &interfaceData))
        {
            break;
        }

        // Get the device ID
        r = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
        if (r != CR_SUCCESS)
            continue;

        // To add to the vector
        DISK_DRIVE_INFORMATION AddToVector;

        DWORD requiredSize = 0;

        // Get the path
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, NULL, NULL, &requiredSize, NULL);
        SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize);

        data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);


        if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, data, requiredSize, NULL, NULL))
        {
            continue;
        }

        AddToVector.Path = nowide::convert(std::wstring(data->DevicePath));
        qDebug("Disk path: %s", AddToVector.Path.c_str());

        // Friendly name (e.g. SanDisk Cruzer USB...)
        SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME,
                                          &dwPropertyRegDataType, (BYTE*)szDesc,
                                          sizeof(szDesc),   // The size, in bytes
                                          &dwSize);
        AddToVector.FriendlyName = nowide::convert(std::wstring((TCHAR*)szDesc));
        qDebug("Friendly name: %s", AddToVector.FriendlyName.c_str());

        OutVector.push_back(AddToVector);
        delete data;
    }
#else
DIR *dir = NULL;
dirent *ent = NULL;
dir = opendir("/dev/");
if (dir != NULL)
{
    // Read the shit
    while ((ent = readdir(dir)) != NULL)
    {
        // Check the directory name, and if it starts with "disk" then keep it!
        QRegExp exp("disk*");
        exp.setPatternSyntax(QRegExp::Wildcard);
        exp.setCaseSensitivity(Qt::CaseInsensitive);
        if (exp.exactMatch(ent->d_name))
        {
            DISK_DRIVE_INFORMATION curdir;

            std::ostringstream ss;
            ss << "/dev/r";
            ss << ent->d_name;
            std::string diskPath = ss.str();

            curdir.Path = diskPath;

            int device;
            if ((device = open(diskPath.c_str(), O_RDONLY)) > 0)
            {
#ifdef __linux
                hd_driveid hd;
                if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
                {
                    curdir.FriendlyName = hd.model;
                }
#elif defined __APPLE__
                curdir.FriendlyName = ent->d_name;
#endif
                OutVector.push_back(curdir);
            }
        }
    }
}
if (dir)
    closedir(dir);
if (ent)
    delete ent;
#endif
}
bool cmtScanPorts(List<CmtPortInfo>& ports,uint32_t baudrate, uint32_t singleScanTimeout, uint32_t scanTries)
{
	CmtPortInfo current = {0,0,0};
	ports.clear();	// clear the list
#ifdef _WIN32
	HDEVINFO hDevInfo;
	SP_DEVINFO_DATA DeviceInfoData;
	DWORD i;

	// Create a HDEVINFO with all present devices.

	// GUID for Ports: 4D36E978-E325-11CE-BFC1-08002BE10318
	GUID portGuid = 
		{0x4D36E978,0xE325,0x11CE,{0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18}};
		
	//	"4D36E978-E325-11CE-BFC1-08002BE10318"
	hDevInfo = SetupDiGetClassDevs(&portGuid, 0, 0, DIGCF_PRESENT | DIGCF_PROFILE);

	if (hDevInfo == INVALID_HANDLE_VALUE)
		return false;

	// Enumerate through all devices in Set.
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	for (i=0;!abortScan && SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);++i)
	{
		DWORD DataT;
		char buffer[256];
		bool isBT = false;

		//
		// Call function with null to begin with,
		// then use the returned buffer size
		// to Alloc the buffer. Keep calling until
		// success or an unknown failure.
		//
#if 1
		if (SetupDiGetDeviceRegistryProperty(hDevInfo,
						&DeviceInfoData,
						SPDRP_MFG,
						&DataT,
						(PBYTE)buffer,
						256,
						NULL))
		{
			// on failure, this is not an Xsens Device
			// on success, we need to check if the device is an Xsens Device
			//if (_strnicmp(buffer,"xsens",5))
			//	scan = true;
			//else
			if (!_strnicmp(buffer,"(Standard port types)",20))
				continue;
			if (_strnicmp(buffer,"xsens",5))	// if this is NOT an xsens device, treat it as a BT device
			{
				isBT = true;
				if (_strnicmp(buffer,"WIDCOMM",7))	// if this is NOT a WIDCOMM (Ezureo / TDK stack), skip it
					continue;
			}
		}
#endif
		// we found an Xsens Device, add its port nr to the list
		//Get the registry key which stores the ports settings
		HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
		if (hDeviceKey != INVALID_HANDLE_VALUE)
		{
			//Read in the name of the port
			char pszPortName[256];
			DWORD dwSize = 256;
			DWORD dwType = 0;
			if ((RegQueryValueEx(hDeviceKey, "PortName", NULL, &dwType, (LPBYTE) pszPortName, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
			{
				//If it looks like "COMX" then
				//add it to the array which will be returned
				int32_t nLen = (int32_t) strlen(pszPortName);
				if (nLen > 3)
				{
					if (_strnicmp(pszPortName, "COM", 3))
						continue;
					int32_t nPort = atoi(&pszPortName[3]);
					if (nPort)
					{
						current.m_portNr = (uint16_t) nPort;
						if (isBT)
							current.m_baudrate = CMT_BAUD_RATE_460K8;
						else
							current.m_baudrate = baudrate;
						ports.append(current);
					}
				}
			}
		}
		//Close the key now that we are finished with it
		RegCloseKey(hDeviceKey);
	}

	//  Cleanup

	SetupDiDestroyDeviceInfoList(hDevInfo);

	// Now sort the list by ascending port nr
	ports.sortAscending();

	// Add the standard com ports 1 and 2 unless they are already in the list
	bool	add1 = true,
			add2 = true;
	if ((ports.length() > 0) && (ports[0].m_portNr == 1))
		add1 = false;
	if (ports.length() > 0)
	{
		if (ports[0].m_portNr == 2)
			add2 = false;
		else
			if (ports.length() > 1)
				if (ports[1].m_portNr == 2)
					add2 = false;
	}
	if (add1)
	{
		current.m_portNr = 1;
		current.m_baudrate = baudrate;
		ports.append(current);
	}
	if (add2)
	{
		current.m_portNr = 2;
		current.m_baudrate = baudrate;
		ports.append(current);
	}
#else
	DIR *dir;
	struct dirent *entry;
	
	if ((dir = opendir("/dev/")) == NULL)
		return false;
	
	while ((entry = readdir(dir)))
		if (strncmp("ttyS", entry->d_name, 4) == 0 || strncmp("ttyUSB", entry->d_name, 6) == 0)
		{
			sprintf(current.m_portName, "/dev/%s", entry->d_name);
			current.m_baudrate = baudrate;
			ports.append(current);
		}
	closedir(dir);
	
	ports.sortAscending();
#endif

	// try to connect so we can detect if there really is an MT / XM attached
	unsigned p = 0;
	while (!abortScan && p < ports.length())
	{
		if (cmtScanPort(ports[p],ports[p].m_baudrate,singleScanTimeout,scanTries))
			++p;
		else
			ports.remove(p);
	}

	if (abortScan)
		return abortScan = false;

	// Now sort the final list by ascending port nr
	ports.sortAscending();
	abortScan = false;
	return true;
}
示例#27
0
int serial_find(const char* prefix, int (*check)(const char* port, void* data), void* data)
{
	GUID *guidDev = (GUID *) &GUID_CLASS_COMPORT;
	HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
	SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
	SP_DEVICE_INTERFACE_DATA ifcData;
	DWORD dwDetDataSize;
	int rc = -1;
	BOOL bOk;
	DWORD i;

	hDevInfo = SetupDiGetClassDevs( guidDev,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
		);

	if(hDevInfo == INVALID_HANDLE_VALUE) {
		printf("error: SetupDiGetClassDevs failed. (err=%lx)\n", GetLastError());
		goto done;
	}

	// Enumerate the serial ports
	dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
	pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(dwDetDataSize);

	ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

	for (i = 0, bOk = TRUE; bOk; ++i) {

		// get the next device
		bOk = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guidDev, i, &ifcData);
		if (bOk) {

			// get the device details
			SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
			bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, &devdata);
			if (bOk) {
				TCHAR fname[256], desc[256];

				// get some additional info
				BOOL bSuccess = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL)
					            && SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL, (PBYTE)desc, sizeof(desc), NULL);
				if (bSuccess) {
					char *comx, *p;
					//printf("Device path: %s\n", pDetData->DevicePath);
					//printf("Friendly name: %s\n", fname);
					//printf("Description: %s\n", desc);
					if ((comx = strchr(fname, '(')) != NULL)
					    ++comx;
					else
					    comx = fname;
					if ((p = strchr(comx, ')')) != NULL)
					    *p = '\0';
                                    if ((*check)(comx, data) == 0) {
				        rc = 0;
				        goto done;
				    }
				}

			}
			else {
				printf("error: SetupDiGetDeviceInterfaceDetail failed. (err=%lx)\n", GetLastError());
				return 1;
			}
		}
		else {
			DWORD err = GetLastError();
			if (err != ERROR_NO_MORE_ITEMS) {
				printf("error: SetupDiEnumDeviceInterfaces failed. (err=%lx)\n", err);
				goto done;
			}
		}
	}

done:
    if (pDetData != NULL)
		free(pDetData);
	if (hDevInfo != INVALID_HANDLE_VALUE)
		SetupDiDestroyDeviceInfoList(hDevInfo);

	return rc;
}
示例#28
0
static int EnumDevices(
    PCNC_ENUM_FILTER pFilter,
    DWORD flags,
    PCNC_DEV_ROUTINE pDevRoutine,
    PEnumParams pEnumParams)
{
  HDEVINFO hDevInfo;

  hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES|flags);

  if (hDevInfo == INVALID_HANDLE_VALUE) {
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetClassDevs()");
    return IDCANCEL;
  }

  SP_DEVINFO_DATA devInfoData;

  devInfoData.cbSize = sizeof(devInfoData);

  int res = IDCONTINUE;

  for (int i = 0 ; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData) ; i++) {
    char hardwareId[40];

    if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)hardwareId, sizeof(hardwareId), NULL)) {
      memset(hardwareId, 0, sizeof(hardwareId));
      SNPRINTF(hardwareId, sizeof(hardwareId)/sizeof(hardwareId[0]), "UNKNOWN HARDWAREID" "\0");
    }

    if (!pFilter(hardwareId))
      continue;

    const char *pHardwareId = hardwareId;

    if (pEnumParams->pDevProperties && pEnumParams->pDevProperties->DevId()) {
      while (lstrcmpi(pHardwareId, pEnumParams->pDevProperties->DevId()) != 0) {
        pHardwareId = pHardwareId + lstrlen(pHardwareId) + 1;

        if (!*pHardwareId) {
          pHardwareId = NULL;
          break;
        }
      }

      if (!pHardwareId)
        continue;
    }

    DevParams devParams(pEnumParams);

    if (!devParams.devProperties.DevId(pHardwareId)) {
      res = IDCANCEL;
      break;
    }

    char location[40];

    if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)location, sizeof(location), NULL)) {
      if (!devParams.devProperties.Location(location)) {
        res = IDCANCEL;
        break;
      }
    }

    if (pEnumParams->pDevProperties &&
        pEnumParams->pDevProperties->Location() && (!devParams.devProperties.Location() ||
        lstrcmpi(devParams.devProperties.Location(), pEnumParams->pDevProperties->Location())))
    {
      continue;
    }

    char name[40];

    if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, NULL, (PBYTE)name, sizeof(name), NULL)) {
      if (!devParams.devProperties.PhObjName(name)) {
        res = IDCANCEL;
        break;
      }
    }

    if (pEnumParams->pDevProperties &&
        pEnumParams->pDevProperties->PhObjName() && (!devParams.devProperties.PhObjName() ||
        lstrcmpi(devParams.devProperties.PhObjName(), pEnumParams->pDevProperties->PhObjName())))
    {
      continue;
    }

    res = pDevRoutine(hDevInfo, &devInfoData, &devParams);

    if (res != IDCONTINUE)
      break;
  }

  DWORD err = GetLastError();

  SetupDiDestroyDeviceInfoList(hDevInfo);

  SetLastError(err);

  return res;
}
示例#29
0
int
InstallPnPDriver(
    IN HWND hWnd,
    PTSTR HardwareId, 
    PTSTR Inf,
    BOOL DelayInstall,
    BOOL ForceUpdateDriver
    )
{
    DWORD Err = NO_ERROR;
    SP_DEVINFO_DATA DeviceInfoData;
    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    TCHAR DeviceIds[REGSTR_VAL_MAX_HCID_LEN];
    DWORD memberIndex;
    PTSTR singleDeviceId;

    DeviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES);
    if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
        Err = GetLastError();
        goto clean;
    }

    memberIndex = 0;
    DeviceInfoData.cbSize = sizeof(DeviceInfoData);
    while (SetupDiEnumDeviceInfo(DeviceInfoSet,
                                 memberIndex++,
                                 &DeviceInfoData)) {
        if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
                                             &DeviceInfoData,
                                             SPDRP_HARDWAREID,
                                             NULL,
                                             (PBYTE)DeviceIds,
                                             sizeof(DeviceIds),
                                             NULL)) {
            for (singleDeviceId = DeviceIds;
                 *singleDeviceId;
                 singleDeviceId += lstrlen(singleDeviceId) + 1) {

                if (!lstrcmpi(HardwareId, singleDeviceId)) {
                    //
                    // Found a match.  Check if it is a phantom if PhantomOnly is
                    // TRUE
                    //
                    if (InstallInfOnDevice(hWnd, 
                                           DeviceInfoSet,
                                           &DeviceInfoData,
                                           Inf,
                                           DelayInstall) != NO_ERROR) {
                        MessageBox(hWnd, "Failed to install drivers on one of the devices", "Install Error", MB_OK);
                    }
                    if (ForceUpdateDriver)
                    {
                        BOOL reboot;
                        if (!UpdateDriverForPlugAndPlayDevices(
                                               hWnd,
                                               HardwareId,
                                               Inf,
                                               INSTALLFLAG_FORCE,
                                               &reboot))
                            MessageBox(hWnd, "Failed to force update driver for one of the devices", "Install Error", MB_OK);
                    }
                }
            }
        }
    }

clean:
    if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    }

    if (Err == NO_ERROR) {
        return 0;
    }
    return 1;
}
示例#30
0
BOOL IsLoopbackInstalled(void)
{
    HDEVINFO DeviceInfoSet;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i,err;
    BOOL found;
    
    //
    // Create a Device Information Set with all present devices.
    //
    DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
    {
        return FALSE; // nothing installed?
    }
    
    //
    //  Enumerate through all Devices.
    //
    found = FALSE;
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i=0; ;i++)
    {
        BOOL ok;
        DWORD DataT;
        TCHAR *p, *buffer = NULL;
        DWORD buffersize = 0;

	ok = SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData);

	if(!ok) {
	  if(GetLastError() == ERROR_NO_MORE_ITEMS)
	    break;
	  else
	    continue;
	}
        
        //
        // We won't know the size of the HardwareID buffer until we call
        // this function. So call it with a null to begin with, and then 
        // use the required buffer size to Alloc the nessicary space.
        // Keep calling we have success or an unknown failure.
        //
        while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
						 &DeviceInfoData,
						 SPDRP_HARDWAREID,
						 &DataT,
						 (PBYTE)buffer,
						 buffersize,
						 &buffersize))
        {
            if (GetLastError() == ERROR_INVALID_DATA)
            {
                // May be a Legacy Device with no hwid. Continue.
                break;
            }
            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                // We need to change the buffer size.
                if (buffer) 
                    LocalFree(buffer);
                buffer = (TCHAR *)LocalAlloc(LPTR,buffersize);
            }
            else
            {
	        if (buffer)
                    LocalFree(buffer);
                goto cleanup_DeviceInfo;
            }
        }
        
        if (GetLastError() == ERROR_INVALID_DATA) {
	    if (buffer)
                LocalFree(buffer);
            continue;
	}
        
        // Compare each entry in the buffer multi-sz list with our hwid.
        for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
        {
            if (!_tcsicmp(DRIVERHWID,p))
            {
                found = TRUE;
                break;
            }
        }
        
        if (buffer)
	    LocalFree(buffer);
        if (found) 
	    break;
    }
    
    //  Cleanup.
cleanup_DeviceInfo:
    err = GetLastError();
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    SetLastError(err);
    
    return found;
}