/*
 * WPA Supplicant / Windows Named Pipe -based control interface
 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "eloop.h"
#include "config.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "wpa_supplicant_i.h"
#include "ctrl_iface.h"
#include "common/wpa_ctrl.h"

#ifdef __MINGW32_VERSION
/* mingw-w32api v3.1 does not yet include sddl.h, so define needed parts here
 */
#define SDDL_REVISION_1 1
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
	LPCSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG);
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
	LPCWSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG);
#ifdef UNICODE
#define ConvertStringSecurityDescriptorToSecurityDescriptor \
ConvertStringSecurityDescriptorToSecurityDescriptorW
#else
#define ConvertStringSecurityDescriptorToSecurityDescriptor \
ConvertStringSecurityDescriptorToSecurityDescriptorA
#endif
#else /* __MINGW32_VERSION */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <sddl.h>
#endif /* __MINGW32_VERSION */

#ifndef WPA_SUPPLICANT_NAMED_PIPE
#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
#endif
#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)

/* Per-interface ctrl_iface */

#define REQUEST_BUFSIZE 256
#define REPLY_BUFSIZE 4096

struct ctrl_iface_priv;

/**
 * struct wpa_ctrl_dst - Internal data structure of control interface clients
 *
 * This structure is used to store information about registered control
 * interface monitors into struct wpa_supplicant. This data is private to
 * ctrl_iface_named_pipe.c and should not be touched directly from other files.
 */
struct wpa_ctrl_dst {
	/* Note: OVERLAPPED must be the first member of struct wpa_ctrl_dst */
	OVERLAPPED overlap;
	struct wpa_ctrl_dst *next, *prev;
	struct ctrl_iface_priv *priv;
	HANDLE pipe;
	int attached;
	int debug_level;
	int errors;
	char req_buf[REQUEST_BUFSIZE];
	char *rsp_buf;
	int used;
};


struct ctrl_iface_priv {
	struct wpa_supplicant *wpa_s;
	struct wpa_ctrl_dst *ctrl_dst;
	SECURITY_ATTRIBUTES attr;
	int sec_attr_set;
};


static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
					   int level, const char *buf,
					   size_t len);

static void ctrl_close_pipe(struct wpa_ctrl_dst *dst);
static void wpa_supplicant_ctrl_iface_receive(void *, void *);
static VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes,
					     LPOVERLAPPED overlap);

struct wpa_global_dst;
static void global_close_pipe(struct wpa_global_dst *dst);
static void wpa_supplicant_global_iface_receive(void *eloop_data,
						void *user_ctx);
static VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes,
					       LPOVERLAPPED overlap);


static int ctrl_broken_pipe(HANDLE pipe, int used)
{
	DWORD err;

	if (PeekNamedPipe(pipe, NULL, 0, NULL, NULL, NULL))
		return 0;

	err = GetLastError();
	if (err == ERROR_BROKEN_PIPE || (err == ERROR_BAD_PIPE && used))
		return 1;
	return 0;
}


static void ctrl_flush_broken_pipes(struct ctrl_iface_priv *priv)
{
	struct wpa_ctrl_dst *dst, *next;

	dst = priv->ctrl_dst;

	while (dst) {
		next = dst->next;
		if (ctrl_broken_pipe(dst->pipe, dst->used)) {
			wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
				   dst);
			ctrl_close_pipe(dst);
		}
		dst = next;
	}
}


static int ctrl_open_pipe(struct ctrl_iface_priv *priv)
{
	struct wpa_ctrl_dst *dst;
	DWORD err;
	TCHAR name[256];

	dst = os_zalloc(sizeof(*dst));
	if (dst == NULL)
		return -1;
	wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);

	dst->priv = priv;
	dst->debug_level = MSG_INFO;
	dst->pipe = INVALID_HANDLE_VALUE;

	dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
	if (dst->overlap.hEvent == NULL) {
		wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
			   (int) GetLastError());
		goto fail;
	}

	eloop_register_event(dst->overlap.hEvent,
			     sizeof(dst->overlap.hEvent),
			     wpa_supplicant_ctrl_iface_receive, dst, NULL);

#ifdef UNICODE
	_snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
		   priv->wpa_s->ifname);
