/*
 * 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, int global,
					     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);
}
