18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / Configuration backend: Windows registry
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This file implements a configuration backend for Windows registry. All the
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration information is stored in the registry and the format for
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * network configuration fields is same as described in the sample
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration file, wpa_supplicant.conf.
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Configuration data is in
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * \a HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant\\configs
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * key. Each configuration profile has its own key under this. In terms of text
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * files, each profile would map to a separate text file with possibly multiple
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * networks. Under each profile, there is a networks key that lists all
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * networks as a subkey. Each network has set of values in the same way as
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * network block in the configuration file. In addition, blobs subkey has
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * possible blobs as values.
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Example network configuration block:
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * \verbatim
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtHKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   ssid="example"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   key_mgmt=WPA-PSK
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt\endverbatim
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "uuid.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_KEY_ROOT
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_KEY_PREFIX
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TSTR "%S"
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TSTR "%s"
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_blobs(struct wpa_config *config, HKEY hk)
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config_blob *blob;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY bhk;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD i;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(hk, TEXT("blobs"), 0, KEY_QUERY_VALUE, &bhk);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "blobs key");
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0; /* assume no blobs */
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; ; i++) {
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TNAMELEN 255
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		TCHAR name[TNAMELEN];
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char data[4096];
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DWORD namelen, datalen, type;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		namelen = TNAMELEN;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		datalen = sizeof(data);
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = RegEnumValue(bhk, i, name, &namelen, NULL, &type,
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (LPBYTE) data, &datalen);
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == ERROR_NO_MORE_ITEMS)
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret != ERROR_SUCCESS) {
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "RegEnumValue failed: 0x%x",
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (unsigned int) ret);
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (namelen >= TNAMELEN)
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			namelen = TNAMELEN - 1;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		name[namelen] = TEXT('\0');
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_unicode2ascii_inplace(name);
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (datalen >= sizeof(data))
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			datalen = sizeof(data) - 1;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_MSGDUMP, "blob %d: field='%s' len %d",
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (int) i, name, (int) datalen);
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob = os_zalloc(sizeof(*blob));
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (blob == NULL) {
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->name = os_strdup((char *) name);
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->data = os_malloc(datalen);
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (blob->name == NULL || blob->data == NULL) {
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_config_free_blob(blob);
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(blob->data, data, datalen);
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->len = datalen;
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_set_blob(config, blob);
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(bhk);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_reg_dword(HKEY hk, const TCHAR *name, int *_val)
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD val, buflen;
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buflen = sizeof(val);
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) &val, &buflen);
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, TSTR "=%d", name, (int) val);
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*_val = val;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * wpa_config_read_reg_string(HKEY hk, const TCHAR *name)
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD buflen;
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR *val;
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buflen = 0;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegQueryValueEx(hk, name, NULL, NULL, NULL, &buflen);
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS)
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = os_malloc(buflen);
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == NULL)
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) val, &buflen);
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(val);
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_unicode2ascii_inplace(val);
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, TSTR "=%s", name, (char *) val);
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return (char *) val;
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_global_uuid(struct wpa_config *config, HKEY hk)
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *str;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = 0;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	str = wpa_config_read_reg_string(hk, TEXT("uuid"));
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (str == NULL)
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (uuid_str2bin(str, config->uuid))
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = -1;
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(str);
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_global_os_version(struct wpa_config *config,
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     HKEY hk)
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *str;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = 0;
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	str = wpa_config_read_reg_string(hk, TEXT("os_version"));
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (str == NULL)
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(str, config->os_version, 4))
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = -1;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(str);
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_global(struct wpa_config *config, HKEY hk)
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	int val;
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("ap_scan"), &config->ap_scan);
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  &config->fast_reauth);
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->dot11RSNAConfigPMKLifetime);
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk,
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  TEXT("dot11RSNAConfigPMKReauthThreshold"),
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *)
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  &config->dot11RSNAConfigPMKReauthThreshold);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->dot11RSNAConfigSATimeout);
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("update_config"),
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  &config->update_config);
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_reg_dword(hk, TEXT("eapol_version"),
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      &config->eapol_version) == 0) {
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (config->eapol_version < 1 ||
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    config->eapol_version > 2) {
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid EAPOL version (%d)",
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->eapol_version);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->ctrl_interface = wpa_config_read_reg_string(
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("ctrl_interface"));
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_global_uuid(config, hk))
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->device_name = wpa_config_read_reg_string(
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("device_name"));
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->manufacturer = wpa_config_read_reg_string(
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("manufacturer"));
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->model_name = wpa_config_read_reg_string(
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("model_name"));
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->serial_number = wpa_config_read_reg_string(
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("serial_number"));
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *t = wpa_config_read_reg_string(
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hk, TEXT("device_type"));
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (t && wps_dev_type_str2bin(t, config->device_type))
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(t);
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->config_methods = wpa_config_read_reg_string(
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("config_methods"));
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_global_os_version(config, hk))
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  &config->wps_cred_processing);
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->p2p_ssid_postfix = wpa_config_read_reg_string(
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hk, TEXT("p2p_ssid_postfix"));
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("p2p_group_idle"),
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->p2p_group_idle);
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("bss_max_count"),
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->bss_max_count);
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("filter_ssids"),
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  &config->filter_ssids);
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("max_num_sta"),
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->max_num_sta);
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("disassoc_low_ack"),
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  (int *) &config->disassoc_low_ack);
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
275d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("okc"), &config->okc);
276d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_config_read_reg_dword(hk, TEXT("pmf"), &val);
277d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	config->pmf = val;
278d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_ssid * wpa_config_read_network(HKEY hk, const TCHAR *netw,
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 int id)
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY nhk;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD i;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(hk, netw, 0, KEY_QUERY_VALUE, &nhk);
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "network '" TSTR "'", netw);
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_MSGDUMP, "Start of a new network '" TSTR "'", netw);
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = os_zalloc(sizeof(*ssid));
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RegCloseKey(nhk);
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->id = id;
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_set_network_defaults(ssid);
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; ; i++) {
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		TCHAR name[255], data[1024];
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DWORD namelen, datalen, type;
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		namelen = 255;
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		datalen = sizeof(data);
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = RegEnumValue(nhk, i, name, &namelen, NULL, &type,
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (LPBYTE) data, &datalen);
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == ERROR_NO_MORE_ITEMS)
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret != ERROR_SUCCESS) {
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "RegEnumValue failed: 0x%x",
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (unsigned int) ret);
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (namelen >= 255)
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			namelen = 255 - 1;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		name[namelen] = TEXT('\0');
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (datalen >= 1024)
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			datalen = 1024 - 1;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		data[datalen] = TEXT('\0');
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_unicode2ascii_inplace(name);
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_unicode2ascii_inplace(data);
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_set(ssid, (char *) name, (char *) data, 0) < 0)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(nhk);
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->passphrase) {
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->psk_set) {
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Both PSK and passphrase "
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "configured for network '" TSTR "'.", netw);
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_update_psk(ssid);
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) {
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Group cipher cannot be stronger than the pairwise cipher. */
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Removed CCMP from group cipher "
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "list since it was not allowed for pairwise "
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "cipher for network '" TSTR "'.", netw);
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->group_cipher &= ~WPA_CIPHER_CCMP;
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (errors) {
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_free_ssid(ssid);
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = NULL;
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ssid;
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_read_networks(struct wpa_config *config, HKEY hk)
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY nhk;
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD i;
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_ENUMERATE_SUB_KEYS,
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   &nhk);
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Could not open wpa_supplicant networks "
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "registry key");
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; ; i++) {
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		TCHAR name[255];
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DWORD namelen;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		namelen = 255;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   NULL);
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == ERROR_NO_MORE_ITEMS)
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret != ERROR_SUCCESS) {
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x",
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (unsigned int) ret);
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (namelen >= 255)
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			namelen = 255 - 1;
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		name[namelen] = '\0';
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_config_read_network(nhk, name, i);
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL) {
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to parse network "
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "profile '%s'.", name);
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (head == NULL) {
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			head = tail = ssid;
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tail->next = ssid;
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tail = ssid;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_add_prio_network(config, ssid)) {
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to add network profile "
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "'%s' to priority list.", name);
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(nhk);
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	config->ssid = head;
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43764f47c5c24428834677459e048420f86e3514c20Dmitry Shmidtstruct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR buf[256];
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config *config;
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY hk;
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44564f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt	if (name == NULL)
44664f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt		return NULL;
44764f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt	if (cfgp)
44864f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt		config = cfgp;
44964f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt	else
45064f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt		config = wpa_config_alloc_empty(NULL, NULL);
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config == NULL)
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Reading configuration profile '%s'", name);
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_QUERY_VALUE, &hk);
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configuration registry HKLM\\" TSTR, buf);
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(config);
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_global(config, hk))
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_networks(config, hk))
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_read_blobs(config, hk))
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_debug_dump_networks(config);
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(hk);
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (errors) {
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_free(config);
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		config = NULL;
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return config;
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_write_reg_dword(HKEY hk, const TCHAR *name, int val,
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      int def)
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD _val = val;
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == def) {
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RegDeleteValue(hk, name);
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegSetValueEx(hk, name, 0, REG_DWORD, (LPBYTE) &_val,
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    sizeof(_val));
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "WINREG: Failed to set %s=%d: error %d",
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   name, val, (int) GetLastError());
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_write_reg_string(HKEY hk, const char *name,
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       const char *val)
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR *_name, *_val;
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_name = wpa_strdup_tchar(name);
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_name == NULL)
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == NULL) {
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RegDeleteValue(hk, _name);
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(_name);
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_val = wpa_strdup_tchar(val);
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (_val == NULL) {
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(_name);
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegSetValueEx(hk, _name, 0, REG_SZ, (BYTE *) _val,
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    (os_strlen(val) + 1) * sizeof(TCHAR));
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "WINREG: Failed to set %s='%s': "
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "error %d", name, val, (int) GetLastError());
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(_name);
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(_val);
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(_name);
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(_val);
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_write_global(struct wpa_config *config, HKEY hk)
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "ctrl_interface",
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    config->ctrl_interface);
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("eapol_version"),
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->eapol_version,
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DEFAULT_EAPOL_VERSION);
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("ap_scan"), config->ap_scan,
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DEFAULT_AP_SCAN);
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("fast_reauth"),
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->fast_reauth, DEFAULT_FAST_REAUTH);
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->dot11RSNAConfigPMKLifetime, 0);
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk,
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   TEXT("dot11RSNAConfigPMKReauthThreshold"),
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->dot11RSNAConfigPMKReauthThreshold,
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   0);
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->dot11RSNAConfigSATimeout, 0);
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("update_config"),
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->update_config,
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   0);
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!is_nil_uuid(config->uuid)) {
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char buf[40];
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		uuid_bin2str(config->uuid, buf, sizeof(buf));
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "uuid", buf);
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "device_name", config->device_name);
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "model_name", config->model_name);
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "model_number", config->model_number);
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "serial_number",
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    config->serial_number);
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf = wps_dev_type_bin2str(config->device_type,
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   _buf, sizeof(_buf));
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "device_type", buf);
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "config_methods",
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    config->config_methods);
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (WPA_GET_BE32(config->os_version)) {
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char vbuf[10];
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(vbuf, sizeof(vbuf), "%08x",
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    WPA_GET_BE32(config->os_version));
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "os_version", vbuf);
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->wps_cred_processing, 0);
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "p2p_ssid_postfix",
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    config->p2p_ssid_postfix);
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("p2p_group_idle"),
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->p2p_group_idle, 0);
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("bss_max_count"),
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->bss_max_count,
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DEFAULT_BSS_MAX_COUNT);
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("filter_ssids"),
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->filter_ssids, 0);
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("max_num_sta"),
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->max_num_sta, DEFAULT_MAX_NUM_STA);
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("disassoc_low_ack"),
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   config->disassoc_low_ack, 0);
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
622d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
623d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
624d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_delete_subkeys(HKEY hk, const TCHAR *key)
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY nhk;
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, errors = 0;
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(hk, key, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &nhk);
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WINREG: Could not open key '" TSTR
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "' for subkey deletion: error 0x%x (%d)", key,
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (unsigned int) ret, (int) GetLastError());
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; ; i++) {
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		TCHAR name[255];
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DWORD namelen;
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		namelen = 255;
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   NULL);
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == ERROR_NO_MORE_ITEMS)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret != ERROR_SUCCESS) {
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x (%d)",
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (unsigned int) ret, (int) GetLastError());
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (namelen >= 255)
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			namelen = 255 - 1;
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		name[namelen] = TEXT('\0');
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = RegDeleteKey(nhk, name);
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret != ERROR_SUCCESS) {
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "RegDeleteKey failed: 0x%x (%d)",
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (unsigned int) ret, (int) GetLastError());
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(nhk);
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_str(HKEY hk, const char *field, struct wpa_ssid *ssid)
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value = wpa_config_get(ssid, field);
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, field, value);
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_int(HKEY hk, const char *field, int value, int def)
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char val[20];
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == def)
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(val, sizeof(val), "%d", value);
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, field, val);
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_bssid(HKEY hk, struct wpa_ssid *ssid)
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value = wpa_config_get(ssid, "bssid");
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "bssid", value);
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_psk(HKEY hk, struct wpa_ssid *ssid)
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value = wpa_config_get(ssid, "psk");
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_write_reg_string(hk, "psk", value);
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_proto(HKEY hk, struct wpa_ssid *ssid)
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->proto == DEFAULT_PROTO)
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "proto");
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "proto", value);
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_key_mgmt(HKEY hk, struct wpa_ssid *ssid)
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "key_mgmt");
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "key_mgmt", value);
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_pairwise(HKEY hk, struct wpa_ssid *ssid)
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "pairwise");
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "pairwise", value);
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_group(HKEY hk, struct wpa_ssid *ssid)
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->group_cipher == DEFAULT_GROUP)
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "group");
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "group", value);
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_auth_alg(HKEY hk, struct wpa_ssid *ssid)
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->auth_alg == 0)
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "auth_alg");
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "auth_alg", value);
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_eap(HKEY hk, struct wpa_ssid *ssid)
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, "eap");
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value == NULL)
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value[0])
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, "eap", value);
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(value);
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void write_wep_key(HKEY hk, int idx, struct wpa_ssid *ssid)
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char field[20], *value;
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(field, sizeof(field), "wep_key%d", idx);
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	value = wpa_config_get(ssid, field);
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (value) {
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_write_reg_string(hk, field, value);
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(value);
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, errors = 0;
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY nhk, netw;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR name[5];
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_CREATE_SUB_KEY, &nhk);
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WINREG: Could not open networks key "
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "for subkey addition: error 0x%x (%d)",
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (unsigned int) ret, (int) GetLastError());
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wsprintf(name, L"%04d", id);
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(name, sizeof(name), "%04d", id);
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegCreateKeyEx(nhk, name, 0, NULL, 0, KEY_WRITE, NULL, &netw,
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     NULL);
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(nhk);
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WINREG: Could not add network key '%s':"
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " error 0x%x (%d)",
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   name, (unsigned int) ret, (int) GetLastError());
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STR(t) write_str(netw, #t, ssid)
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INT(t) write_int(netw, #t, ssid->t, 0)
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTe(t) write_int(netw, #t, ssid->eap.t, 0)
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INT_DEFe(t, def) write_int(netw, #t, ssid->eap.t, def)
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ssid);
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(scan_ssid);
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_bssid(netw, ssid);
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_psk(netw, ssid);
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_proto(netw, ssid);
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_key_mgmt(netw, ssid);
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_pairwise(netw, ssid);
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_group(netw, ssid);
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_auth_alg(netw, ssid);
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	write_eap(netw, ssid);
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(identity);
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(anonymous_identity);
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(password);
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_cert);
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_path);
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(client_cert);
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(private_key);
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(private_key_passwd);
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(dh_file);
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(subject_match);
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(altsubject_match);
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_cert2);
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_path2);
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(client_cert2);
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(private_key2);
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(private_key2_passwd);
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(dh_file2);
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(subject_match2);
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(altsubject_match2);
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(phase1);
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(phase2);
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(pcsc);
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(pin);
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(engine_id);
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(key_id);
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(cert_id);
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_cert_id);
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(key2_id);
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(pin2);
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(engine2_id);
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(cert2_id);
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(ca_cert2_id);
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INTe(engine);
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INTe(engine2);
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 4; i++)
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		write_wep_key(netw, i, ssid);
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(wep_tx_keyidx);
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(priority);
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(pac_file);
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(mode);
920d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	write_int(netw, "proactive_key_caching", ssid->proactive_key_caching,
921d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		  -1);
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(disabled);
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	INT(peerkey);
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
925d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	write_int(netw, "ieee80211w", ssid->ieee80211w,
926d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		  MGMT_FRAME_PROTECTION_DEFAULT);
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	STR(id_str);
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef STR
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef INT
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef INT_DEF
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(netw);
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_config_write_blob(HKEY hk, struct wpa_config_blob *blob)
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY bhk;
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR *name;
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegCreateKeyEx(hk, TEXT("blobs"), 0, NULL, 0, KEY_WRITE, NULL,
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     &bhk, NULL);
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WINREG: Could not add blobs key: "
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "error 0x%x (%d)",
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (unsigned int) ret, (int) GetLastError());
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	name = wpa_strdup_tchar(blob->name);
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegSetValueEx(bhk, name, 0, REG_BINARY, blob->data,
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    blob->len);
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "WINREG: Failed to set blob %s': "
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "error 0x%x (%d)", blob->name, (unsigned int) ret,
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (int) GetLastError());
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RegCloseKey(bhk);
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(name);
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(name);
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(bhk);
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_config_write(const char *name, struct wpa_config *config)
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR buf[256];
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HKEY hk;
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	LONG ret;
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int errors = 0;
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config_blob *blob;
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_SET_VALUE | DELETE, &hk);
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != ERROR_SUCCESS) {
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configuration registry %s: error %d", buf,
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (int) GetLastError());
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_write_global(config, hk)) {
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to write global configuration "
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "data");
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_delete_subkeys(hk, TEXT("networks"));
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (ssid = config->ssid, id = 0; ssid; ssid = ssid->next, id++) {
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue; /* do not save temporary WPS networks */
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_write_network(hk, ssid, id))
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegDeleteKey(hk, TEXT("blobs"));
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (blob = config->blobs; blob; blob = blob->next) {
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_write_blob(hk, blob))
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RegCloseKey(hk);
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Configuration '%s' written %ssuccessfully",
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   name, errors ? "un" : "");
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return errors ? -1 : 0;
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1026