static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
{
	int i;

#define STR(t) write_str(f, #t, ssid)
#define INT(t) write_int(f, #t, ssid->t, 0)
#define INTe(t) write_int(f, #t, ssid->eap.t, 0)
#define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
#define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def)

	STR(ssid);
	INT(scan_ssid);
	write_bssid(f, ssid);
	write_psk(f, ssid);
	write_proto(f, ssid);
	write_key_mgmt(f, ssid);
	INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
	write_pairwise(f, ssid);
	write_group(f, ssid);
	write_auth_alg(f, ssid);
	STR(bgscan);
	STR(autoscan);
#ifdef IEEE8021X_EAPOL
	write_eap(f, ssid);
	STR(identity);
	STR(anonymous_identity);
	STR(password);
	STR(ca_cert);
	STR(ca_path);
	STR(client_cert);
	STR(private_key);
	STR(private_key_passwd);
	STR(dh_file);
	STR(subject_match);
	STR(altsubject_match);
	STR(ca_cert2);
	STR(ca_path2);
	STR(client_cert2);
	STR(private_key2);
	STR(private_key2_passwd);
	STR(dh_file2);
	STR(subject_match2);
	STR(altsubject_match2);
	STR(phase1);
	STR(phase2);
	STR(pcsc);
	STR(pin);
	STR(engine_id);
	STR(key_id);
	STR(cert_id);
	STR(ca_cert_id);
	STR(key2_id);
	STR(pin2);
	STR(engine2_id);
	STR(cert2_id);
	STR(ca_cert2_id);
	INTe(engine);
	INTe(engine2);
	INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
#endif /* IEEE8021X_EAPOL */
	for (i = 0; i < 4; i++)
		write_wep_key(f, i, ssid);
	INT(wep_tx_keyidx);
	INT(priority);
#ifdef IEEE8021X_EAPOL
	INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
	STR(pac_file);
	INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
#endif /* IEEE8021X_EAPOL */
	INT(mode);
	INT(frequency);
	write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
	INT(disabled);
	INT(peerkey);
#ifdef CONFIG_IEEE80211W
	write_int(f, "ieee80211w", ssid->ieee80211w,
		  MGMT_FRAME_PROTECTION_DEFAULT);
#endif /* CONFIG_IEEE80211W */
	STR(id_str);
#ifdef CONFIG_P2P
	write_p2p_client_list(f, ssid);
	write_psk_list(f, ssid);
#endif /* CONFIG_P2P */
	INT(dtim_period);
	INT(beacon_int);

#undef STR
#undef INT
#undef INT_DEF
}
static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
{
	int i;

#define STR(t) write_str(f, #t, ssid)
#define INT(t) write_int(f, #t, ssid->t, 0)
#define INTe(t) write_int(f, #t, ssid->eap.t, 0)
#define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
#define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def)

	STR(ssid);
	INT(scan_ssid);
	write_bssid(f, ssid);
	write_bssid_hint(f, ssid);
	write_str(f, "bssid_blacklist", ssid);
	write_str(f, "bssid_whitelist", ssid);
	write_psk(f, ssid);
	INT(mem_only_psk);
	STR(sae_password);
	write_proto(f, ssid);
	write_key_mgmt(f, ssid);
	INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
	write_pairwise(f, ssid);
	write_group(f, ssid);
	write_group_mgmt(f, ssid);
	write_auth_alg(f, ssid);
	STR(bgscan);
	STR(autoscan);
	STR(scan_freq);
#ifdef IEEE8021X_EAPOL
	write_eap(f, ssid);
	STR(identity);
	STR(anonymous_identity);
	STR(password);
	STR(ca_cert);
	STR(ca_path);
	STR(client_cert);
	STR(private_key);
	STR(private_key_passwd);
	STR(dh_file);
	STR(subject_match);
	STR(altsubject_match);
	STR(domain_suffix_match);
	STR(domain_match);
	STR(ca_cert2);
	STR(ca_path2);
	STR(client_cert2);
	STR(private_key2);
	STR(private_key2_passwd);
	STR(dh_file2);
	STR(subject_match2);
	STR(altsubject_match2);
	STR(domain_suffix_match2);
	STR(domain_match2);
	STR(phase1);
	STR(phase2);
	STR(pcsc);
	STR(pin);
	STR(engine_id);
	STR(key_id);
	STR(cert_id);
	STR(ca_cert_id);
	STR(key2_id);
	STR(pin2);
	STR(engine2_id);
	STR(cert2_id);
	STR(ca_cert2_id);
	INTe(engine);
	INTe(engine2);
	INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
	STR(openssl_ciphers);
	INTe(erp);
#endif /* IEEE8021X_EAPOL */
	for (i = 0; i < 4; i++)
		write_wep_key(f, i, ssid);
	INT(wep_tx_keyidx);
	INT(priority);
#ifdef IEEE8021X_EAPOL
	INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
	STR(pac_file);
	INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
	INTe(ocsp);
	INT_DEFe(sim_num, DEFAULT_USER_SELECTED_SIM);
#endif /* IEEE8021X_EAPOL */
	INT(mode);
	INT(no_auto_peer);
	INT(frequency);
	INT(fixed_freq);
#ifdef CONFIG_ACS
	INT(acs);
#endif /* CONFIG_ACS */
	write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
	INT(disabled);
	INT(mixed_cell);
	INT(vht);
	INT_DEF(ht, 1);
	INT(ht40);
	INT(max_oper_chwidth);
	INT(vht_center_freq1);
	INT(vht_center_freq2);
	INT(pbss);
	INT(wps_disabled);
	INT(fils_dh_group);
#ifdef CONFIG_IEEE80211W
	write_int(f, "ieee80211w", ssid->ieee80211w,
		  MGMT_FRAME_PROTECTION_DEFAULT);
#endif /* CONFIG_IEEE80211W */
	STR(id_str);
#ifdef CONFIG_P2P
	write_go_p2p_dev_addr(f, ssid);
	write_p2p_client_list(f, ssid);
	write_psk_list(f, ssid);
#endif /* CONFIG_P2P */
	INT(ap_max_inactivity);
	INT(dtim_period);
	INT(beacon_int);
#ifdef CONFIG_MACSEC
	INT(macsec_policy);
	write_mka_cak(f, ssid);
	write_mka_ckn(f, ssid);
	INT(macsec_integ_only);
	INT(macsec_port);
	INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER);
