Example #1
1
// Use to write uint32 value to windows registry the HKEY in the next definition HHLM, HKCU, HKCC, HKCR, HKU
func WriteDwordReg(hkey, path, name string, val uint32) (err error) {
	var handle syscall.Handle
	switch hkey {
	case "HKLM":
		err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(""), 0, syscall.KEY_CREATE_SUB_KEY, &handle)
	case "HKCC":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_CONFIG, syscall.StringToUTF16Ptr(""), 0, syscall.KEY_CREATE_SUB_KEY, &handle)
	case "HKCR":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, syscall.StringToUTF16Ptr(""), 0, syscall.KEY_CREATE_SUB_KEY, &handle)
	case "HKCU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER, syscall.StringToUTF16Ptr(""), 0, syscall.KEY_CREATE_SUB_KEY, &handle)
	case "HKU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_USERS, syscall.StringToUTF16Ptr(""), 0, syscall.KEY_CREATE_SUB_KEY, &handle)
	default:
		err = errors.New("Unknown HKEY: " + hkey)
		return
	}
	if err != nil {
		return
	}
	defer syscall.RegCloseKey(handle)
	var d uint32
	err = winapi.RegCreateKeyEx(handle, syscall.StringToUTF16Ptr(path), 0, nil, winapi.REG_OPTION_NON_VOLATILE, syscall.KEY_ALL_ACCESS, nil, &handle, &d)
	if err != nil {
		return
	}
	err = winapi.RegSetValueEx(handle, syscall.StringToUTF16Ptr(name), 0, syscall.REG_DWORD, (*byte)(unsafe.Pointer(&val)), uint32(unsafe.Sizeof(val)))
	return
}
Example #2
0
func RegQuery(regname, installer_name, args string) (result string) {
	var handle, subtestkey syscall.Handle

	var csubkey uint32
	var list [1 << 10]string

	if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(regname), 0, syscall.KEY_READ, &handle) != nil {
		return
	}
	defer syscall.RegCloseKey(handle)
	csubkey = QueryKey(handle, &list)
	//	fmt.Println("the args is :", args)

	for j := uint32(0); j < csubkey; j++ {

		var buffer, uninstall_buf [syscall.MAX_LONG_PATH]uint16
		n := uint32(len(buffer))
		dwSize := uint32(len(uninstall_buf))
		var display_name string
		reg1 := regname + "\\" + list[j]
		//fmt.Println("reg1 is ", reg1)
		if reg1 == "Software\\Wow6432Node\\Xoreax\\IncrediBuild\\Builder" {
			if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(reg1), 0, syscall.KEY_READ, &subtestkey) == nil {

				e1 := syscall.RegQueryValueEx(subtestkey, syscall.StringToUTF16Ptr(args), nil, nil, (*byte)(unsafe.Pointer(&buffer[0])), &n)
				if e1 != nil {
					fmt.Println(e1)
				}
				result = syscall.UTF16ToString(buffer[:])
				//				fmt.Println(result, args)
				return
			}
		}
		if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(reg1), 0, syscall.KEY_READ, &subtestkey) == nil {
			syscall.RegQueryValueEx(subtestkey, syscall.StringToUTF16Ptr("DisplayName"), nil, nil, (*byte)(unsafe.Pointer(&buffer[0])), &n)
			display_name = syscall.UTF16ToString(buffer[:])

			if strings.Contains(display_name, installer_name) {

				if syscall.RegQueryValueEx(subtestkey, syscall.StringToUTF16Ptr(args), nil, nil, (*byte)(unsafe.Pointer(&uninstall_buf[0])), &dwSize) == nil {

					result = syscall.UTF16ToString(uninstall_buf[:])

					if result != "" {
						return
					}

				}
			}
		}
		defer syscall.RegCloseKey(subtestkey)
	}

	return
}
Example #3
0
func getPath() {
	var root syscall.Handle

	error := syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER, syscall.StringToUTF16Ptr(`Environment`),
		0, syscall.KEY_READ, &root)

	defer syscall.RegCloseKey(root)

	var buf [1 << 10]uint16

	var typ uint32
	n := uint32(len(buf)) // api expects array of bytes, not uint16
	if syscall.RegQueryValueEx(
		root, syscall.StringToUTF16Ptr(`Path`),
		nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {

	}

	path := syscall.UTF16ToString(buf[:])

	fmt.Println(path)

	if error != nil {
		fmt.Println(error)
		return
	}

}
Example #4
0
func nativeGetPortsList() ([]string, error) {
	subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\")
	if err != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	var h syscall.Handle
	if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}
	defer syscall.RegCloseKey(h)

	var valuesCount uint32
	if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	list := make([]string, valuesCount)
	for i := range list {
		var data [1024]uint16
		dataSize := uint32(len(data))
		var name [1024]uint16
		nameSize := uint32(len(name))
		if regEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil {
			return nil, &PortError{code: ErrorEnumeratingPorts}
		}
		list[i] = syscall.UTF16ToString(data[:])
	}
	return list, nil
}
func GetOperatingSystem() (string, error) {

	var h syscall.Handle

	// Default return value
	ret := "Unknown Operating System"

	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
		0,
		syscall.KEY_READ,
		&h); err != nil {
		return ret, err
	}
	defer syscall.RegCloseKey(h)

	var buf [1 << 10]uint16
	var typ uint32
	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16

	if err := syscall.RegQueryValueEx(h,
		syscall.StringToUTF16Ptr("ProductName"),
		nil,
		&typ,
		(*byte)(unsafe.Pointer(&buf[0])),
		&n); err != nil {
		return ret, err
	}
	ret = syscall.UTF16ToString(buf[:])

	return ret, nil
}
Example #6
0
// toEnglishName searches the registry for an English name of a time zone
// whose zone names are stdname and dstname and returns the English name.
func toEnglishName(stdname, dstname string) (string, error) {
	var zones syscall.Handle
	p, _ := syscall.UTF16PtrFromString(`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`)
	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, p, 0, syscall.KEY_READ, &zones); err != nil {
		return "", err
	}
	defer syscall.RegCloseKey(zones)

	var count uint32
	if err := syscall.RegQueryInfoKey(zones, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil); err != nil {
		return "", err
	}

	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
	for i := uint32(0); i < count; i++ {
		n := uint32(len(buf))
		if syscall.RegEnumKeyEx(zones, i, &buf[0], &n, nil, nil, nil, nil) != nil {
			continue
		}
		kname := syscall.UTF16ToString(buf[:])
		matched, err := matchZoneKey(zones, kname, stdname, dstname)
		if err == nil && matched {
			return kname, nil
		}
	}
	return "", errors.New(`English name for time zone "` + stdname + `" not found in registry`)
}
Example #7
0
func main() {
	getPath()
	return

	var root syscall.Handle

	error := syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER, syscall.StringToUTF16Ptr(`Control Panel\Accessibility\HighContrast`),
		0, syscall.KEY_READ, &root)

	defer syscall.RegCloseKey(root)

	var buf [1 << 10]uint16

	var typ uint32
	n := uint32(len(buf)) // api expects array of bytes, not uint16
	if syscall.RegQueryValueEx(
		root, syscall.StringToUTF16Ptr(`Previous High Contrast Scheme MUI Value`),
		nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {

	}

	path := syscall.UTF16ToString(buf[:])

	fmt.Println(path)

	if error != nil {
		fmt.Println(error)
		return
	}

}
// See http://blog.natefinch.com/2012/11/go-win-stuff.html
//
// This is used by workstationVMwareRoot in order to read some registry data.
func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value string, err error) {
	var h syscall.Handle
	err = syscall.RegOpenKeyEx(hive, syscall.StringToUTF16Ptr(subKeyPath), 0, syscall.KEY_READ, &h)
	if err != nil {
		return
	}
	defer syscall.RegCloseKey(h)

	var typ uint32
	var bufSize uint32
	err = syscall.RegQueryValueEx(
		h,
		syscall.StringToUTF16Ptr(valueName),
		nil,
		&typ,
		nil,
		&bufSize)
	if err != nil {
		return
	}

	data := make([]uint16, bufSize/2+1)
	err = syscall.RegQueryValueEx(
		h,
		syscall.StringToUTF16Ptr(valueName),
		nil,
		&typ,
		(*byte)(unsafe.Pointer(&data[0])),
		&bufSize)
	if err != nil {
		return
	}

	return syscall.UTF16ToString(data), nil
}
Example #9
0
func initMime() {
	var root syscall.Handle
	rootpathp, _ := syscall.UTF16PtrFromString(`\`)
	if syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, rootpathp,
		0, syscall.KEY_READ, &root) != nil {
		return
	}
	defer syscall.RegCloseKey(root)
	var count uint32
	if syscall.RegQueryInfoKey(root, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil) != nil {
		return
	}
	var buf [1 << 10]uint16
	for i := uint32(0); i < count; i++ {
		n := uint32(len(buf))
		if syscall.RegEnumKeyEx(root, i, &buf[0], &n, nil, nil, nil, nil) != nil {
			continue
		}
		ext := syscall.UTF16ToString(buf[:])
		if len(ext) < 2 || ext[0] != '.' { // looking for extensions only
			continue
		}
		var h syscall.Handle
		extpathp, _ := syscall.UTF16PtrFromString(`\` + ext)
		if syscall.RegOpenKeyEx(
			syscall.HKEY_CLASSES_ROOT, extpathp,
			0, syscall.KEY_READ, &h) != nil {
			continue
		}
		var typ uint32
		n = uint32(len(buf) * 2) // api expects array of bytes, not uint16
		contenttypep, _ := syscall.UTF16PtrFromString("Content Type")
		if syscall.RegQueryValueEx(
			h, contenttypep,
			nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {
			syscall.RegCloseKey(h)
			continue
		}
		syscall.RegCloseKey(h)
		if typ != syscall.REG_SZ { // null terminated strings only
			continue
		}
		mimeType := syscall.UTF16ToString(buf[:])
		setExtensionType(ext, mimeType)
	}
}
Example #10
0
func queryNetworkKey() (syscall.Handle, error) {
	var handle syscall.Handle
	err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(NETWORK_KEY), 0, syscall.KEY_READ, &handle)
	if err != nil {
		return 0, err
	}
	return handle, nil
}
Example #11
0
func OpenKey(parent syscall.Handle, path string) (*Key, error) {
	var h syscall.Handle
	e := syscall.RegOpenKeyEx(
		parent, syscall.StringToUTF16Ptr(path),
		0, syscall.KEY_ALL_ACCESS, &h)
	if e != nil {
		return nil, e
	}
	return &Key{Handle: h}, nil
}
Example #12
0
// TODO: Solve error in query DWORD registry
// Use to read value from windows registry the HKEY in the next definition HKLM, HKCU, HKCC, HKCR, HKU
func GetRegRaw(hkey, path, name string) (val []uint16, err error) {
	var handle syscall.Handle
	switch hkey {
	case "HKLM":
		err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCC":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_CONFIG, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCR":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_USERS, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	default:
		err = errors.New("Unknown HKEY: " + hkey)
		return
	}
	if err != nil {
		return
	}
	defer syscall.RegCloseKey(handle)
	var typ uint32
	var buffer [syscall.MAX_LONG_PATH]uint16
	n := uint32(len(buffer))
	err = syscall.RegQueryValueEx(handle, syscall.StringToUTF16Ptr(name), nil, &typ, (*byte)(unsafe.Pointer(&buffer[0])), &n)
	if err != nil {
		return
	}
	var lastNonNull uint64
	lastNonNull = 0
	length := uint64(len(buffer))
	for i := uint64(0); i < length; i++ {
		if buffer[i] != 0x00 {
			lastNonNull = (i + 1)
		}
	}
	if lastNonNull >= length {
		lastNonNull = (length - 1)
	}
	val = buffer[:lastNonNull]
	return
}
Example #13
0
// OpenKey opens a new key with path name relative to key k.
// It accepts any open key, including CURRENT_USER and others,
// and returns the new key and an error.
// The access parameter specifies desired access rights to the
// key to be opened.
func OpenKey(k Key, path string, access uint32) (Key, error) {
	p, err := syscall.UTF16PtrFromString(path)
	if err != nil {
		return 0, err
	}
	var subkey syscall.Handle
	err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
	if err != nil {
		return 0, err
	}
	return Key(subkey), nil
}
Example #14
0
func getVersionFromRegistry() (string, error) {
	var h syscall.Handle
	err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
		syscall.StringToUTF16Ptr("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
		0, syscall.KEY_READ, &h)
	if err != nil {
		return "", err
	}
	defer syscall.RegCloseKey(h)
	str, err := readRegString(h, "ProductName")
	if err != nil {
		return "", err
	}
	return str, nil
}
Example #15
0
// Use to remove key from windows registry the HKEY in the next definition HHLM, HKCU, HKCC, HKCR, HKU
func DeleteKey(hkey, path, name string) (err error) {
	var handle syscall.Handle
	switch hkey {
	case "HKLM":
		err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCC":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_CONFIG, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCR":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKCU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	case "HKU":
		err = syscall.RegOpenKeyEx(syscall.HKEY_USERS, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &handle)
	default:
		err = errors.New("Unknown HKEY: " + hkey)
		return
	}
	if err != nil {
		return
	}
	defer syscall.RegCloseKey(handle)
	err = winapi.RegDeleteKey(handle, syscall.StringToUTF16Ptr(name))
	return
}
Example #16
0
func GetKernelVersion() (*KernelVersionInfo, error) {

	var (
		h         syscall.Handle
		dwVersion uint32
		err       error
	)

	KVI := &KernelVersionInfo{"Unknown", 0, 0, 0}

	if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
		0,
		syscall.KEY_READ,
		&h); err != nil {
		return KVI, err
	}
	defer syscall.RegCloseKey(h)

	var buf [1 << 10]uint16
	var typ uint32
	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16

	if err = syscall.RegQueryValueEx(h,
		syscall.StringToUTF16Ptr("BuildLabEx"),
		nil,
		&typ,
		(*byte)(unsafe.Pointer(&buf[0])),
		&n); err != nil {
		return KVI, err
	}

	KVI.kvi = syscall.UTF16ToString(buf[:])

	// Important - docker.exe MUST be manifested for this API to return
	// the correct information.
	if dwVersion, err = syscall.GetVersion(); err != nil {
		return KVI, err
	}

	KVI.major = int(dwVersion & 0xFF)
	KVI.minor = int((dwVersion & 0XFF00) >> 8)
	KVI.build = int((dwVersion & 0xFFFF0000) >> 16)

	return KVI, nil
}
Example #17
0
func homeFromRegistry(sid string) (string, error) {
	var h syscall.Handle
	// This key will exist on all platforms we support the agent on (windows server 2008 and above)
	keyPath := fmt.Sprintf("Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%s", sid)
	err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
		syscall.StringToUTF16Ptr(keyPath),
		0, syscall.KEY_READ, &h)
	if err != nil {
		return "", err
	}
	defer syscall.RegCloseKey(h)
	str, err := readRegString(h, "ProfileImagePath")
	if err != nil {
		return "", err
	}
	return str, nil
}
Example #18
0
// OsRegGetValue read windows registry
func OsRegGetValue(path, key string) (v string) {
	var hKey syscall.Handle
	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &hKey); err != nil {
		return
	}
	defer syscall.RegCloseKey(hKey)
	var buf [1 << 10]uint16
	typ := uint32(0)
	n := uint32(len(buf) * 2)
	if err := syscall.RegQueryValueEx(hKey, syscall.StringToUTF16Ptr(key), nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n); err != nil {
		return
	}
	if typ != syscall.REG_SZ {
		return
	}
	return syscall.UTF16ToString(buf[:])
}
Example #19
0
// SetWinlogonShell sets the value of
// `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon` in
// the windows registry.
func SetWinlogonShell(value string) error {
	winlogonKey, err := syscall.UTF16PtrFromString(
		`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`)
	if err != nil {
		return err
	}

	shell, err := syscall.UTF16PtrFromString("Shell")
	if err != nil {
		return err
	}
	explorerexe, err := syscall.UTF16PtrFromString(value)
	if err != nil {
		return err
	}

	var winlogon syscall.Handle
	err = syscall.RegOpenKeyEx(
		syscall.HKEY_LOCAL_MACHINE,
		winlogonKey,
		0,
		syscall.KEY_WRITE,
		&winlogon,
	)
	if err != nil {
		return err
	}
	defer syscall.RegCloseKey(winlogon)
	err = regSetKeyValue(
		winlogon,
		nil,
		shell,
		syscall.REG_SZ,
		(*byte)(unsafe.Pointer(explorerexe)),
		uint32(len(value)*2),
	)
	if err != nil {
		return err
	}
	return nil
}
Example #20
0
// matchZoneKey checks if stdname and dstname match the corresponding "Std"
// and "Dlt" key values in the kname key stored under the open registry key zones.
func matchZoneKey(zones syscall.Handle, kname string, stdname, dstname string) (matched bool, err2 error) {
	var h syscall.Handle
	p, _ := syscall.UTF16PtrFromString(kname)
	if err := syscall.RegOpenKeyEx(zones, p, 0, syscall.KEY_READ, &h); err != nil {
		return false, err
	}
	defer syscall.RegCloseKey(h)

	s, err := getKeyValue(h, "Std")
	if err != nil {
		return false, err
	}
	if s != stdname {
		return false, nil
	}
	s, err = getKeyValue(h, "Dlt")
	if err != nil {
		return false, err
	}
	if s != dstname && dstname != stdname {
		return false, nil
	}
	return true, nil
}
Example #21
0
func queryAdapters(handle syscall.Handle) (*Interface, error) {
	var dev Interface
	var index uint32
	for {
		var length uint32 = 72
		adapter := make([]uint16, length)
		err := syscall.RegEnumKeyEx(handle, index, &adapter[0], &length, nil, nil, nil, nil)
		if err == NO_MORE_ITEMS {
			Log(Warning, "No more items in Windows Registry")
			break
		}
		index++
		adapterID := string(utf16.Decode(adapter[0:length]))
		adapterID = removeZeroes(adapterID)
		path := fmt.Sprintf("%s\\%s\\Connection", NETWORK_KEY, adapterID)
		var iHandle syscall.Handle
		err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(path), 0, syscall.KEY_READ, &iHandle)
		if err != nil {
			syscall.RegCloseKey(iHandle)
			continue
		}
		length = 1024
		aName := make([]byte, length)
		err = syscall.RegQueryValueEx(iHandle, syscall.StringToUTF16Ptr("Name"), nil, nil, &aName[0], &length)

		if err != nil {
			syscall.RegCloseKey(iHandle)
			continue
		}

		aNameUtf16 := make([]uint16, length/2)
		for i := 0; i < int(length)-2; i += 2 {
			aNameUtf16[i/2] = binary.LittleEndian.Uint16(aName[i:])
		}
		aNameUtf16[length/2-1] = 0

		adapterName := string(utf16.Decode(aNameUtf16))
		adapterName = removeZeroes(adapterName)
		Log(Warning, "AdapterName : %s, len : %d", adapterName, len(adapterName))

		var isInUse = false
		for _, i := range UsedInterfaces {
			if i == adapterName {
				isInUse = true
			}
		}
		if isInUse {
			Log(Warning, "Adapter already in use. Skipping.")
			continue
		}
		UsedInterfaces = append(UsedInterfaces, adapterName)

		tapname := fmt.Sprintf("%s%s%s", USERMODE_DEVICE_DIR, adapterID, TAP_SUFFIX)

		dev.file, err = syscall.CreateFile(syscall.StringToUTF16Ptr(tapname),
			syscall.GENERIC_WRITE|syscall.GENERIC_READ,
			0,
			nil,
			syscall.OPEN_EXISTING,
			syscall.FILE_ATTRIBUTE_SYSTEM|syscall.FILE_FLAG_OVERLAPPED,
			0)
		if err != nil {
			syscall.CloseHandle(dev.Handle)
			continue
		}
		Log(Info, "Acquired control over TAP interface: %s", adapterName)
		dev.Name = adapterID
		dev.Interface = adapterName
		return &dev, nil
	}
	return nil, nil
}