main_winsvc.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / main() function for Win32 service 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2006, 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 * The root of wpa_supplicant configuration in registry is 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant. This level includes global 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters and a 'interfaces' subkey with all the interface configuration 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (adapter to confname mapping). Each such mapping is a subkey that has 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 'adapter' and 'config' values. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program can be run either as a normal command line application, e.g., 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for debugging, with 'wpasvc.exe app' or as a Windows service. Service need 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to be registered with 'wpasvc.exe reg <full path to wpasvc.exe>'. After 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this, it can be started like any other Windows service (e.g., 'net start 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpasvc') or it can be configured to start automatically through the Services 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tool in administrative tasks. The service can be unregistered with 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 'wpasvc.exe unreg'. 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <windows.h> 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPASVC_NAME 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPASVC_NAME TEXT("wpasvc") 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPASVC_DISPLAY_NAME 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPASVC_DISPLAY_NAME TEXT("wpa_supplicant service") 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPASVC_DESCRIPTION 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPASVC_DESCRIPTION \ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTEXT("Provides IEEE 802.1X and WPA/WPA2 supplicant functionality") 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic HANDLE kill_svc; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic SERVICE_STATUS_HANDLE svc_status_handle; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic SERVICE_STATUS svc_status; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_KEY_ROOT 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_KEY_PREFIX 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant") 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TSTR "%S" 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TSTR "%s" 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int read_interface(struct wpa_global *global, HKEY _hk, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const TCHAR *name) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HKEY hk; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TBUFLEN 255 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN]; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD buflen, val; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LONG ret; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface iface; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int skip_on_error = 0; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open wpa_supplicant interface key\n"); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver = "ndis"; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(ctrl_interface); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("ctrl_interface"), NULL, NULL, 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) ctrl_interface, &buflen); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctrl_interface[TBUFLEN - 1] = TEXT('\0'); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_unicode2ascii_inplace(ctrl_interface); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("ctrl_interface[len=%d] '%s'\n", 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) buflen, (char *) ctrl_interface); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ctrl_interface = (char *) ctrl_interface; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(adapter); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("adapter"), NULL, NULL, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) adapter, &buflen); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS) { 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt adapter[TBUFLEN - 1] = TEXT('\0'); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_unicode2ascii_inplace(adapter); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("adapter[len=%d] '%s'\n", 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) buflen, (char *) adapter); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ifname = (char *) adapter; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(config); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("config"), NULL, NULL, 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) config, &buflen); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS) { 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config[sizeof(config) - 1] = '\0'; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_unicode2ascii_inplace(config); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("config[len=%d] '%s'\n", 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) buflen, (char *) config); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.confname = (char *) config; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(val); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("skip_on_error"), NULL, NULL, 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) &val, &buflen); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt skip_on_error = val; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_add_iface(global, &iface) == NULL) { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (skip_on_error) 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to " 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialization failure", iface.ifname); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_thread(void) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int exitcode; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_params params; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HKEY hk, ihk; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD val, buflen, i; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LONG ret; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_program_init()) 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_debug_level = MSG_INFO; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX, 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, KEY_QUERY_VALUE, &hk); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open wpa_supplicant registry key\n"); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(val); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_level"), NULL, NULL, 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) &val, &buflen); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_debug_level = val; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(val); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_show_keys"), NULL, NULL, 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) &val, &buflen); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_debug_show_keys = val; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(val); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_timestamp"), NULL, NULL, 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) &val, &buflen); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_debug_timestamp = val; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(val); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL, 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) &val, &buflen); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt"; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exitcode = 0; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = wpa_supplicant_init(¶ms); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global == NULL) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to initialize wpa_supplicant\n"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exitcode = -1; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(hk, TEXT("interfaces"), 0, KEY_ENUMERATE_SUB_KEYS, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &ihk); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open wpa_supplicant interfaces registry " 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key\n"); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR name[255]; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD namelen; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt namelen = 255; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegEnumKeyEx(ihk, i, name, &namelen, NULL, NULL, NULL, 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == ERROR_NO_MORE_ITEMS) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("RegEnumKeyEx failed: 0x%x\n", 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) ret); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (namelen >= 255) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt namelen = 255 - 1; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[namelen] = '\0'; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "interface %d: %s\n", (int) i, name); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (read_interface(global, ihk, name) < 0) 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exitcode = -1; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(ihk); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (exitcode == 0) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exitcode = wpa_supplicant_run(global); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deinit(global); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_program_deinit(); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return exitcode; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic DWORD svc_thread(LPDWORD param) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = wpa_supplicant_thread(); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwCurrentState = SERVICE_STOPPED; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwWaitHint = 0; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("SetServiceStatus() failed: %d\n", 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int register_service(const TCHAR *exe) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SC_HANDLE svc, scm; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_DESCRIPTION sd; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Registering service: " TSTR "\n", WPASVC_NAME); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!scm) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("OpenSCManager failed: %d\n", (int) GetLastError()); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc = CreateService(scm, WPASVC_NAME, WPASVC_DISPLAY_NAME, 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exe, NULL, NULL, NULL, NULL, NULL); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!svc) { 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("CreateService failed: %d\n\n", (int) GetLastError()); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(scm); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sd, 0, sizeof(sd)); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sd.lpDescription = WPASVC_DESCRIPTION; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ChangeServiceConfig2(svc, SERVICE_CONFIG_DESCRIPTION, &sd)) { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("ChangeServiceConfig2 failed: %d\n", 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This is not a fatal error, so continue anyway. */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(svc); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(scm); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Service registered successfully.\n"); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int unregister_service(void) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SC_HANDLE svc, scm; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_STATUS status; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unregistering service: " TSTR "\n", WPASVC_NAME); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!scm) { 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("OpenSCManager failed: %d\n", (int) GetLastError()); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc = OpenService(scm, WPASVC_NAME, SERVICE_ALL_ACCESS | DELETE); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!svc) { 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("OpenService failed: %d\n\n", (int) GetLastError()); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(scm); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (QueryServiceStatus(svc, &status)) { 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status.dwCurrentState != SERVICE_STOPPED) { 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Service currently active - stopping " 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "service...\n"); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ControlService(svc, SERVICE_CONTROL_STOP, 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &status)) { 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("ControlService failed: %d\n", 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Sleep(500); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (DeleteService(svc)) { 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Service unregistered successfully.\n"); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("DeleteService failed: %d\n", (int) GetLastError()); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(svc); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseServiceHandle(scm); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void WINAPI service_ctrl_handler(DWORD control_code) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (control_code) { 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVICE_CONTROL_INTERROGATE: 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVICE_CONTROL_SHUTDOWN: 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVICE_CONTROL_STOP: 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwCurrentState = SERVICE_STOP_PENDING; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwWaitHint = 2000; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SetEvent(kill_svc); 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("SetServiceStatus() failed: %d\n", 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void WINAPI service_start(DWORD argc, LPTSTR *argv) 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD id; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status_handle = RegisterServiceCtrlHandler(WPASVC_NAME, 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt service_ctrl_handler); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (svc_status_handle == (SERVICE_STATUS_HANDLE) 0) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("RegisterServiceCtrlHandler failed: %d\n", 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&svc_status, 0, sizeof(svc_status)); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwCurrentState = SERVICE_START_PENDING; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwWaitHint = 1000; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("SetServiceStatus() failed: %d\n", 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kill_svc = CreateEvent(0, TRUE, FALSE, 0); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!kill_svc) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("CreateEvent failed: %d\n", (int) GetLastError()); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CreateThread(0, 0, (LPTHREAD_START_ROUTINE) svc_thread, 0, 0, &id) 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("CreateThread failed: %d\n", (int) GetLastError()); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (svc_status.dwCurrentState == SERVICE_START_PENDING) { 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwCurrentState = SERVICE_RUNNING; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwWaitHint = 0; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_ACCEPT_SHUTDOWN; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("SetServiceStatus() failed: %d\n", 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* wait until service gets killed */ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WaitForSingleObject(kill_svc, INFINITE); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVICE_TABLE_ENTRY dt[] = { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { WPASVC_NAME, service_start }, 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { NULL, NULL } 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc > 1) { 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(argv[1], "reg") == 0) { 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR *path; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc < 3) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path = os_malloc(MAX_PATH * sizeof(TCHAR)); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (path == NULL) 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!GetModuleFileName(NULL, path, MAX_PATH)) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("GetModuleFileName failed: " 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d\n", (int) GetLastError()); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(path); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path = wpa_strdup_tchar(argv[2]); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (path == NULL) 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = register_service(path); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(path); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(argv[1], "unreg") == 0) { 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return unregister_service(); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(argv[1], "app") == 0) { 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_supplicant_thread(); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!StartServiceCtrlDispatcher(dt)) { 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("StartServiceCtrlDispatcher failed: %d\n", 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 459