#endif /* CONFIG_MACSEC */
#ifdef CONFIG_HS20
	INT(update_identifier);
#endif /* CONFIG_HS20 */
	write_int(f, "mac_addr", ssid->mac_addr, -1);
#ifdef CONFIG_MESH
	STR(mesh_basic_rates);
	INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
	INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT);
	INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT);
	INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT);
	INT_DEF(mesh_rssi_threshold, DEFAULT_MESH_RSSI_THRESHOLD);
#endif /* CONFIG_MESH */
	INT(wpa_ptk_rekey);
	INT(group_rekey);
	INT(ignore_broadcast_ssid);
#ifdef CONFIG_DPP
	STR(dpp_connector);
	STR(dpp_netaccesskey);
	INT(dpp_netaccesskey_expiry);
	STR(dpp_csign);
#endif /* CONFIG_DPP */
	INT(owe_group);
#ifdef CONFIG_HT_OVERRIDES
	INT_DEF(disable_ht, DEFAULT_DISABLE_HT);
	INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40);
	INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI);
	INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC);
	INT(ht40_intolerant);
	INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU);
	INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR);
	INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY);
	STR(ht_mcs);
#endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
	INT(disable_vht);
	INT(vht_capa);
	INT(vht_capa_mask);
	INT_DEF(vht_rx_mcs_nss_1, -1);
	INT_DEF(vht_rx_mcs_nss_2, -1);
	INT_DEF(vht_rx_mcs_nss_3, -1);
	INT_DEF(vht_rx_mcs_nss_4, -1);
	INT_DEF(vht_rx_mcs_nss_5, -1);
	INT_DEF(vht_rx_mcs_nss_6, -1);
	INT_DEF(vht_rx_mcs_nss_7, -1);
	INT_DEF(vht_rx_mcs_nss_8, -1);
	INT_DEF(vht_tx_mcs_nss_1, -1);
	INT_DEF(vht_tx_mcs_nss_2, -1);
	INT_DEF(vht_tx_mcs_nss_3, -1);
	INT_DEF(vht_tx_mcs_nss_4, -1);
	INT_DEF(vht_tx_mcs_nss_5, -1);
	INT_DEF(vht_tx_mcs_nss_6, -1);
	INT_DEF(vht_tx_mcs_nss_7, -1);
	INT_DEF(vht_tx_mcs_nss_8, -1);
