/*
 * WPA Supplicant / Windows Named Pipe -based control interface
 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Alternatively, this software may be distributed under the terms of BSD
 * license.
 *
 * See README and COPYING for more details.
 */

#include "includes.h"

#include "common.h"
#include "eloop.h"
#include "config.h"
#include "eapol_sm.h"
#include "wpa_supplicant_i.h"
#include "ctrl_iface.h"
#include "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 *) &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,
					     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);
}