#else /* UNICODE */
	os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
		    priv->wpa_s->ifname);
#endif /* UNICODE */

	/* TODO: add support for configuring access list for the pipe */
	dst->pipe = CreateNamedPipe(name,
				    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
				    PIPE_TYPE_MESSAGE |
				    PIPE_READMODE_MESSAGE |
				    PIPE_WAIT,
				    15, REPLY_BUFSIZE, REQUEST_BUFSIZE,
				    1000,
				    priv->sec_attr_set ? &priv->attr : NULL);
	if (dst->pipe == INVALID_HANDLE_VALUE) {
		wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
			   (int) GetLastError());
		goto fail;
	}

	if (ConnectNamedPipe(dst->pipe, &dst->overlap)) {
		wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
			   (int) GetLastError());
		CloseHandle(dst->pipe);
		os_free(dst);
		return -1;
	}

	err = GetLastError();
	switch (err) {
	case ERROR_IO_PENDING:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in "
			   "progress");
		break;
	case ERROR_PIPE_CONNECTED:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already "
			   "connected");
		if (SetEvent(dst->overlap.hEvent))
			break;
		/* fall through */
	default:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
			   (int) err);
		CloseHandle(dst->pipe);
		os_free(dst);
		return -1;
	}

	dst->next = priv->ctrl_dst;
	if (dst->next)
		dst->next->prev = dst;
	priv->ctrl_dst = dst;

	return 0;

fail:
	ctrl_close_pipe(dst);
	return -1;
}


static void ctrl_close_pipe(struct wpa_ctrl_dst *dst)
{
	wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst);

	if (dst->overlap.hEvent) {
		eloop_unregister_event(dst->overlap.hEvent,
				       sizeof(dst->overlap.hEvent));
		CloseHandle(dst->overlap.hEvent);
	}

	if (dst->pipe != INVALID_HANDLE_VALUE) {
		/*
		 * Could use FlushFileBuffers() here to guarantee that all data
		 * gets delivered to the client, but that can block, so let's
		 * not do this for now.
		 * FlushFileBuffers(dst->pipe);
		 */
		CloseHandle(dst->pipe);
	}

	if (dst->prev)
		dst->prev->next = dst->next;
	else
		dst->priv->ctrl_dst = dst->next;
	if (dst->next)
		dst->next->prev = dst->prev;

	os_free(dst->rsp_buf);
	os_free(dst);
}


static VOID WINAPI ctrl_iface_write_completed(DWORD err, DWORD bytes,
					      LPOVERLAPPED overlap)
{
	struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap;
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p "
		   "err=%d bytes=%d", dst, (int) err, (int) bytes);
	if (err) {
		ctrl_close_pipe(dst);
		return;
	}

	os_free(dst->rsp_buf);
	dst->rsp_buf = NULL;

	if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
			&dst->overlap, ctrl_iface_read_completed)) {
		wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
			   (int) GetLastError());
		ctrl_close_pipe(dst);
		return;
	}
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
}


static void wpa_supplicant_ctrl_iface_rx(struct wpa_ctrl_dst *dst, size_t len)
{
	struct wpa_supplicant *wpa_s = dst->priv->wpa_s;
	char *reply = NULL, *send_buf;
	size_t reply_len = 0, send_len;
	int new_attached = 0;
	char *buf = dst->req_buf;

	dst->used = 1;
	if (len >= REQUEST_BUFSIZE)
		len = REQUEST_BUFSIZE - 1;
	buf[len] = '\0';

	if (os_strcmp(buf, "ATTACH") == 0) {
		dst->attached = 1;
		wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached");
		new_attached = 1;
		reply_len = 2;
	} else if (os_strcmp(buf, "DETACH") == 0) {
		dst->attached = 0;
		wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached");
		reply_len = 2;
	} else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", buf + 6);
		dst->debug_level = atoi(buf + 6);
		reply_len = 2;
	} else {
		reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
							  &reply_len);
	}

	if (reply) {
		send_buf = reply;
		send_len = reply_len;
	} else if (reply_len == 2) {
		send_buf = "OK\n";
		send_len = 3;
	} else {
		send_buf = "FAIL\n";
		send_len = 5;
	}

	os_free(dst->rsp_buf);
	dst->rsp_buf = os_malloc(send_len);
	if (dst->rsp_buf == NULL) {
		ctrl_close_pipe(dst);
		os_free(reply);
		return;
	}
	os_memcpy(dst->rsp_buf, send_buf, send_len);
	os_free(reply);

	if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
			 ctrl_iface_write_completed)) {
		wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
			   (int) GetLastError());
		ctrl_close_pipe(dst);
	} else {
		wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
			   dst);
	}

	if (new_attached)
		eapol_sm_notify_ctrl_attached(wpa_s->eapol);
}


static VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes,
					     LPOVERLAPPED overlap)
{
	struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap;
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d "
		   "bytes=%d", dst, (int) err, (int) bytes);
	if (err == 0 && bytes > 0)
		wpa_supplicant_ctrl_iface_rx(dst, bytes);
}


static void wpa_supplicant_ctrl_iface_receive(void *eloop_data, void *user_ctx)
{
	struct wpa_ctrl_dst *dst = eloop_data;
	struct ctrl_iface_priv *priv = dst->priv;
	DWORD bytes;

	wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_ctrl_iface_receive");
	ResetEvent(dst->overlap.hEvent);

	if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) {
		wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d",
			   (int) GetLastError());
		return;
	}
	wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client "
		   "connected");

	/* Open a new named pipe for the next client. */
	ctrl_open_pipe(priv);

	/* Use write completion function to start reading a command */
	ctrl_iface_write_completed(0, 0, &dst->overlap);

	ctrl_flush_broken_pipes(priv);
}


static int ctrl_iface_parse(struct ctrl_iface_priv *priv, const char *params)
{
	const char *sddl = NULL;
	TCHAR *t_sddl;

	if (os_strncmp(params, "SDDL=", 5) == 0)
		sddl = params + 5;
	if (!sddl) {
		sddl = os_strstr(params, " SDDL=");
		if (sddl)
			sddl += 6;
	}

	if (!sddl)
		return 0;

	wpa_printf(MSG_DEBUG, "CTRL: SDDL='%s'", sddl);
	os_memset(&priv->attr, 0, sizeof(priv->attr));
	priv->attr.nLength = sizeof(priv->attr);
	priv->attr.bInheritHandle = FALSE;
	t_sddl = wpa_strdup_tchar(sddl);
	if (t_sddl == NULL)
		return -1;
	if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
		    t_sddl, SDDL_REVISION_1,
		    (PSECURITY_DESCRIPTOR *) (void *)
		    &priv->attr.lpSecurityDescriptor,
		    NULL)) {
		os_free(t_sddl);
		wpa_printf(MSG_ERROR, "CTRL: SDDL='%s' - could not convert to "
			   "security descriptor: %d",
			   sddl, (int) GetLastError());
		return -1;
	}
	os_free(t_sddl);

	priv->sec_attr_set = 1;

	return 0;
}


static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
					     enum wpa_msg_type type,
					     const char *txt, size_t len)
{
	struct wpa_supplicant *wpa_s = ctx;
	if (wpa_s == NULL || wpa_s->ctrl_iface == NULL)
		return;
	wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len);
}


struct ctrl_iface_priv *
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
{
	struct ctrl_iface_priv *priv;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->wpa_s = wpa_s;

	if (wpa_s->conf->ctrl_interface == NULL)
		return priv;

	if (ctrl_iface_parse(priv, wpa_s->conf->ctrl_interface) < 0) {
		os_free(priv);
		return NULL;
	}

	if (ctrl_open_pipe(priv) < 0) {
		os_free(priv);
		return NULL;
	}

	wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);

	return priv;
}


void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
{
	while (priv->ctrl_dst)
		ctrl_close_pipe(priv->ctrl_dst);
	if (priv->sec_attr_set)
		LocalFree(priv->attr.lpSecurityDescriptor);
	os_free(priv);
}


