func getNativeName(DeviceInfoSet C.HDEVINFO, DeviceInfoData C.PSP_DEVINFO_DATA) (string, error) {
	key := C.SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, C.DICS_FLAG_GLOBAL, 0, C.DIREG_DEV, C.KEY_READ)
	defer C.RegCloseKey(key)
	if C.is_INVALID_HANDLE_VALUE(unsafe.Pointer(key)) != C.FALSE {
		return "", errors.New(fmt.Sprintf("Reg error: %d", int(C.GetLastError())))
	}

	var i C.DWORD = 0
	var keyType C.DWORD = 0
	buffKeyName := make([]C.CHAR, 16384)
	buffKeyVal := make([]C.BYTE, 16384)
	for {
		var lenKeyName C.DWORD = C.DWORD(cap(buffKeyName))
		var lenKeyValue C.DWORD = C.DWORD(cap(buffKeyVal))
		ret := C.RegEnumValue(key, i, &buffKeyName[0], &lenKeyName, (*C.DWORD)(nil), &keyType, &buffKeyVal[0], &lenKeyValue)
		i++
		if ret == C.ERROR_SUCCESS {
			if keyType == C.REG_SZ {
				itemName := C.GoString((*C.char)(&buffKeyName[0]))
				itemValue := C.GoString((*C.char)(unsafe.Pointer((&buffKeyVal[0]))))

				if strings.Contains(itemName, "PortName") {
					return itemValue, nil
				}
			}
		} else {
			break
		}
	}

	return "", errors.New("Empty response")
}
func enumerate() ([]DeviceDescription, error) {
	//log.Print("Calling windows backend")

	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\services`, registry.QUERY_VALUE)
	if err != nil {
		return nil, err
	}
	defer k.Close()

	var result []DeviceDescription

	for i := 0; i < len(guidArray); i++ {
		DeviceInfoSet := C.SetupDiGetClassDevs(&guidArray[i], (*C.CHAR)(nil), (*C.struct_HWND__)(nil), C.DIGCF_PRESENT)

		if C.is_INVALID_HANDLE_VALUE(unsafe.Pointer(DeviceInfoSet)) != 0 {
			return nil, errors.New(fmt.Sprintf(
				`Windows: SerialDeviceEnumeratorPrivate::updateInfo() 
				SetupDiGetClassDevs() returned INVALID_HANDLE_VALUE, 
				last error: %d`, int(C.GetLastError())))
		}

		var DeviceIndex C.DWORD = 0
		var DeviceInfoData C.SP_DEVINFO_DATA
		DeviceInfoData.cbSize = C.DWORD(unsafe.Sizeof(DeviceInfoData))

		for {
			if C.SetupDiEnumDeviceInfo(DeviceInfoSet, DeviceIndex, &DeviceInfoData) != C.TRUE {
				break
			}
			DeviceIndex++

			name, err := getNativeName(DeviceInfoSet, &DeviceInfoData)
			if err != nil || len(name) == 0 {
				continue
			}

			if strings.Contains(name, "LPT") {
				continue
			}

			var dev DeviceDescription
			dev.Name = name
			dev.ShortName = name
			if dev.Bus, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_ENUMERATOR_NAME)); err != nil {
				log.Printf("Error get bus of device %s: %s", name, err.Error())
			}
			if dev.Description, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_DEVICEDESC)); err != nil {
				log.Printf("Error get Description of device %s: %s", name, err.Error())
			}
			if dev.FriendlyName, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_FRIENDLYNAME)); err != nil {
				log.Printf("Error get FriendlyName of device %s: %s", name, err.Error())
			}
			if dev.HardwareID, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_HARDWAREID)); err != nil {
				log.Printf("Error get HardwareID of device %s: %s", name, err.Error())
			}
			if dev.LocationInfo, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_LOCATION_INFORMATION)); err != nil {
				log.Printf("Error get LocationInfo of device %s: %s", name, err.Error())
			}
			if dev.Manufacturer, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_MFG)); err != nil {
				log.Printf("Error get Manufacturer of device %s: %s", name, err.Error())
			}
			if dev.SubSystem, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_CLASS)); err != nil {
				log.Printf("Error get SubSystem of device %s: %s", name, err.Error())
			}
			if dev.Service, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_SERVICE)); err != nil {
				log.Printf("Error get Service of device %s: %s", name, err.Error())
			}
			if dev.Driver, err = getNativeDriver(dev.Service); err != nil {
				log.Printf("Error get Driver of device %s: %s", name, err.Error())
			}
			if dev.SystemPath, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)); err != nil {
				log.Printf("Error get SystemPath of device %s: %s", name, err.Error())
			}

			match := vidpidRegExp.FindStringSubmatch(dev.HardwareID)
			if len(match) > 1 {
				var v []byte
				if v, err = hex.DecodeString(match[1]); err == nil {
					dev.VendorID = (uint16)(v[0])<<8 + (uint16)(v[1])
				}
				if v, err = hex.DecodeString(match[2]); err == nil {
					dev.ProductID = (uint16)(v[0])<<8 + (uint16)(v[1])
				}
			}

			result = append(result, dev)
		}
	}
	return result, nil
}