00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "includes.h"
00030 #include <windows.h>
00031
00032 #include "common.h"
00033 #include "wpa_supplicant_i.h"
00034 #include "eloop.h"
00035
00036 #ifndef WPASVC_NAME
00037 #define WPASVC_NAME TEXT("wpasvc")
00038 #endif
00039 #ifndef WPASVC_DISPLAY_NAME
00040 #define WPASVC_DISPLAY_NAME TEXT("wpa_supplicant service")
00041 #endif
00042 #ifndef WPASVC_DESCRIPTION
00043 #define WPASVC_DESCRIPTION \
00044 TEXT("Provides IEEE 802.1X and WPA/WPA2 supplicant functionality")
00045 #endif
00046
00047 static HANDLE kill_svc;
00048
00049 static SERVICE_STATUS_HANDLE svc_status_handle;
00050 static SERVICE_STATUS svc_status;
00051
00052
00053 #ifndef WPA_KEY_ROOT
00054 #define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
00055 #endif
00056 #ifndef WPA_KEY_PREFIX
00057 #define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
00058 #endif
00059
00060 #ifdef UNICODE
00061 #define TSTR "%S"
00062 #else
00063 #define TSTR "%s"
00064 #endif
00065
00066
00067 static int read_interface(struct wpa_global *global, HKEY _hk,
00068 const TCHAR *name)
00069 {
00070 HKEY hk;
00071 #define TBUFLEN 255
00072 TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN];
00073 DWORD buflen, val;
00074 LONG ret;
00075 struct wpa_interface iface;
00076 int skip_on_error = 0;
00077
00078 ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk);
00079 if (ret != ERROR_SUCCESS) {
00080 printf("Could not open wpa_supplicant interface key\n");
00081 return -1;
00082 }
00083
00084 os_memset(&iface, 0, sizeof(iface));
00085 iface.driver = "ndis";
00086
00087 buflen = sizeof(ctrl_interface);
00088 ret = RegQueryValueEx(hk, TEXT("ctrl_interface"), NULL, NULL,
00089 (LPBYTE) ctrl_interface, &buflen);
00090 if (ret == ERROR_SUCCESS) {
00091 ctrl_interface[TBUFLEN - 1] = TEXT('\0');
00092 wpa_unicode2ascii_inplace(ctrl_interface);
00093 printf("ctrl_interface[len=%d] '%s'\n",
00094 (int) buflen, (char *) ctrl_interface);
00095 iface.ctrl_interface = (char *) ctrl_interface;
00096 }
00097
00098 buflen = sizeof(adapter);
00099 ret = RegQueryValueEx(hk, TEXT("adapter"), NULL, NULL,
00100 (LPBYTE) adapter, &buflen);
00101 if (ret == ERROR_SUCCESS) {
00102 adapter[TBUFLEN - 1] = TEXT('\0');
00103 wpa_unicode2ascii_inplace(adapter);
00104 printf("adapter[len=%d] '%s'\n",
00105 (int) buflen, (char *) adapter);
00106 iface.ifname = (char *) adapter;
00107 }
00108
00109 buflen = sizeof(config);
00110 ret = RegQueryValueEx(hk, TEXT("config"), NULL, NULL,
00111 (LPBYTE) config, &buflen);
00112 if (ret == ERROR_SUCCESS) {
00113 config[sizeof(config) - 1] = '\0';
00114 wpa_unicode2ascii_inplace(config);
00115 printf("config[len=%d] '%s'\n",
00116 (int) buflen, (char *) config);
00117 iface.confname = (char *) config;
00118 }
00119
00120 buflen = sizeof(val);
00121 ret = RegQueryValueEx(hk, TEXT("skip_on_error"), NULL, NULL,
00122 (LPBYTE) &val, &buflen);
00123 if (ret == ERROR_SUCCESS && buflen == sizeof(val))
00124 skip_on_error = val;
00125
00126 RegCloseKey(hk);
00127
00128 if (wpa_supplicant_add_iface(global, &iface) == NULL) {
00129 if (skip_on_error)
00130 wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to "
00131 "initialization failure", iface.ifname);
00132 else
00133 return -1;
00134 }
00135
00136 return 0;
00137 }
00138
00139
00140 static int wpa_supplicant_thread(void)
00141 {
00142 int exitcode;
00143 struct wpa_params params;
00144 struct wpa_global *global;
00145 HKEY hk, ihk;
00146 DWORD val, buflen, i;
00147 LONG ret;
00148
00149 if (os_program_init())
00150 return -1;
00151
00152 os_memset(¶ms, 0, sizeof(params));
00153 params.wpa_debug_level = MSG_INFO;
00154
00155 ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX,
00156 0, KEY_QUERY_VALUE, &hk);
00157 if (ret != ERROR_SUCCESS) {
00158 printf("Could not open wpa_supplicant registry key\n");
00159 return -1;
00160 }
00161
00162 buflen = sizeof(val);
00163 ret = RegQueryValueEx(hk, TEXT("debug_level"), NULL, NULL,
00164 (LPBYTE) &val, &buflen);
00165 if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
00166 params.wpa_debug_level = val;
00167 }
00168
00169 buflen = sizeof(val);
00170 ret = RegQueryValueEx(hk, TEXT("debug_show_keys"), NULL, NULL,
00171 (LPBYTE) &val, &buflen);
00172 if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
00173 params.wpa_debug_show_keys = val;
00174 }
00175
00176 buflen = sizeof(val);
00177 ret = RegQueryValueEx(hk, TEXT("debug_timestamp"), NULL, NULL,
00178 (LPBYTE) &val, &buflen);
00179 if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
00180 params.wpa_debug_timestamp = val;
00181 }
00182
00183 buflen = sizeof(val);
00184 ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL,
00185 (LPBYTE) &val, &buflen);
00186 if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) {
00187 params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
00188 }
00189
00190 exitcode = 0;
00191 global = wpa_supplicant_init(¶ms);
00192 if (global == NULL) {
00193 printf("Failed to initialize wpa_supplicant\n");
00194 exitcode = -1;
00195 }
00196
00197 ret = RegOpenKeyEx(hk, TEXT("interfaces"), 0, KEY_ENUMERATE_SUB_KEYS,
00198 &ihk);
00199 RegCloseKey(hk);
00200 if (ret != ERROR_SUCCESS) {
00201 printf("Could not open wpa_supplicant interfaces registry "
00202 "key\n");
00203 return -1;
00204 }
00205
00206 for (i = 0; ; i++) {
00207 TCHAR name[255];
00208 DWORD namelen;
00209
00210 namelen = 255;
00211 ret = RegEnumKeyEx(ihk, i, name, &namelen, NULL, NULL, NULL,
00212 NULL);
00213
00214 if (ret == ERROR_NO_MORE_ITEMS)
00215 break;
00216
00217 if (ret != ERROR_SUCCESS) {
00218 printf("RegEnumKeyEx failed: 0x%x\n",
00219 (unsigned int) ret);
00220 break;
00221 }
00222
00223 if (namelen >= 255)
00224 namelen = 255 - 1;
00225 name[namelen] = '\0';
00226
00227 wpa_printf(MSG_DEBUG, "interface %d: %s\n", (int) i, name);
00228 if (read_interface(global, ihk, name) < 0)
00229 exitcode = -1;
00230 }
00231
00232 RegCloseKey(ihk);
00233
00234 if (exitcode == 0)
00235 exitcode = wpa_supplicant_run(global);
00236
00237 wpa_supplicant_deinit(global);
00238
00239 os_program_deinit();
00240
00241 return exitcode;
00242 }
00243
00244
00245 static DWORD svc_thread(LPDWORD param)
00246 {
00247 int ret = wpa_supplicant_thread();
00248
00249 svc_status.dwCurrentState = SERVICE_STOPPED;
00250 svc_status.dwWaitHint = 0;
00251 if (!SetServiceStatus(svc_status_handle, &svc_status)) {
00252 printf("SetServiceStatus() failed: %d\n",
00253 (int) GetLastError());
00254 }
00255
00256 return ret;
00257 }
00258
00259
00260 static int register_service(const TCHAR *exe)
00261 {
00262 SC_HANDLE svc, scm;
00263 SERVICE_DESCRIPTION sd;
00264
00265 printf("Registering service: " TSTR "\n", WPASVC_NAME);
00266
00267 scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
00268 if (!scm) {
00269 printf("OpenSCManager failed: %d\n", (int) GetLastError());
00270 return -1;
00271 }
00272
00273 svc = CreateService(scm, WPASVC_NAME, WPASVC_DISPLAY_NAME,
00274 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
00275 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
00276 exe, NULL, NULL, NULL, NULL, NULL);
00277
00278 if (!svc) {
00279 printf("CreateService failed: %d\n\n", (int) GetLastError());
00280 CloseServiceHandle(scm);
00281 return -1;
00282 }
00283
00284 os_memset(&sd, 0, sizeof(sd));
00285 sd.lpDescription = WPASVC_DESCRIPTION;
00286 if (!ChangeServiceConfig2(svc, SERVICE_CONFIG_DESCRIPTION, &sd)) {
00287 printf("ChangeServiceConfig2 failed: %d\n",
00288 (int) GetLastError());
00289
00290 }
00291
00292 CloseServiceHandle(svc);
00293 CloseServiceHandle(scm);
00294
00295 printf("Service registered successfully.\n");
00296
00297 return 0;
00298 }
00299
00300
00301 static int unregister_service(void)
00302 {
00303 SC_HANDLE svc, scm;
00304 SERVICE_STATUS status;
00305
00306 printf("Unregistering service: " TSTR "\n", WPASVC_NAME);
00307
00308 scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
00309 if (!scm) {
00310 printf("OpenSCManager failed: %d\n", (int) GetLastError());
00311 return -1;
00312 }
00313
00314 svc = OpenService(scm, WPASVC_NAME, SERVICE_ALL_ACCESS | DELETE);
00315 if (!svc) {
00316 printf("OpenService failed: %d\n\n", (int) GetLastError());
00317 CloseServiceHandle(scm);
00318 return -1;
00319 }
00320
00321 if (QueryServiceStatus(svc, &status)) {
00322 if (status.dwCurrentState != SERVICE_STOPPED) {
00323 printf("Service currently active - stopping "
00324 "service...\n");
00325 if (!ControlService(svc, SERVICE_CONTROL_STOP,
00326 &status)) {
00327 printf("ControlService failed: %d\n",
00328 (int) GetLastError());
00329 }
00330 Sleep(500);
00331 }
00332 }
00333
00334 if (DeleteService(svc)) {
00335 printf("Service unregistered successfully.\n");
00336 } else {
00337 printf("DeleteService failed: %d\n", (int) GetLastError());
00338 }
00339
00340 CloseServiceHandle(svc);
00341 CloseServiceHandle(scm);
00342
00343 return 0;
00344 }
00345
00346
00347 static void WINAPI service_ctrl_handler(DWORD control_code)
00348 {
00349 switch (control_code) {
00350 case SERVICE_CONTROL_INTERROGATE:
00351 break;
00352 case SERVICE_CONTROL_SHUTDOWN:
00353 case SERVICE_CONTROL_STOP:
00354 svc_status.dwCurrentState = SERVICE_STOP_PENDING;
00355 svc_status.dwWaitHint = 2000;
00356 eloop_terminate();
00357 SetEvent(kill_svc);
00358 break;
00359 }
00360
00361 if (!SetServiceStatus(svc_status_handle, &svc_status)) {
00362 printf("SetServiceStatus() failed: %d\n",
00363 (int) GetLastError());
00364 }
00365 }
00366
00367
00368 static void WINAPI service_start(DWORD argc, LPTSTR *argv)
00369 {
00370 DWORD id;
00371
00372 svc_status_handle = RegisterServiceCtrlHandler(WPASVC_NAME,
00373 service_ctrl_handler);
00374 if (svc_status_handle == (SERVICE_STATUS_HANDLE) 0) {
00375 printf("RegisterServiceCtrlHandler failed: %d\n",
00376 (int) GetLastError());
00377 return;
00378 }
00379
00380 os_memset(&svc_status, 0, sizeof(svc_status));
00381 svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00382 svc_status.dwCurrentState = SERVICE_START_PENDING;
00383 svc_status.dwWaitHint = 1000;
00384
00385 if (!SetServiceStatus(svc_status_handle, &svc_status)) {
00386 printf("SetServiceStatus() failed: %d\n",
00387 (int) GetLastError());
00388 return;
00389 }
00390
00391 kill_svc = CreateEvent(0, TRUE, FALSE, 0);
00392 if (!kill_svc) {
00393 printf("CreateEvent failed: %d\n", (int) GetLastError());
00394 return;
00395 }
00396
00397 if (CreateThread(0, 0, (LPTHREAD_START_ROUTINE) svc_thread, 0, 0, &id)
00398 == 0) {
00399 printf("CreateThread failed: %d\n", (int) GetLastError());
00400 return;
00401 }
00402
00403 if (svc_status.dwCurrentState == SERVICE_START_PENDING) {
00404 svc_status.dwCurrentState = SERVICE_RUNNING;
00405 svc_status.dwWaitHint = 0;
00406 svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
00407 SERVICE_ACCEPT_SHUTDOWN;
00408 }
00409
00410 if (!SetServiceStatus(svc_status_handle, &svc_status)) {
00411 printf("SetServiceStatus() failed: %d\n",
00412 (int) GetLastError());
00413 return;
00414 }
00415
00416
00417 WaitForSingleObject(kill_svc, INFINITE);
00418 }
00419
00420
00421 int main(int argc, char *argv[])
00422 {
00423 SERVICE_TABLE_ENTRY dt[] = {
00424 { WPASVC_NAME, service_start },
00425 { NULL, NULL }
00426 };
00427
00428 if (argc > 1) {
00429 if (os_strcmp(argv[1], "reg") == 0) {
00430 TCHAR *path;
00431 int ret;
00432
00433 if (argc < 3) {
00434 path = os_malloc(MAX_PATH * sizeof(TCHAR));
00435 if (path == NULL)
00436 return -1;
00437 if (!GetModuleFileName(NULL, path, MAX_PATH)) {
00438 printf("GetModuleFileName failed: "
00439 "%d\n", (int) GetLastError());
00440 os_free(path);
00441 return -1;
00442 }
00443 } else {
00444 path = wpa_strdup_tchar(argv[2]);
00445 if (path == NULL)
00446 return -1;
00447 }
00448 ret = register_service(path);
00449 os_free(path);
00450 return ret;
00451 } else if (os_strcmp(argv[1], "unreg") == 0) {
00452 return unregister_service();
00453 } else if (os_strcmp(argv[1], "app") == 0) {
00454 return wpa_supplicant_thread();
00455 }
00456 }
00457
00458 if (!StartServiceCtrlDispatcher(dt)) {
00459 printf("StartServiceCtrlDispatcher failed: %d\n",
00460 (int) GetLastError());
00461 }
00462
00463 return 0;
00464 }