1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * WPA Supplicant / main() function for Win32 service
3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify
6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as
7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation.
8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD
10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license.
11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details.
13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The root of wpa_supplicant configuration in registry is
15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant. This level includes global
16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * parameters and a 'interfaces' subkey with all the interface configuration
17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * (adapter to confname mapping). Each such mapping is a subkey that has
18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 'adapter' and 'config' values.
19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program can be run either as a normal command line application, e.g.,
21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * for debugging, with 'wpasvc.exe app' or as a Windows service. Service need
22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * to be registered with 'wpasvc.exe reg <full path to wpasvc.exe>'. After
23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * this, it can be started like any other Windows service (e.g., 'net start
24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * wpasvc') or it can be configured to start automatically through the Services
25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * tool in administrative tasks. The service can be unregistered with
26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 'wpasvc.exe unreg'.
27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h"
30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <windows.h>
31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h"
33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "wpa_supplicant_i.h"
34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eloop.h"
35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef WPASVC_NAME
37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define WPASVC_NAME TEXT("wpasvc")
38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef WPASVC_DISPLAY_NAME
40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define WPASVC_DISPLAY_NAME TEXT("wpa_supplicant service")
41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef WPASVC_DESCRIPTION
43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define WPASVC_DESCRIPTION \
44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectTEXT("Provides IEEE 802.1X and WPA/WPA2 supplicant functionality")
45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic HANDLE kill_svc;
48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic SERVICE_STATUS_HANDLE svc_status_handle;
50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic SERVICE_STATUS svc_status;
51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef WPA_KEY_ROOT
54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef WPA_KEY_PREFIX
57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef UNICODE
61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define TSTR "%S"
62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* UNICODE */
63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define TSTR "%s"
64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* UNICODE */
65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int read_interface(struct wpa_global *global, HKEY _hk,
68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			  const TCHAR *name)
69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HKEY hk;
71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define TBUFLEN 255
72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN];
73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	DWORD buflen;
74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	LONG ret;
75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct wpa_interface iface;
76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk);
78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret != ERROR_SUCCESS) {
79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("Could not open wpa_supplicant interface key\n");
80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memset(&iface, 0, sizeof(iface));
84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	iface.driver = "ndis";
85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(ctrl_interface);
87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("ctrl_interface"), NULL, NULL,
88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) ctrl_interface, &buflen);
89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS) {
90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		ctrl_interface[TBUFLEN - 1] = TEXT('\0');
91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		wpa_unicode2ascii_inplace(ctrl_interface);
92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("ctrl_interface[len=%d] '%s'\n",
93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) buflen, (char *) ctrl_interface);
94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		iface.ctrl_interface = (char *) ctrl_interface;
95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(adapter);
98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("adapter"), NULL, NULL,
99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) adapter, &buflen);
100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS) {
101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		adapter[TBUFLEN - 1] = TEXT('\0');
102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		wpa_unicode2ascii_inplace(adapter);
103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("adapter[len=%d] '%s'\n",
104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) buflen, (char *) adapter);
105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		iface.ifname = (char *) adapter;
106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(config);
109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("config"), NULL, NULL,
110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) config, &buflen);
111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS) {
112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		config[sizeof(config) - 1] = '\0';
113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		wpa_unicode2ascii_inplace(config);
114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("config[len=%d] '%s'\n",
115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) buflen, (char *) config);
116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		iface.confname = (char *) config;
117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	RegCloseKey(hk);
120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (wpa_supplicant_add_iface(global, &iface) == NULL)
122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_supplicant_thread(void)
129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int exitcode;
131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct wpa_params params;
132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct wpa_global *global;
133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HKEY hk, ihk;
134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	DWORD val, buflen, i;
135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	LONG ret;
136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (os_program_init())
138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memset(&params, 0, sizeof(params));
141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	params.wpa_debug_level = MSG_INFO;
142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX,
144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   0, KEY_QUERY_VALUE, &hk);
145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret != ERROR_SUCCESS) {
146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("Could not open wpa_supplicant registry key\n");
147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(val);
151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("debug_level"), NULL, NULL,
152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) &val, &buflen);
153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		params.wpa_debug_level = val;
155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(val);
158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("debug_show_keys"), NULL, NULL,
159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) &val, &buflen);
160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		params.wpa_debug_show_keys = val;
162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	buflen = sizeof(val);
165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL,
166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			      (LPBYTE) &val, &buflen);
167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) {
168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	exitcode = 0;
172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	global = wpa_supplicant_init(&params);
173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (global == NULL) {
174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("Failed to initialize wpa_supplicant\n");
175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		exitcode = -1;
176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ret = RegOpenKeyEx(hk, TEXT("interfaces"), 0, KEY_ENUMERATE_SUB_KEYS,
179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   &ihk);
180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	RegCloseKey(hk);
181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (ret != ERROR_SUCCESS) {
182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("Could not open wpa_supplicant interfaces registry "
183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       "key\n");
184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; ; i++) {
188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		TCHAR name[255];
189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		DWORD namelen;
190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		namelen = 255;
192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		ret = RegEnumKeyEx(ihk, i, name, &namelen, NULL, NULL, NULL,
193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				   NULL);
194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (ret == ERROR_NO_MORE_ITEMS)
196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (ret != ERROR_SUCCESS) {
199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			printf("RegEnumKeyEx failed: 0x%x\n",
200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			       (unsigned int) ret);
201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (namelen >= 255)
205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			namelen = 255 - 1;
206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		name[namelen] = '\0';
207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		wpa_printf(MSG_DEBUG, "interface %d: %s\n", (int) i, name);
209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (read_interface(global, ihk, name) < 0)
210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			exitcode = -1;
211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	RegCloseKey(ihk);
214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (exitcode == 0)
216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		exitcode = wpa_supplicant_run(global);
217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	wpa_supplicant_deinit(global);
219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_program_deinit();
221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return exitcode;
223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic DWORD svc_thread(LPDWORD param)
227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int ret = wpa_supplicant_thread();
229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status.dwCurrentState = SERVICE_STOPPED;
231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status.dwWaitHint = 0;
232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!SetServiceStatus(svc_status_handle, &svc_status)) {
233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("SetServiceStatus() failed: %d\n",
234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return ret;
238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int register_service(const TCHAR *exe)
242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SC_HANDLE svc, scm;
244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SERVICE_DESCRIPTION sd;
245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	printf("Registering service: " TSTR "\n", WPASVC_NAME);
247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!scm) {
250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("OpenSCManager failed: %d\n", (int) GetLastError());
251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc = CreateService(scm, WPASVC_NAME, WPASVC_DISPLAY_NAME,
255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			    SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			    exe, NULL, NULL, NULL, NULL, NULL);
258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!svc) {
260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("CreateService failed: %d\n\n", (int) GetLastError());
261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		CloseServiceHandle(scm);
262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memset(&sd, 0, sizeof(sd));
266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sd.lpDescription = WPASVC_DESCRIPTION;
267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!ChangeServiceConfig2(svc, SERVICE_CONFIG_DESCRIPTION, &sd)) {
268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("ChangeServiceConfig2 failed: %d\n",
269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		/* This is not a fatal error, so continue anyway. */
271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	CloseServiceHandle(svc);
274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	CloseServiceHandle(scm);
275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	printf("Service registered successfully.\n");
277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int unregister_service(void)
283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SC_HANDLE svc, scm;
285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SERVICE_STATUS status;
286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	printf("Unregistering service: " TSTR "\n", WPASVC_NAME);
288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!scm) {
291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("OpenSCManager failed: %d\n", (int) GetLastError());
292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc = OpenService(scm, WPASVC_NAME, SERVICE_ALL_ACCESS | DELETE);
296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!svc) {
297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("OpenService failed: %d\n\n", (int) GetLastError());
298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		CloseServiceHandle(scm);
299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (QueryServiceStatus(svc, &status)) {
303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (status.dwCurrentState != SERVICE_STOPPED) {
304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			printf("Service currently active - stopping "
305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			       "service...\n");
306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (!ControlService(svc, SERVICE_CONTROL_STOP,
307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					    &status)) {
308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				printf("ControlService failed: %d\n",
309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				       (int) GetLastError());
310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			}
311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			Sleep(500);
312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (DeleteService(svc)) {
316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("Service unregistered successfully.\n");
317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	} else {
318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("DeleteService failed: %d\n", (int) GetLastError());
319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	CloseServiceHandle(svc);
322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	CloseServiceHandle(scm);
323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void WINAPI service_ctrl_handler(DWORD control_code)
329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	switch (control_code) {
331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	case SERVICE_CONTROL_INTERROGATE:
332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		break;
333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	case SERVICE_CONTROL_SHUTDOWN:
334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	case SERVICE_CONTROL_STOP:
335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		svc_status.dwCurrentState = SERVICE_STOP_PENDING;
336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		svc_status.dwWaitHint = 2000;
337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop_terminate();
338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		SetEvent(kill_svc);
339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		break;
340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!SetServiceStatus(svc_status_handle, &svc_status)) {
343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("SetServiceStatus() failed: %d\n",
344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void WINAPI service_start(DWORD argc, LPTSTR *argv)
350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	DWORD id;
352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status_handle = RegisterServiceCtrlHandler(WPASVC_NAME,
354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						       service_ctrl_handler);
355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (svc_status_handle == (SERVICE_STATUS_HANDLE) 0) {
356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("RegisterServiceCtrlHandler failed: %d\n",
357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memset(&svc_status, 0, sizeof(svc_status));
362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status.dwCurrentState = SERVICE_START_PENDING;
364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	svc_status.dwWaitHint = 1000;
365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!SetServiceStatus(svc_status_handle, &svc_status)) {
367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("SetServiceStatus() failed: %d\n",
368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	kill_svc = CreateEvent(0, TRUE, FALSE, 0);
373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!kill_svc) {
374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("CreateEvent failed: %d\n", (int) GetLastError());
375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (CreateThread(0, 0, (LPTHREAD_START_ROUTINE) svc_thread, 0, 0, &id)
379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	    == 0) {
380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("CreateThread failed: %d\n", (int) GetLastError());
381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (svc_status.dwCurrentState == SERVICE_START_PENDING) {
385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		svc_status.dwCurrentState = SERVICE_RUNNING;
386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		svc_status.dwWaitHint = 0;
387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			SERVICE_ACCEPT_SHUTDOWN;
389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!SetServiceStatus(svc_status_handle, &svc_status)) {
392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("SetServiceStatus() failed: %d\n",
393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* wait until service gets killed */
398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WaitForSingleObject(kill_svc, INFINITE);
399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint main(int argc, char *argv[])
403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SERVICE_TABLE_ENTRY dt[] = {
405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		{ WPASVC_NAME, service_start },
406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		{ NULL, NULL }
407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	};
408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (argc > 1) {
410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (os_strcmp(argv[1], "reg") == 0) {
411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			TCHAR *path;
412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			int ret;
413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (argc < 3) {
415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				path = os_malloc(MAX_PATH * sizeof(TCHAR));
416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				if (path == NULL)
417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					return -1;
418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				if (!GetModuleFileName(NULL, path, MAX_PATH)) {
419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					printf("GetModuleFileName failed: "
420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					       "%d\n", (int) GetLastError());
421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					os_free(path);
422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					return -1;
423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				}
424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			} else {
425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				path = wpa_strdup_tchar(argv[2]);
426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				if (path == NULL)
427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					return -1;
428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			}
429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			ret = register_service(path);
430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_free(path);
431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			return ret;
432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		} else if (os_strcmp(argv[1], "unreg") == 0) {
433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			return unregister_service();
434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		} else if (os_strcmp(argv[1], "app") == 0) {
435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			return wpa_supplicant_thread();
436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (!StartServiceCtrlDispatcher(dt)) {
440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("StartServiceCtrlDispatcher failed: %d\n",
441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
446