#endif /* CONFIG_VHT_OVERRIDES */

#undef STR
#undef INT
#undef INT_DEF
}
static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
{
	int i, errors = 0;
	HKEY nhk, netw;
	LONG ret;
	TCHAR name[5];

	ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_CREATE_SUB_KEY, &nhk);
	if (ret != ERROR_SUCCESS) {
		wpa_printf(MSG_DEBUG, "WINREG: Could not open networks key "
			   "for subkey addition: error 0x%x (%d)",
			   (unsigned int) ret, (int) GetLastError());
		return 0;
	}

#ifdef UNICODE
	wsprintf(name, L"%04d", id);
#else /* UNICODE */
	os_snprintf(name, sizeof(name), "%04d", id);
#endif /* UNICODE */
	ret = RegCreateKeyEx(nhk, name, 0, NULL, 0, KEY_WRITE, NULL, &netw,
			     NULL);
	RegCloseKey(nhk);
	if (ret != ERROR_SUCCESS) {
		wpa_printf(MSG_DEBUG, "WINREG: Could not add network key '%s':"
			   " error 0x%x (%d)",
			   name, (unsigned int) ret, (int) GetLastError());
		return -1;
	}

#define STR(t) write_str(netw, #t, ssid)
#define INT(t) write_int(netw, #t, ssid->t, 0)
#define INTe(t) write_int(netw, #t, ssid->eap.t, 0)
#define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
#define INT_DEFe(t, def) write_int(netw, #t, ssid->eap.t, def)

	STR(ssid);
	INT(scan_ssid);
	write_bssid(netw, ssid);
	write_psk(netw, ssid);
	write_proto(netw, ssid);
	write_key_mgmt(netw, ssid);
	write_pairwise(netw, ssid);
	write_group(netw, ssid);
	write_auth_alg(netw, ssid);
#ifdef IEEE8021X_EAPOL
	write_eap(netw, ssid);
	STR(identity);
	STR(anonymous_identity);
	STR(password);
	STR(ca_cert);
	STR(ca_path);
	STR(client_cert);
	STR(private_key);
	STR(private_key_passwd);
	STR(dh_file);
	STR(subject_match);
	STR(altsubject_match);
	STR(ca_cert2);
	STR(ca_path2);
	STR(client_cert2);
	STR(private_key2);
	STR(private_key2_passwd);
	STR(dh_file2);
	STR(subject_match2);
	STR(altsubject_match2);
	STR(phase1);
	STR(phase2);
	STR(pcsc);
	STR(pin);
	STR(engine_id);
	STR(key_id);
	STR(cert_id);
	STR(ca_cert_id);
	STR(key2_id);
	STR(pin2);
	STR(engine2_id);
	STR(cert2_id);
	STR(ca_cert2_id);
	INTe(engine);
	INTe(engine2);
	INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
#endif /* IEEE8021X_EAPOL */
	for (i = 0; i < 4; i++)
		write_wep_key(netw, i, ssid);
	INT(wep_tx_keyidx);
	INT(priority);
#ifdef IEEE8021X_EAPOL
	INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
	STR(pac_file);
	INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
#endif /* IEEE8021X_EAPOL */
	INT(mode);
	INT(proactive_key_caching);
	INT(disabled);
	INT(peerkey);
#ifdef CONFIG_IEEE80211W
	INT(ieee80211w);
#endif /* CONFIG_IEEE80211W */
	STR(id_str);

#undef STR
#undef INT
#undef INT_DEF

	RegCloseKey(netw);

	return errors ? -1 : 0;
}