static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
					   int level, const char *buf,
					   size_t len)
{
	struct wpa_ctrl_dst *dst, *next;
	char levelstr[10];
	int idx;
	char *sbuf;
	int llen;
	DWORD written;

	dst = priv->ctrl_dst;
	if (dst == NULL)
		return;

	os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);

	llen = os_strlen(levelstr);
	sbuf = os_malloc(llen + len);
	if (sbuf == NULL)
		return;

	os_memcpy(sbuf, levelstr, llen);
	os_memcpy(sbuf + llen, buf, len);

	idx = 0;
	while (dst) {
		next = dst->next;
		if (dst->attached && level >= dst->debug_level) {
			wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %p",
				   dst);
			if (!WriteFile(dst->pipe, sbuf, llen + len, &written,
				       NULL)) {
				wpa_printf(MSG_DEBUG, "CTRL: WriteFile to dst "
					   "%p failed: %d",
					   dst, (int) GetLastError());
				dst->errors++;
				if (dst->errors > 10)
					ctrl_close_pipe(dst);
			} else
				dst->errors = 0;
		}
		idx++;
		dst = next;
	}
	os_free(sbuf);
}


void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
{
	wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor",
		   priv->wpa_s->ifname);
	if (priv->ctrl_dst == NULL)
		return;
	WaitForSingleObject(priv->ctrl_dst->pipe, INFINITE);
}


/* Global ctrl_iface */

struct ctrl_iface_global_priv;

struct wpa_global_dst {
	/* Note: OVERLAPPED must be the first member of struct wpa_global_dst
	 */
	OVERLAPPED overlap;
	struct wpa_global_dst *next, *prev;
	struct ctrl_iface_global_priv *priv;
	HANDLE pipe;
	char req_buf[REQUEST_BUFSIZE];
	char *rsp_buf;
	int used;
};

struct ctrl_iface_global_priv {
	struct wpa_global *global;
	struct wpa_global_dst *ctrl_dst;
};


static void global_flush_broken_pipes(struct ctrl_iface_global_priv *priv)
{
	struct wpa_global_dst *dst, *next;

	dst = priv->ctrl_dst;

	while (dst) {
		next = dst->next;
		if (ctrl_broken_pipe(dst->pipe, dst->used)) {
			wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
				   dst);
			global_close_pipe(dst);
		}
		dst = next;
	}
}


static int global_open_pipe(struct ctrl_iface_global_priv *priv)
{
	struct wpa_global_dst *dst;
	DWORD err;

	dst = os_zalloc(sizeof(*dst));
	if (dst == NULL)
		return -1;
	wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);

	dst->priv = priv;
	dst->pipe = INVALID_HANDLE_VALUE;

	dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
	if (dst->overlap.hEvent == NULL) {
		wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
			   (int) GetLastError());
		goto fail;
	}

	eloop_register_event(dst->overlap.hEvent,
			     sizeof(dst->overlap.hEvent),
			     wpa_supplicant_global_iface_receive, dst, NULL);

	/* TODO: add support for configuring access list for the pipe */
	dst->pipe = CreateNamedPipe(NAMED_PIPE_PREFIX,
				    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
				    PIPE_TYPE_MESSAGE |
				    PIPE_READMODE_MESSAGE |
				    PIPE_WAIT,
				    10, REPLY_BUFSIZE, REQUEST_BUFSIZE,
				    1000, NULL);
	if (dst->pipe == INVALID_HANDLE_VALUE) {
		wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
			   (int) GetLastError());
		goto fail;
	}

	if (ConnectNamedPipe(dst->pipe, &dst->overlap)) {
		wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
			   (int) GetLastError());
		CloseHandle(dst->pipe);
		os_free(dst);
		return -1;
	}

	err = GetLastError();
	switch (err) {
	case ERROR_IO_PENDING:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in "
			   "progress");
		break;
	case ERROR_PIPE_CONNECTED:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already "
			   "connected");
		if (SetEvent(dst->overlap.hEvent))
			break;
		/* fall through */
	default:
		wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
			   (int) err);
		CloseHandle(dst->pipe);
		os_free(dst);
		return -1;
	}

	dst->next = priv->ctrl_dst;
	if (dst->next)
		dst->next->prev = dst;
	priv->ctrl_dst = dst;

	return 0;

fail:
	global_close_pipe(dst);
	return -1;
}


