1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant / main() function for Win32 service 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * The root of wpa_supplicant configuration in registry is 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant. This level includes global 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * parameters and a 'interfaces' subkey with all the interface configuration 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * (adapter to confname mapping). Each such mapping is a subkey that has 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 'adapter' and 'config' values. 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program can be run either as a normal command line application, e.g., 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * for debugging, with 'wpasvc.exe app' or as a Windows service. Service need 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * to be registered with 'wpasvc.exe reg <full path to wpasvc.exe>'. After 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * this, it can be started like any other Windows service (e.g., 'net start 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpasvc') or it can be configured to start automatically through the Services 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tool in administrative tasks. The service can be unregistered with 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 'wpasvc.exe unreg'. 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <windows.h> 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wpa_supplicant_i.h" 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPASVC_NAME 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPASVC_NAME TEXT("wpasvc") 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPASVC_DISPLAY_NAME 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPASVC_DISPLAY_NAME TEXT("wpa_supplicant service") 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPASVC_DESCRIPTION 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPASVC_DESCRIPTION \ 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtTEXT("Provides IEEE 802.1X and WPA/WPA2 supplicant functionality") 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic HANDLE kill_svc; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic SERVICE_STATUS_HANDLE svc_status_handle; 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic SERVICE_STATUS svc_status; 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPA_KEY_ROOT 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPA_KEY_PREFIX 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant") 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define TSTR "%S" 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* UNICODE */ 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define TSTR "%s" 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* UNICODE */ 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int read_interface(struct wpa_global *global, HKEY _hk, 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const TCHAR *name) 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HKEY hk; 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define TBUFLEN 255 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN]; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD buflen, val; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LONG ret; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_interface iface; 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int skip_on_error = 0; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk); 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret != ERROR_SUCCESS) { 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not open wpa_supplicant interface key\n"); 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface.driver = "ndis"; 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(ctrl_interface); 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("ctrl_interface"), NULL, NULL, 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) ctrl_interface, &buflen); 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS) { 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_interface[TBUFLEN - 1] = TEXT('\0'); 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_unicode2ascii_inplace(ctrl_interface); 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("ctrl_interface[len=%d] '%s'\n", 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) buflen, (char *) ctrl_interface); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface.ctrl_interface = (char *) ctrl_interface; 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(adapter); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("adapter"), NULL, NULL, 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) adapter, &buflen); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS) { 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt adapter[TBUFLEN - 1] = TEXT('\0'); 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_unicode2ascii_inplace(adapter); 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("adapter[len=%d] '%s'\n", 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) buflen, (char *) adapter); 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface.ifname = (char *) adapter; 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(config); 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("config"), NULL, NULL, 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) config, &buflen); 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS) { 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt config[sizeof(config) - 1] = '\0'; 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_unicode2ascii_inplace(config); 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("config[len=%d] '%s'\n", 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) buflen, (char *) config); 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface.confname = (char *) config; 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(val); 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("skip_on_error"), NULL, NULL, 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) &val, &buflen); 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt skip_on_error = val; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RegCloseKey(hk); 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_supplicant_add_iface(global, &iface) == NULL) { 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (skip_on_error) 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to " 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "initialization failure", iface.ifname); 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_supplicant_thread(void) 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int exitcode; 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_params params; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global *global; 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HKEY hk, ihk; 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD val, buflen, i; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LONG ret; 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_program_init()) 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.wpa_debug_level = MSG_INFO; 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX, 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0, KEY_QUERY_VALUE, &hk); 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret != ERROR_SUCCESS) { 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not open wpa_supplicant registry key\n"); 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(val); 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_level"), NULL, NULL, 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) &val, &buflen); 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.wpa_debug_level = val; 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(val); 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_show_keys"), NULL, NULL, 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) &val, &buflen); 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.wpa_debug_show_keys = val; 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(val); 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_timestamp"), NULL, NULL, 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) &val, &buflen); 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val)) { 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.wpa_debug_timestamp = val; 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buflen = sizeof(val); 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL, 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPBYTE) &val, &buflen); 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) { 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt"; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exitcode = 0; 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global = wpa_supplicant_init(¶ms); 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global == NULL) { 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Failed to initialize wpa_supplicant\n"); 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exitcode = -1; 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegOpenKeyEx(hk, TEXT("interfaces"), 0, KEY_ENUMERATE_SUB_KEYS, 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &ihk); 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RegCloseKey(hk); 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret != ERROR_SUCCESS) { 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not open wpa_supplicant interfaces registry " 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "key\n"); 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; ; i++) { 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TCHAR name[255]; 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD namelen; 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt namelen = 255; 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = RegEnumKeyEx(ihk, i, name, &namelen, NULL, NULL, NULL, 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL); 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == ERROR_NO_MORE_ITEMS) 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret != ERROR_SUCCESS) { 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("RegEnumKeyEx failed: 0x%x\n", 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned int) ret); 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (namelen >= 255) 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt namelen = 255 - 1; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt name[namelen] = '\0'; 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "interface %d: %s\n", (int) i, name); 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (read_interface(global, ihk, name) < 0) 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exitcode = -1; 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RegCloseKey(ihk); 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (exitcode == 0) 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exitcode = wpa_supplicant_run(global); 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_deinit(global); 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_program_deinit(); 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return exitcode; 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DWORD svc_thread(LPDWORD param) 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = wpa_supplicant_thread(); 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwCurrentState = SERVICE_STOPPED; 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwWaitHint = 0; 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("SetServiceStatus() failed: %d\n", 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int register_service(const TCHAR *exe) 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SC_HANDLE svc, scm; 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_DESCRIPTION sd; 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Registering service: " TSTR "\n", WPASVC_NAME); 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!scm) { 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("OpenSCManager failed: %d\n", (int) GetLastError()); 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc = CreateService(scm, WPASVC_NAME, WPASVC_DISPLAY_NAME, 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exe, NULL, NULL, NULL, NULL, NULL); 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!svc) { 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("CreateService failed: %d\n\n", (int) GetLastError()); 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(scm); 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&sd, 0, sizeof(sd)); 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sd.lpDescription = WPASVC_DESCRIPTION; 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!ChangeServiceConfig2(svc, SERVICE_CONFIG_DESCRIPTION, &sd)) { 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("ChangeServiceConfig2 failed: %d\n", 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* This is not a fatal error, so continue anyway. */ 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(svc); 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(scm); 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Service registered successfully.\n"); 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int unregister_service(void) 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SC_HANDLE svc, scm; 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_STATUS status; 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Unregistering service: " TSTR "\n", WPASVC_NAME); 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!scm) { 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("OpenSCManager failed: %d\n", (int) GetLastError()); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc = OpenService(scm, WPASVC_NAME, SERVICE_ALL_ACCESS | DELETE); 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!svc) { 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("OpenService failed: %d\n\n", (int) GetLastError()); 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(scm); 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (QueryServiceStatus(svc, &status)) { 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status.dwCurrentState != SERVICE_STOPPED) { 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Service currently active - stopping " 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "service...\n"); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!ControlService(svc, SERVICE_CONTROL_STOP, 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &status)) { 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("ControlService failed: %d\n", 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt Sleep(500); 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (DeleteService(svc)) { 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Service unregistered successfully.\n"); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("DeleteService failed: %d\n", (int) GetLastError()); 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(svc); 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseServiceHandle(scm); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void WINAPI service_ctrl_handler(DWORD control_code) 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (control_code) { 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SERVICE_CONTROL_INTERROGATE: 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SERVICE_CONTROL_SHUTDOWN: 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SERVICE_CONTROL_STOP: 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwCurrentState = SERVICE_STOP_PENDING; 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwWaitHint = 2000; 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_terminate(); 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SetEvent(kill_svc); 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("SetServiceStatus() failed: %d\n", 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void WINAPI service_start(DWORD argc, LPTSTR *argv) 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD id; 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status_handle = RegisterServiceCtrlHandler(WPASVC_NAME, 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt service_ctrl_handler); 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (svc_status_handle == (SERVICE_STATUS_HANDLE) 0) { 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("RegisterServiceCtrlHandler failed: %d\n", 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&svc_status, 0, sizeof(svc_status)); 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwCurrentState = SERVICE_START_PENDING; 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwWaitHint = 1000; 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("SetServiceStatus() failed: %d\n", 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kill_svc = CreateEvent(0, TRUE, FALSE, 0); 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!kill_svc) { 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("CreateEvent failed: %d\n", (int) GetLastError()); 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (CreateThread(0, 0, (LPTHREAD_START_ROUTINE) svc_thread, 0, 0, &id) 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt == 0) { 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("CreateThread failed: %d\n", (int) GetLastError()); 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (svc_status.dwCurrentState == SERVICE_START_PENDING) { 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwCurrentState = SERVICE_RUNNING; 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwWaitHint = 0; 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_ACCEPT_SHUTDOWN; 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SetServiceStatus(svc_status_handle, &svc_status)) { 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("SetServiceStatus() failed: %d\n", 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* wait until service gets killed */ 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WaitForSingleObject(kill_svc, INFINITE); 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint main(int argc, char *argv[]) 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SERVICE_TABLE_ENTRY dt[] = { 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { WPASVC_NAME, service_start }, 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { NULL, NULL } 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (argc > 1) { 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_strcmp(argv[1], "reg") == 0) { 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TCHAR *path; 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (argc < 3) { 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = os_malloc(MAX_PATH * sizeof(TCHAR)); 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!GetModuleFileName(NULL, path, MAX_PATH)) { 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("GetModuleFileName failed: " 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "%d\n", (int) GetLastError()); 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(path); 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = wpa_strdup_tchar(argv[2]); 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = register_service(path); 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(path); 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (os_strcmp(argv[1], "unreg") == 0) { 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return unregister_service(); 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (os_strcmp(argv[1], "app") == 0) { 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_supplicant_thread(); 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!StartServiceCtrlDispatcher(dt)) { 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("StartServiceCtrlDispatcher failed: %d\n", 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 465