static void global_close_pipe(struct wpa_global_dst *dst)
{
	wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst);

	if (dst->overlap.hEvent) {
		eloop_unregister_event(dst->overlap.hEvent,
				       sizeof(dst->overlap.hEvent));
		CloseHandle(dst->overlap.hEvent);
	}

	if (dst->pipe != INVALID_HANDLE_VALUE) {
		/*
		 * Could use FlushFileBuffers() here to guarantee that all data
		 * gets delivered to the client, but that can block, so let's
		 * not do this for now.
		 * FlushFileBuffers(dst->pipe);
		 */
		CloseHandle(dst->pipe);
	}

	if (dst->prev)
		dst->prev->next = dst->next;
	else
		dst->priv->ctrl_dst = dst->next;
	if (dst->next)
		dst->next->prev = dst->prev;

	os_free(dst->rsp_buf);
	os_free(dst);
}


static VOID WINAPI global_iface_write_completed(DWORD err, DWORD bytes,
						LPOVERLAPPED overlap)
{
	struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap;
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p "
		   "err=%d bytes=%d", dst, (int) err, (int) bytes);
	if (err) {
		global_close_pipe(dst);
		return;
	}

	os_free(dst->rsp_buf);
	dst->rsp_buf = NULL;

	if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
			&dst->overlap, global_iface_read_completed)) {
		wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
			   (int) GetLastError());
		global_close_pipe(dst);
		/* FIX: if this was the pipe waiting for new global
		 * connections, at this point there are no open global pipes..
		 * Should try to open a new pipe.. */
		return;
	}
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
}


static void wpa_supplicant_global_iface_rx(struct wpa_global_dst *dst,
					   size_t len)
{
	struct wpa_global *global = dst->priv->global;
	char *reply = NULL, *send_buf;
	size_t reply_len = 0, send_len;
	char *buf = dst->req_buf;

	dst->used = 1;
	if (len >= REQUEST_BUFSIZE)
		len = REQUEST_BUFSIZE - 1;
	buf[len] = '\0';

	reply = wpa_supplicant_global_ctrl_iface_process(global, buf,
							 &reply_len);
	if (reply) {
		send_buf = reply;
		send_len = reply_len;
	} else if (reply_len) {
		send_buf = "FAIL\n";
		send_len = 5;
	} else {
		os_free(dst->rsp_buf);
		dst->rsp_buf = NULL;
		return;
	}

	os_free(dst->rsp_buf);
	dst->rsp_buf = os_malloc(send_len);
	if (dst->rsp_buf == NULL) {
		global_close_pipe(dst);
		os_free(reply);
		return;
	}
	os_memcpy(dst->rsp_buf, send_buf, send_len);
	os_free(reply);

	if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
			 global_iface_write_completed)) {
		wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
			   (int) GetLastError());
		global_close_pipe(dst);
	} else {
		wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
			   dst);
	}
}


static VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes,
					       LPOVERLAPPED overlap)
{
	struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap;
	wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d "
		   "bytes=%d", dst, (int) err, (int) bytes);
	if (err == 0 && bytes > 0)
		wpa_supplicant_global_iface_rx(dst, bytes);
}


static void wpa_supplicant_global_iface_receive(void *eloop_data,
						void *user_ctx)
{
	struct wpa_global_dst *dst = eloop_data;
	struct ctrl_iface_global_priv *priv = dst->priv;
	DWORD bytes;

	wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_global_iface_receive");
	ResetEvent(dst->overlap.hEvent);

	if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) {
		wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d",
			   (int) GetLastError());
		return;
	}
	wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client "
		   "connected");

	/* Open a new named pipe for the next client. */
	if (global_open_pipe(priv) < 0) {
		wpa_printf(MSG_DEBUG, "CTRL: global_open_pipe failed");
		return;
	}

	/* Use write completion function to start reading a command */
	global_iface_write_completed(0, 0, &dst->overlap);

	global_flush_broken_pipes(priv);
}


struct ctrl_iface_global_priv *
wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
{
	struct ctrl_iface_global_priv *priv;

	priv = os_zalloc(sizeof(*priv));
	if (priv == NULL)
		return NULL;
	priv->global = global;

	if (global_open_pipe(priv) < 0) {
		os_free(priv);
		return NULL;
	}

	return priv;
}


void
wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
{
	while (priv->ctrl_dst)
		global_close_pipe(priv->ctrl_dst);
	os_free(priv);
}
