winexe 0.7

AH andrzej.hajda at wp.pl
Tue Jul 25 17:56:34 GMT 2006


Hi

I have updated winexe.
Changes:
0.7 - 25/07/06 Making code more pretty.
    By default commands run on user's account.
    Added --system - commands run on system account.
    Added --runas - any user can be impersonated(BEWARE: passwords are 
sent in clear text).
    Many changes in winexesvc.

More info at http://eol.ovh.org/winexe/

Andrzej Hajda

-------------- next part --------------
Index: main.mk
===================================================================
--- main.mk	(revision 17234)
+++ main.mk	(working copy)
@@ -25,6 +25,7 @@
 include ntvfs/config.mk
 include ntptr/config.mk
 include torture/config.mk
+include winexe/config.mk
 include librpc/config.mk
 include client/config.mk
 include libcli/config.mk
Index: winexe/winexe.c
===================================================================
--- winexe/winexe.c	(revision 0)
+++ winexe/winexe.c	(revision 0)
@@ -0,0 +1,278 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/ndr_svcctl_c.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/libcli.h"
+#include "lib/events/events.h"
+
+#include "winexe.h"
+#include "winexesvc/shared.h"
+
+#include <sys/fcntl.h>
+#include <sys/unistd.h>
+#include <sys/termios.h>
+
+struct program_args {
+	char *hostname;
+	char *cmd;
+	struct cli_credentials *credentials;
+	int reinstall;
+	int uninstall;
+	int system;
+	char *runas;
+};
+
+void parse_args(int argc, char *argv[], struct program_args *pmyargs)
+{
+	poptContext pc;
+	int opt, i;
+
+	int argc_new;
+	char **argv_new;
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		POPT_COMMON_SAMBA
+		POPT_COMMON_CONNECTION
+		POPT_COMMON_CREDENTIALS
+		POPT_COMMON_VERSION
+		{"uninstall", 0, POPT_ARG_NONE, &pmyargs->uninstall, 0,
+		 "Uninstall winexe service after remote execution", NULL},
+		{"reinstall", 0, POPT_ARG_NONE, &pmyargs->reinstall, 0,
+		 "Reinstall winexe service before remote execution", NULL},
+		{"system", 0, POPT_ARG_NONE, &pmyargs->system, 0,
+		 "Use SYSTEM account" , NULL},
+		{"runas", 0, POPT_ARG_STRING, &pmyargs->runas, 0,
+		 "Run as user (BEWARE: password is sent in cleartext over net)" , "[DOMAIN\\]USERNAME%PASSWORD"},
+		POPT_TABLEEND
+	};
+
+	pc = poptGetContext("winexe", argc, (const char **) argv,
+			    long_options, POPT_CONTEXT_KEEP_FIRST);
+
+	poptSetOtherOptionHelp(pc, "//host command");
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		poptPrintUsage(pc, stdout, 0);
+		exit(1);
+	}
+
+	argv_new = discard_const_p(char *, poptGetArgs(pc));
+
+	argc_new = argc;
+	for (i = 0; i < argc; i++) {
+		if (argv_new[i] == NULL) {
+			argc_new = i;
+			break;
+		}
+	}
+
+	if (argc_new != 3 || argv_new[1][0] != '/'
+	    || argv_new[1][1] != '/') {
+		poptPrintUsage(pc, stdout, 0);
+		exit(1);
+	}
+
+	pmyargs->hostname = argv_new[1] + 2;
+	pmyargs->cmd = argv_new[2];
+}
+
+struct winexe_context {
+	struct program_args *args;
+	struct smbcli_tree *tree;
+	struct async_context *ac_ctrl;
+	struct async_context *ac_io;
+	struct async_context *ac_err;
+	int return_code;
+};
+
+void exit_program(struct winexe_context *c);
+
+void on_ctrl_pipe_error(struct winexe_context *c, int func, NTSTATUS status)
+{
+	DEBUG(1, ("ERROR: on_ctrl_pipe_error - %s\n", nt_errstr(status)));
+	static int activated = 0;
+	if (!activated
+	    && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+		status =
+		    svc_install(c->args->hostname, c->args->credentials);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,
+			      ("ERROR: Failed to install service winexesvc - %s\n",
+			       nt_errstr(status)));
+			c->return_code = 1;
+			exit_program(c);
+		}
+		activated = 1;
+		async_open(c->ac_ctrl, "\\pipe\\" PIPE_NAME, OPENX_MODE_ACCESS_RDWR);
+	} else if (func == ASYNC_OPEN_RECV) {
+		DEBUG(0,
+		      ("ERROR: Cannot open control pipe - %s\n",
+		       nt_errstr(status)));
+		c->return_code = 1;
+		exit_program(c);
+	} else
+		exit_program(c);
+}
+
+void on_io_pipe_open(struct winexe_context *c);
+void on_io_pipe_read(struct winexe_context *c, const char *data, int len);
+void on_io_pipe_error(struct winexe_context *c, int func, NTSTATUS status);
+void on_err_pipe_read(struct winexe_context *c, const char *data, int len);
+void on_err_pipe_error(struct winexe_context *c, int func, NTSTATUS status);
+
+const char *cmd_check(const char *data, const char *cmd, int len)
+{
+	int lcmd = strlen(cmd);
+	if (lcmd >= len)
+		return 0;
+	if (!strncmp(data, cmd, lcmd)
+	    && (data[lcmd] == ' ' || data[lcmd] == '\n')) {
+		return data + lcmd + 1;
+	}
+	return 0;
+}
+
+void on_ctrl_pipe_open(struct winexe_context *c)
+{
+	char *str;
+	if (c->args->runas)
+		str = talloc_asprintf(c, "set runas %s\nrun %s\n", c->args->runas, c->args->cmd);
+	else
+		str = talloc_asprintf(c, "%srun %s\n", c->args->system ? "set system 1\n" : "" , c->args->cmd);
+	DEBUG(1, ("CTRL: Sending command: %s", str));
+	async_write(c->ac_ctrl, str, strlen(str));
+	talloc_free(str);
+}
+
+void on_ctrl_pipe_read(struct winexe_context *c, const char *data, int len)
+{
+	const char *p;
+	if ((p = cmd_check(data, CMD_STD_IO_ERR, len))) {
+		DEBUG(1, ("CTRL: Recieved command: %.*s", len, data));
+		unsigned int npipe = strtoul(p, 0, 16);
+		c->ac_io = talloc_zero(c, struct async_context);
+		c->ac_io->tree = c->tree;
+		c->ac_io->cb_ctx = c;
+		c->ac_io->cb_open = (async_cb_open) on_io_pipe_open;
+		c->ac_io->cb_read = (async_cb_read) on_io_pipe_read;
+		c->ac_io->cb_error = (async_cb_error) on_io_pipe_error;
+		char *fn = talloc_asprintf(c->ac_io, "\\pipe\\" PIPE_NAME_IO, npipe);
+		async_open(c->ac_io, fn, OPENX_MODE_ACCESS_RDWR);
+		c->ac_err = talloc_zero(c, struct async_context);
+		c->ac_err->tree = c->tree;
+		c->ac_err->cb_ctx = c;
+		c->ac_err->cb_read = (async_cb_read) on_err_pipe_read;
+		c->ac_err->cb_error = (async_cb_error) on_err_pipe_error;
+		fn = talloc_asprintf(c->ac_err, "\\pipe\\" PIPE_NAME_ERR, npipe);
+		async_open(c->ac_err, fn, OPENX_MODE_ACCESS_RDWR);
+	} else if ((p = cmd_check(data, CMD_RETURN_CODE, len))) {
+		c->return_code = strtoul(p, 0, 16);
+	} else {
+		DEBUG(0, ("CTRL: Unknown command: %.*s", len, data));
+	}
+}
+
+static void on_stdin_read_event(struct event_context *event_ctx,
+			     struct fd_event *fde, uint16_t flags,
+			     struct winexe_context *c)
+{
+	char buf[256];
+	int len;
+	if ((len = read(0, &buf, sizeof(buf))) > 0) {
+		async_write(c->ac_io, buf, len);
+	}
+}
+
+void on_io_pipe_open(struct winexe_context *c)
+{
+	event_add_fd(c->tree->session->transport->socket->event.ctx,
+		     c->tree, 0, EVENT_FD_READ,
+		     (event_fd_handler_t) on_stdin_read_event, c);
+	struct termios term;
+	tcgetattr(0, &term);
+	term.c_lflag &= ~ICANON;
+	tcsetattr(0, TCSANOW, &term);
+	setbuf(stdin, NULL);
+}
+
+void on_io_pipe_read(struct winexe_context *c, const char *data, int len)
+{
+	write(1, data, len);
+}
+
+void on_io_pipe_error(struct winexe_context *c, int func, NTSTATUS status)
+{
+	async_close(c->ac_io);
+}
+
+void on_err_pipe_read(struct winexe_context *c, const char *data, int len)
+{
+	write(2, data, len);
+}
+
+void on_err_pipe_error(struct winexe_context *c, int func, NTSTATUS status)
+{
+	async_close(c->ac_err);
+}
+
+void exit_program(struct winexe_context *c)
+{
+	if (c->args->uninstall)
+		svc_uninstall(c->args->hostname, c->args->credentials);
+	exit(c->return_code);
+}
+
+int main(int argc, char *argv[])
+{
+	NTSTATUS status;
+	struct smbcli_state *cli;
+	struct program_args myargs = {.reinstall = 0,.uninstall = 0, .system = 0 };
+
+	parse_args(argc, argv, &myargs);
+
+	dcerpc_init();
+
+	if (myargs.reinstall)
+		svc_uninstall(myargs.hostname, cmdline_credentials);
+	status =
+	    smbcli_full_connection(NULL, &cli, myargs.hostname, "IPC$",
+				   NULL, cmdline_credentials, NULL);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,
+		      ("ERROR: Failed to open connection - %s\n",
+		       nt_errstr(status)));
+		return 1;
+	}
+
+	struct winexe_context *c =
+	    talloc_zero(cli->tree, struct winexe_context);
+	if (c == NULL) {
+		DEBUG(0,
+		      ("ERROR: Failed to allocate struct winexe_context\n"));
+		return 1;
+	}
+
+	c->tree = cli->tree;
+	c->ac_ctrl = talloc_zero(cli->tree, struct async_context);
+	c->ac_ctrl->tree = cli->tree;
+	c->ac_ctrl->cb_ctx = c;
+	c->ac_ctrl->cb_open = (async_cb_open) on_ctrl_pipe_open;
+	c->ac_ctrl->cb_read = (async_cb_read) on_ctrl_pipe_read;
+	c->ac_ctrl->cb_error = (async_cb_error) on_ctrl_pipe_error;
+	c->args = &myargs;
+	c->args->credentials = cmdline_credentials;
+	c->return_code = 99;
+
+	async_open(c->ac_ctrl, "\\pipe\\" PIPE_NAME, OPENX_MODE_ACCESS_RDWR);
+
+	event_loop_wait(cli->tree->session->transport->socket->event.ctx);
+	return 0;
+}
Index: winexe/service.c
===================================================================
--- winexe/service.c	(revision 0)
+++ winexe/service.c	(revision 0)
@@ -0,0 +1,256 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/ndr_svcctl_c.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#define SERVICE_ALL_ACCESS (0xF01FF)
+#define SERVICE_WIN32_OWN_PROCESS (0x00000010)
+#define SERVICE_DEMAND_START (0x00000003)
+#define SERVICE_ERROR_NORMAL (0x00000001)
+#define SERVICE_CONTROL_STOP (0x00000001)
+#define NT_STATUS_SERVICE_DOES_NOT_EXIST NT_STATUS(0xc0000424)
+#include "libcli/libcli.h"
+#include "libcli/smb_composite/smb_composite.h"
+
+/* FIX We need it for dirty usleep */
+#include <sys/unistd.h>
+
+#include "winexe.h"
+
+#define NT_ERR(status, lvl, args...) if (!NT_STATUS_IS_OK(status)) { DEBUG(lvl,("ERROR: " args)); DEBUG(lvl,(". %s.\n", nt_errstr(status))); return status; }
+#define NT_RES(status, werr) (NT_STATUS_IS_OK(status) ? werror_to_ntstatus(werr) : status)
+
+NTSTATUS svc_pipe_connect(struct dcerpc_pipe **psvc_pipe,
+			  const char *hostname,
+			  struct cli_credentials *credentials)
+{
+	NTSTATUS status;
+	char *binding;
+
+	asprintf(&binding, "ncacn_np:%s", hostname);
+	status =
+	    dcerpc_pipe_connect(NULL, psvc_pipe, binding,
+				&dcerpc_table_svcctl, credentials, NULL);
+	free(binding);
+	return status;
+}
+
+NTSTATUS svc_OpenSCManager(struct dcerpc_pipe * svc_pipe,
+			   const char *hostname,
+			   struct policy_handle * pscm_handle)
+{
+	NTSTATUS status;
+	struct svcctl_OpenSCManagerW r;
+
+	r.in.MachineName = hostname;
+	r.in.DatabaseName = NULL;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.out.handle = pscm_handle;
+	status = dcerpc_svcctl_OpenSCManagerW(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_OpenService(struct dcerpc_pipe * svc_pipe,
+			 struct policy_handle * pscm_handle,
+			 const char *ServiceName,
+			 struct policy_handle * psvc_handle)
+{
+	NTSTATUS status;
+	struct svcctl_OpenServiceW r;
+
+	r.in.scmanager_handle = pscm_handle;
+	r.in.ServiceName = ServiceName;
+	r.in.access_mask = SERVICE_ALL_ACCESS;
+	r.out.handle = psvc_handle;
+	status = dcerpc_svcctl_OpenServiceW(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_CreateService(struct dcerpc_pipe * svc_pipe,
+			   struct policy_handle * pscm_handle,
+			   const char *ServiceName,
+			   const char *binary_path,
+			   struct policy_handle * psvc_handle)
+{
+	NTSTATUS status;
+	struct svcctl_CreateServiceW r;
+
+	r.in.scmanager_handle = pscm_handle;
+	r.in.ServiceName = ServiceName;
+	r.in.DisplayName = NULL;
+	r.in.desired_access = SERVICE_ALL_ACCESS;
+	r.in.type = SERVICE_WIN32_OWN_PROCESS;
+	r.in.start_type = SERVICE_DEMAND_START;
+	r.in.error_control = SERVICE_ERROR_NORMAL;
+	r.in.binary_path = binary_path;
+	r.in.LoadOrderGroupKey = NULL;
+	r.in.TagId = NULL;
+	r.in.dependencies = NULL;
+	r.in.dependencies_size = 0;
+	r.in.service_start_name = NULL;
+	r.in.password = NULL;
+	r.in.password_size = 0;
+	r.out.handle = psvc_handle;
+	r.out.TagId = NULL;
+	status = dcerpc_svcctl_CreateServiceW(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_StartService(struct dcerpc_pipe * svc_pipe,
+			  struct policy_handle * psvc_handle)
+{
+	NTSTATUS status;
+	struct svcctl_StartServiceW r;
+
+	r.in.handle = psvc_handle;
+	r.in.NumArgs = 0;
+	r.in.Arguments = NULL;
+	status = dcerpc_svcctl_StartServiceW(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_ControlService(struct dcerpc_pipe * svc_pipe,
+			    struct policy_handle * psvc_handle,
+			    int control, struct SERVICE_STATUS * sstatus)
+{
+	NTSTATUS status;
+	struct svcctl_ControlService r;
+
+	r.in.handle = psvc_handle;
+	r.in.control = control;
+	r.out.status = sstatus;
+	status = dcerpc_svcctl_ControlService(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_DeleteService(struct dcerpc_pipe * svc_pipe,
+			   struct policy_handle * psvc_handle)
+{
+	NTSTATUS status;
+	struct svcctl_DeleteService r;
+
+	r.in.handle = psvc_handle;
+	status = dcerpc_svcctl_DeleteService(svc_pipe, NULL, &r);
+	return NT_RES(status, r.out.result);
+}
+
+NTSTATUS svc_CloseServiceHandle(struct dcerpc_pipe * svc_pipe,
+				struct policy_handle * psvc_handle)
+{
+	NTSTATUS status;
+	struct svcctl_CloseServiceHandle r;
+
+	r.in.handle = psvc_handle;
+	r.out.handle = psvc_handle;
+	status = dcerpc_svcctl_CloseServiceHandle(svc_pipe, NULL, &r);
+	return status;
+}
+
+NTSTATUS svc_UploadService(const char *hostname,
+			   struct cli_credentials * credentials)
+{
+	struct smb_composite_savefile *io;
+	struct smbcli_state *cli;
+	NTSTATUS status;
+
+	status =
+	    smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL,
+				   credentials, NULL);
+	NT_ERR(status, 1, "Failed to open ADMIN$ share");
+	io = talloc_zero(cli->tree, struct smb_composite_savefile);
+	io->in.fname = "winexesvc.exe";
+	io->in.data = winexesvc_exe;
+	io->in.size = winexesvc_exe_len;
+	smbcli_unlink(cli->tree, io->in.fname);
+	status = smb_composite_savefile(cli->tree, io);
+	talloc_free(io);
+	smbcli_tdis(cli);
+	NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname);
+	return status;
+}
+
+/* Start, Creates, Install service if necccesary */
+NTSTATUS svc_install(const char *hostname,
+		     struct cli_credentials * credentials)
+{
+	NTSTATUS status;
+	struct dcerpc_pipe *svc_pipe;
+	struct policy_handle scm_handle;
+	struct policy_handle svc_handle;
+
+	status = svc_pipe_connect(&svc_pipe, hostname, credentials);
+	NT_ERR(status, 1, "Cannot connect to svcctl pipe");
+	status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle);
+	NT_ERR(status, 1, "OpenSCManager failed");
+	status =
+	    svc_OpenService(svc_pipe, &scm_handle, "winexesvc",
+			    &svc_handle);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_SERVICE_DOES_NOT_EXIST)) {
+		status = svc_UploadService(hostname, credentials);
+		NT_ERR(status, 1, "UploadService failed");
+		status =
+		    svc_CreateService(svc_pipe, &scm_handle, "winexesvc",
+				      "winexesvc.exe", &svc_handle);
+		NT_ERR(status, 1, "CreateService failed");
+	} else {
+		NT_ERR(status, 1, "OpenService failed");
+	}
+	status = svc_StartService(svc_pipe, &svc_handle);
+	NT_ERR(status, 1, "StartService failed");
+	/* FIXME wait to service real activation */
+	sleep(1);
+	svc_CloseServiceHandle(svc_pipe, &svc_handle);
+	svc_CloseServiceHandle(svc_pipe, &scm_handle);
+	/* FIXME we need to disconnect/close/destroy svc_pipe, how???? */
+	return status;
+}
+
+NTSTATUS svc_uninstall(const char *hostname,
+		       struct cli_credentials * credentials)
+{
+	NTSTATUS status;
+	struct dcerpc_pipe *svc_pipe;
+	struct policy_handle scm_handle;
+	struct policy_handle svc_handle;
+	struct SERVICE_STATUS svc_status;
+
+	status = svc_pipe_connect(&svc_pipe, hostname, credentials);
+	NT_ERR(status, 1, "Cannot connect to svcctl pipe");
+	status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle);
+	NT_ERR(status, 1, "OpenSCManager failed");
+	status =
+	    svc_OpenService(svc_pipe, &scm_handle, "winexesvc",
+			    &svc_handle);
+	NT_ERR(status, 1, "OpenService failed");
+	DEBUG(1, ("OpenService - %s\n", nt_errstr(status)));
+	if (NT_STATUS_IS_OK(status)) {
+		status =
+		    svc_ControlService(svc_pipe, &svc_handle,
+				       SERVICE_CONTROL_STOP, &svc_status);
+		DEBUG(1, ("StopService - %s\n", nt_errstr(status)));
+		status = svc_DeleteService(svc_pipe, &svc_handle);
+		DEBUG(1, ("DeleteService - %s\n", nt_errstr(status)));
+		status = svc_CloseServiceHandle(svc_pipe, &svc_handle);
+		DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status)));
+	}
+	svc_CloseServiceHandle(svc_pipe, &scm_handle);
+	DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status)));
+
+	struct smbcli_state *cli;
+	status =
+	    smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL,
+				   credentials, NULL);
+	NT_ERR(status, 1, "Failed to open ADMIN$ share");
+	status = smbcli_unlink(cli->tree, "winexesvc.exe");
+	DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status)));
+	status = smbcli_tdis(cli);
+	DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status)));
+	return status;
+}
Index: winexe/winexe.h
===================================================================
--- winexe/winexe.h	(revision 0)
+++ winexe/winexe.h	(revision 0)
@@ -0,0 +1,59 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+/* service.c */
+NTSTATUS svc_install(const char *hostname,
+		     struct cli_credentials *credentials);
+NTSTATUS svc_uninstall(const char *hostname,
+		       struct cli_credentials *credentials);
+
+/* async.c */
+enum { ASYNC_OPEN, ASYNC_OPEN_RECV, ASYNC_READ, ASYNC_READ_RECV,
+	    ASYNC_WRITE, ASYNC_WRITE_RECV, ASYNC_CLOSE, ASYNC_CLOSE_RECV };
+typedef void (*async_cb_open) (void *ctx);
+typedef void (*async_cb_read) (void *ctx, const char *data, int len);
+typedef void (*async_cb_close) (void *ctx);
+typedef void (*async_cb_error) (void *ctx, int func, NTSTATUS status);
+
+struct list_item {
+	struct list_item *next;
+	int size;
+	char data[0];
+};
+
+struct list {
+	struct list_item *begin;
+	struct list_item *end;
+};
+
+struct async_context {
+/* Public - must be initialized by client */
+	struct smbcli_tree *tree;
+	void *cb_ctx;
+	async_cb_open cb_open;
+	async_cb_read cb_read;
+	async_cb_close cb_close;
+	async_cb_error cb_error;
+/* Private - internal usage, initialize to zeros */
+	int fd;
+	union smb_open *io_open;
+	union smb_read *io_read;
+	union smb_write *io_write;
+	union smb_close *io_close;
+	struct smbcli_request *rreq;
+	struct smbcli_request *wreq;
+	struct list wq;
+	char buffer[256];
+};
+
+int async_open(struct async_context *c, const char *fn, int open_mode);
+int async_read(struct async_context *c);
+int async_write(struct async_context *c, const void *buf, int len);
+int async_close(struct async_context *c);
+
+/* winexesvc_exe.c */
+extern unsigned int winexesvc_exe_len;
+extern unsigned char winexesvc_exe[];
Index: winexe/TODO
===================================================================
--- winexe/TODO	(revision 0)
+++ winexe/TODO	(revision 0)
@@ -0,0 +1,5 @@
+- add service config options, esp. "interactive",
+- encryption of pipes (I hope it can be done using smb proto),
+- other psexec/beyondexec options
+- turn off line buffering of stdin on windows side (how???)
+- review/fix code :)
Index: winexe/changes
===================================================================
--- winexe/changes	(revision 0)
+++ winexe/changes	(revision 0)
@@ -0,0 +1,33 @@
+0.7 - 25/07/06 Making code more pretty.
+    By default commands run on user's account.
+    Added --system - commands run on system account.
+    Added --runas - any user can be impersonated(BEWARE: passwords are sent in clear text).
+    Many changes in winexesvc.
+0.61 - 07/07/06 Fixed bug in svcctl.idl
+    Changed types of 'dependencies' and 'password' params in CreateServiceW.
+0.6 - 07/07/06 svcctl.idl cosmetics
+    Linux code style applied, semi automatic.
+    Removed // style comments.
+    Changed includes <xx.h> to <sys/xx.h>
+0.5 - 06/07/06 Cleaned up winexe/service code.
+    Changed deps in winexe/config.mk.
+    Renamed directory service to winexesvc.
+    STDIN read corrected.
+    async_write serialized - now server should receive input in correct order.
+0.4 - 02/07/06 Added dependencies in winexe/config.mk to auto rebuild service.
+    Turned off timeouts - proces do not disconnect after 60sec.
+    Added some debug messages.
+    Removed small leaks in winexesvc.
+0.3 - 02/07/06 winexe is fully integrated with smb_build system. Now there is
+    no need to separately compile winexe/service. I have also removed symlink
+    to winexesvc_exe.c, should be cleaner.
+0.2 - 02/07/06 Now it works with NT - all pipes are created with security 
+    descriptor allowing admins to open it.
+    Added options --reinstall/--uninstall.
+    Added error messages, cleaned debug messages(-d 1).
+    Some code cleaning.
+    Added 'precompiled' winexe/service/winexesvc_exe.c, for users without 
+    crosscompiler or windows compile enironment.
+0.1 - 01/07/06 In winexe dir added link to winexe/service/winexesvc_exe.c, 
+    I am not sure if patch utility supports it.
+0.0 - 30/06/06 Initial release
Index: winexe/config.mk
===================================================================
--- winexe/config.mk	(revision 0)
+++ winexe/config.mk	(revision 0)
@@ -0,0 +1,19 @@
+#################################
+# Start BINARY winexe
+[BINARY::winexe]
+INSTALLDIR = BINDIR
+OBJ_FILES = \
+                winexe.o \
+		service.o \
+		async.o \
+		winexesvc/winexesvc_exe.o
+PRIVATE_DEPENDENCIES = \
+                POPT_SAMBA \
+                POPT_CREDENTIALS \
+                LIBPOPT \
+		RPC_NDR_SVCCTL
+# End BINARY winexe
+#################################
+
+winexe/winexesvc/winexesvc_exe.c: winexe/winexesvc/winexesvc.c
+	@$(MAKE) -C winexe/winexesvc
Index: winexe/winexesvc/service.c
===================================================================
--- winexe/winexesvc/service.c	(revision 0)
+++ winexe/winexesvc/service.c	(revision 0)
@@ -0,0 +1,156 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+#include <windows.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "shared.h"
+
+#if 0
+static void SvcDebugOut(const char *a, int b)
+{
+	FILE *f = fopen("C:\\" SERVICE_NAME ".log", "at");
+	fprintf(f, a, b);
+	fclose(f);
+}
+#else
+#define SvcDebugOut(a,b) 0
+#endif
+
+DWORD WINAPI server_loop(LPVOID lpParameter);
+
+SERVICE_STATUS winexesvcStatus;
+SERVICE_STATUS_HANDLE winexesvcStatusHandle;
+
+VOID WINAPI winexesvcCtrlHandler(DWORD Opcode)
+{
+	DWORD status;
+
+	switch (Opcode) {
+	case SERVICE_CONTROL_PAUSE:
+		winexesvcStatus.dwCurrentState = SERVICE_PAUSED;
+		break;
+
+	case SERVICE_CONTROL_CONTINUE:
+		winexesvcStatus.dwCurrentState = SERVICE_RUNNING;
+		break;
+
+	case SERVICE_CONTROL_STOP:
+		winexesvcStatus.dwWin32ExitCode = 0;
+		winexesvcStatus.dwCurrentState = SERVICE_STOPPED;
+		winexesvcStatus.dwCheckPoint = 0;
+		winexesvcStatus.dwWaitHint = 0;
+
+		if (!SetServiceStatus
+		    (winexesvcStatusHandle, &winexesvcStatus)) {
+			status = GetLastError();
+			SvcDebugOut(SERVICE_NAME
+				    ": SetServiceStatus error %ld\n",
+				    status);
+		}
+
+		SvcDebugOut(SERVICE_NAME ": Leaving winexesvc \n", 0);
+		return;
+
+	case SERVICE_CONTROL_INTERROGATE:
+		break;
+
+	default:
+		SvcDebugOut(SERVICE_NAME ": Unrecognized opcode %ld\n",
+			    Opcode);
+	}
+
+	if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) {
+		status = GetLastError();
+		SvcDebugOut(SERVICE_NAME ": SetServiceStatus error %ld\n",
+			    status);
+	}
+	return;
+}
+
+DWORD winexesvcInitialization(DWORD argc, LPTSTR * argv,
+			      DWORD * specificError)
+{
+	HANDLE th = CreateThread(NULL, 0, server_loop, NULL, 0, NULL);
+	if (th) {
+		CloseHandle(th);
+		return NO_ERROR;
+	}
+	return !NO_ERROR;
+}
+
+void WINAPI winexesvcStart(DWORD argc, LPTSTR * argv)
+{
+	DWORD status;
+	DWORD specificError;
+
+	winexesvcStatus.dwServiceType = SERVICE_WIN32;
+	winexesvcStatus.dwCurrentState = SERVICE_START_PENDING;
+	winexesvcStatus.dwControlsAccepted =
+	    SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
+	winexesvcStatus.dwWin32ExitCode = 0;
+	winexesvcStatus.dwServiceSpecificExitCode = 0;
+	winexesvcStatus.dwCheckPoint = 0;
+	winexesvcStatus.dwWaitHint = 0;
+
+	SvcDebugOut(SERVICE_NAME ": RegisterServiceCtrlHandler\n", 0);
+
+	winexesvcStatusHandle =
+	    RegisterServiceCtrlHandler(SERVICE_NAME, winexesvcCtrlHandler);
+
+	if (winexesvcStatusHandle == (SERVICE_STATUS_HANDLE) 0) {
+		SvcDebugOut(SERVICE_NAME
+			    ": RegisterServiceCtrlHandler failed %d\n",
+			    GetLastError());
+		return;
+	}
+	status = winexesvcInitialization(argc, argv, &specificError);
+
+	if (status != NO_ERROR) {
+		winexesvcStatus.dwCurrentState = SERVICE_STOPPED;
+		winexesvcStatus.dwCheckPoint = 0;
+		winexesvcStatus.dwWaitHint = 0;
+		winexesvcStatus.dwWin32ExitCode = status;
+		winexesvcStatus.dwServiceSpecificExitCode = specificError;
+
+		SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus);
+		return;
+	}
+
+	winexesvcStatus.dwCurrentState = SERVICE_RUNNING;
+	winexesvcStatus.dwCheckPoint = 0;
+	winexesvcStatus.dwWaitHint = 0;
+
+	if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) {
+		status = GetLastError();
+		SvcDebugOut(SERVICE_NAME ": SetServiceStatus error %ld\n",
+			    status);
+	}
+
+	SvcDebugOut(SERVICE_NAME ": Returning the Main Thread \n", 0);
+
+	return;
+}
+
+int main(int argc, char *argv[])
+{
+	SERVICE_TABLE_ENTRY DispatchTable[] = {
+		{SERVICE_NAME, winexesvcStart},
+		{NULL, NULL}
+	};
+
+	SvcDebugOut(SERVICE_NAME ": StartServiceCtrlDispatcher\n",
+		    GetLastError());
+	if (!StartServiceCtrlDispatcher(DispatchTable)) {
+		SvcDebugOut(SERVICE_NAME
+			    ": StartServiceCtrlDispatcher (%d)\n",
+			    GetLastError());
+	}
+	return 0;
+}
Index: winexe/winexesvc/winexesvc.c
===================================================================
--- winexe/winexesvc/winexesvc.c	(revision 0)
+++ winexe/winexesvc/winexesvc.c	(revision 0)
@@ -0,0 +1,459 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+#include <windows.h>
+#include <aclapi.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "shared.h"
+
+#define BUFSIZE 256
+
+#if 0
+static void SvcDebugOut(const char *a, int b)
+{
+	FILE *f = fopen("C:\\" SERVICE_NAME ".log", "at");
+	fprintf(f, a, b);
+	fclose(f);
+}
+#else
+#define SvcDebugOut(a,b) 0
+#endif
+
+SECURITY_ATTRIBUTES sa;
+
+/* Creates SECURITY_ATTRIBUTES sa with full access for BUILTIN\Administrators */
+int CreatePipesSA()
+{
+	DWORD dwRes;
+	PSID pAdminSID = NULL;
+	PACL pACL = NULL;
+	PSECURITY_DESCRIPTOR pSD = NULL;
+	EXPLICIT_ACCESS ea;
+	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
+
+	/* Create a SID for the BUILTIN\Administrators group. */
+	if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
+				      SECURITY_BUILTIN_DOMAIN_RID,
+				      DOMAIN_ALIAS_RID_ADMINS,
+				      0, 0, 0, 0, 0, 0, &pAdminSID)) {
+		SvcDebugOut("AllocateAndInitializeSid Error %u\n",
+			    GetLastError());
+		return 0;
+	}
+	/* Initialize an EXPLICIT_ACCESS structure for an ACE.
+	   The ACE will allow the Administrators group full access to the key.
+	*/
+	ea.grfAccessPermissions = FILE_ALL_ACCESS;
+	ea.grfAccessMode = SET_ACCESS;
+	ea.grfInheritance = NO_INHERITANCE;
+	ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+	ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+	ea.Trustee.ptstrName = (LPTSTR) pAdminSID;
+
+	/* Create a new ACL that contains the new ACEs */
+	dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
+	if (ERROR_SUCCESS != dwRes) {
+		SvcDebugOut("SetEntriesInAcl Error %u\n", GetLastError());
+		return 0;
+	}
+	/* Initialize a security descriptor */
+	pSD =
+	    (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
+					      SECURITY_DESCRIPTOR_MIN_LENGTH);
+	if (NULL == pSD) {
+		SvcDebugOut("LocalAlloc Error %u\n", GetLastError());
+		return 0;
+	}
+
+	if (!InitializeSecurityDescriptor
+	    (pSD, SECURITY_DESCRIPTOR_REVISION)) {
+		SvcDebugOut("InitializeSecurityDescriptor Error %u\n",
+			    GetLastError());
+		return 0;
+	}
+	/* Add the ACL to the security descriptor */
+	if (!SetSecurityDescriptorDacl(pSD, TRUE,	/* bDaclPresent flag */
+				       pACL, FALSE))	/* not a default DACL */
+	{
+		SvcDebugOut("SetSecurityDescriptorDacl Error %u\n",
+			    GetLastError());
+		return 0;
+	}
+	/* Initialize a security attributes structure */
+	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+	sa.lpSecurityDescriptor = pSD;
+	sa.bInheritHandle = FALSE;
+	return 1;
+}
+
+int hgets(char *str, int n, HANDLE pipe)
+{
+	DWORD res;
+	DWORD count = 0;
+	--n;
+	while (--n >= 0) {
+		if (!ReadFile(pipe, str, 1, &res, NULL) || !res)
+			goto finish;
+		if (*str == '\n')
+			goto finish;
+		++count;
+		++str;
+	}
+finish:
+	*str = 0;
+	return count;
+}
+
+int hprintf(HANDLE pipe, const char *fmt, ...)
+{
+	int res;
+	char buf[1024];
+	va_list ap;
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+	WriteFile(pipe, buf, strlen(buf), (LPDWORD) & res, NULL);
+	FlushFileBuffers(pipe);
+	return res;
+}
+
+typedef struct {
+	HANDLE pipe;
+	const char *cmd;
+	HANDLE pio;
+	HANDLE perr;
+	HANDLE token;
+	int implevel;
+	int system;
+	char *runas;
+} connection_context;
+
+typedef int CMD_FUNC(connection_context *);
+
+typedef struct {
+	const char *name;
+	CMD_FUNC *func;
+} CMD_ITEM;
+
+int cmd_set(connection_context *c)
+{
+	static const char* var_system = "system";
+	static const char* var_implevel = "implevel";
+	static const char* var_runas = "runas";
+	char *cmdline;
+	int res = 0;
+
+	cmdline = strchr(c->cmd, ' ');
+	if (!cmdline) {
+		goto finish;
+	}
+	++cmdline;
+	int l;
+	if ((strstr(cmdline, var_system) == cmdline) &&
+            (cmdline[l = strlen(var_system)] == ' ')) {
+		c->system = atoi(cmdline + l + 1);
+	} else if ((strstr(cmdline, var_implevel) == cmdline) &&
+            (cmdline[l = strlen(var_implevel)] == ' ')) {
+		c->implevel = atoi(cmdline + l + 1);
+	} else if ((strstr(cmdline, var_runas) == cmdline) &&
+            (cmdline[l = strlen(var_runas)] == ' ')) {
+		c->runas = strdup(cmdline + l + 1);
+	} else {
+	    hprintf(c->pipe, "error Unknown commad (%s)\n", c->cmd);
+	    goto finish;
+	}
+	res = 1;
+finish:
+	return res;
+}
+
+typedef struct {
+	char *user;
+	char *domain;
+	char *password;
+} credentials;
+
+int prepare_credentials(char *str, credentials *crd)
+{
+	char *p;
+	p = strchr(str, '/');
+	if (!p) p = strchr(str, '\\');
+	if (p) {
+		*p++ = 0;
+		crd->domain = str;
+	} else {
+	        p = str;
+		crd->domain = ".";
+	}
+	crd->user = p;
+	p = strchr(p, '%');
+	if (p)
+	    *p++ = 0;
+	crd->password = p;
+	return 1;
+}
+
+int get_token(connection_context *c)
+{
+	int res = 0;
+	int wres;
+	HANDLE token;
+
+	if (c->runas) {
+		credentials crd;
+		if (!prepare_credentials(c->runas, &crd)) {
+			hprintf(c->pipe, "error Incorrect runas credentials\n");
+			goto finish;
+		}
+		wres = LogonUser(crd.user, crd.domain, crd.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &c->token);
+		if (!wres) {
+			hprintf(c->pipe, "error Cannot LogonUser(%s,%s,%s) %d\n", crd.user, crd.domain, crd.password, GetLastError());
+			goto finish;
+		}
+		res = 1;
+		goto finish;
+	} else if (c->system) {
+		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
+			hprintf(c->pipe, "error Cannot OpenProcessToken %d\n", GetLastError());
+			goto finish;
+		}
+	} else {
+		if (!ImpersonateNamedPipeClient(c->pipe)) {
+			hprintf(c->pipe, "error Cannot ImpersonateNamedPipeClient %d\n", GetLastError());
+			goto finish;
+		}
+		if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &token)) {
+			hprintf(c->pipe, "error Cannot OpenThreadToken %d\n", GetLastError());
+			goto finishRevertToSelf;
+		}
+	}
+	if (!DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, c->implevel, TokenPrimary, &c->token)) {
+		hprintf(c->pipe, "error Cannot Duplicate Token %d\n", GetLastError());
+		goto finishCloseToken;
+	}
+	res = 1;
+finishCloseToken:
+	CloseHandle(token);
+finishRevertToSelf:
+	if (!c->system) {
+		if (!RevertToSelf()) {
+			hprintf(c->pipe, "error Cannot RevertToSelf %d\n", GetLastError());
+			res = 0;
+		}
+	}
+finish:
+	return res;
+}
+
+int cmd_run(connection_context *c)
+{
+	char buf[256];
+	int res = 0;
+	int wres;
+	char *cmdline;
+	cmdline = strchr(c->cmd, ' ');
+	if (!cmdline) {
+		goto finish;
+	}
+	++cmdline;
+
+	if (!get_token(c))
+		return 0;
+
+	sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_IO, (unsigned int) c->pipe);
+	c->pio = CreateNamedPipe(buf,		/* pipe name */
+			      PIPE_ACCESS_DUPLEX,	/* read/write access */
+			      PIPE_WAIT,	/* blocking mode */
+			      1,	/* max. instances */
+			      BUFSIZE,	/* output buffer size */
+			      BUFSIZE,	/* input buffer size */
+			      NMPWAIT_USE_DEFAULT_WAIT,	/* client time-out */
+			      &sa);	/* default security attribute */
+	if (c->pio == INVALID_HANDLE_VALUE) {
+		hprintf(c->pipe, "error Cannot create io pipe\n");
+		goto finish;
+	}
+
+	sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_ERR, (unsigned int) c->pipe);
+	c->perr = CreateNamedPipe(buf,	/* pipe name */
+			       PIPE_ACCESS_DUPLEX,	/* read/write access */
+			       PIPE_WAIT,	/* blocking mode */
+			       1,	/* max. instances */
+			       BUFSIZE,	/* output buffer size */
+			       BUFSIZE,	/* input buffer size */
+			       NMPWAIT_USE_DEFAULT_WAIT,	/* client time-out */
+			       &sa);	/* default security attribute */
+	if (c->perr == INVALID_HANDLE_VALUE) {
+		hprintf(c->pipe, "error Cannot create err pipe\n");
+		goto finishClosePio;
+	}
+	/* Send handle to client (it will use it to connect pipes) */
+	hprintf(c->pipe, CMD_STD_IO_ERR " %08X\n", (unsigned int) c->pipe);
+
+	wres = ConnectNamedPipe(c->pio, NULL);
+	if (!wres)
+		wres = (GetLastError() == ERROR_PIPE_CONNECTED);
+
+	if (!wres) {
+		hprintf(c->pipe, "error ConnectNamedPipe(pio)\n");
+		goto finishClosePerr;
+	}
+
+	wres = ConnectNamedPipe(c->perr, NULL);
+	if (!wres)
+		wres = (GetLastError() == ERROR_PIPE_CONNECTED);
+
+	if (!wres) {
+		hprintf(c->pipe, "error ConnectNamedPipe(perr)\n");
+		goto finishDisconnectPio;
+	}
+
+	SetHandleInformation(c->pio, HANDLE_FLAG_INHERIT, 1);
+	SetHandleInformation(c->perr, HANDLE_FLAG_INHERIT, 1);
+
+
+	SECURITY_ATTRIBUTES sattr;
+	sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+	sattr.bInheritHandle = TRUE;
+	sattr.lpSecurityDescriptor = NULL;
+
+	PROCESS_INFORMATION pi;
+	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+	STARTUPINFO si;
+	ZeroMemory(&si, sizeof(STARTUPINFO));
+	si.cb = sizeof(STARTUPINFO);
+	si.hStdInput = c->pio;
+	si.hStdOutput = c->pio;
+	si.hStdError = c->perr;
+	si.dwFlags |= STARTF_USESTDHANDLES;
+
+	if (CreateProcessAsUser(
+			  c->token,
+			  NULL, 
+			  cmdline,	/* command line */
+			  NULL,	/* process security attributes */
+			  NULL,	/* primary thread security attributes */
+			  TRUE,	/* handles are inherited */
+			  0,	/* creation flags */
+			  NULL,	/* use parent's environment */
+			  NULL,	/* use parent's current directory */
+			  &si,	/* STARTUPINFO pointer */
+			  &pi))	/* receives PROCESS_INFORMATION */
+	{
+		WaitForSingleObject(pi.hProcess, INFINITE);
+		DWORD ec;
+		GetExitCodeProcess(pi.hProcess, &ec);
+		FlushFileBuffers(c->pio);
+		FlushFileBuffers(c->perr);
+		CloseHandle(pi.hProcess);
+		CloseHandle(pi.hThread);
+		hprintf(c->pipe, CMD_RETURN_CODE " %08X\n", ec);
+	} else {
+		hprintf(c->pipe, "error Creating process(%s) %d\n", cmdline, GetLastError());
+	}
+
+	DisconnectNamedPipe(c->perr);
+finishDisconnectPio:
+	DisconnectNamedPipe(c->pio);
+finishClosePerr:
+	CloseHandle(c->perr);
+finishClosePio:
+	CloseHandle(c->pio);
+finish:
+	return res;
+}
+
+CMD_ITEM cmd_table[] = {
+	{"run", cmd_run},
+	{"set", cmd_set},
+	{NULL, NULL}
+};
+
+VOID handle_connection(HANDLE pipe)
+{
+	char cmd[1024];
+	int res;
+	connection_context _c, *c = &_c;
+	ZeroMemory(c, sizeof(connection_context));
+	c->pipe = pipe;
+	c->cmd = cmd;
+	/* FIXME make wait for end of process or ctrl_pipe input */
+	while (1) {
+		res = hgets(cmd, sizeof(cmd), pipe);
+		if (res <= 0) {
+			SvcDebugOut("Error reading from pipe(%08X)\n", (int) c->pipe);
+			goto finish;
+		}
+		CMD_ITEM *ci;
+		for (ci = cmd_table; ci->name; ++ci) {
+			if (strstr(cmd, ci->name) != cmd) continue;
+			char c = cmd[strlen(ci->name)];
+			if (!c || (c == ' '))
+				break;
+		}
+		if (ci->name) {
+			if (!ci->func(c))
+				goto finish;
+		} else
+			hprintf(c->pipe, "error Ignoring unknown command (%s)\n", cmd);
+	}
+finish:
+	FlushFileBuffers(c->pipe);
+	DisconnectNamedPipe(c->pipe);
+	CloseHandle(c->pipe);
+}
+
+DWORD WINAPI server_loop(LPVOID lpParameter)
+{
+	HANDLE pipe;
+	BOOL res;
+	if (!CreatePipesSA()) {
+		SvcDebugOut("CreatePipesSA failed (%08X)\n",
+			    GetLastError());
+		return -1;
+	}
+	for (;;) {
+		pipe = CreateNamedPipe("\\\\.\\pipe\\" PIPE_NAME,	/* pipe name */
+				       PIPE_ACCESS_DUPLEX,	/* read/write access */
+				       PIPE_WAIT,	/* blocking mode */
+				       PIPE_UNLIMITED_INSTANCES,	/* max. instances */
+				       BUFSIZE,	/* output buffer size */
+				       BUFSIZE,	/* input buffer size */
+				       NMPWAIT_USE_DEFAULT_WAIT,	/* client time-out */
+				       &sa);	/* default security attribute */
+
+		if (pipe == INVALID_HANDLE_VALUE) {
+			SvcDebugOut("CreatePipe failed(%08X)\n",
+				    GetLastError());
+			return 0;
+		}
+		res =
+		    ConnectNamedPipe(pipe,
+				     NULL) ? TRUE : (GetLastError() ==
+						     ERROR_PIPE_CONNECTED);
+		if (res) {
+			HANDLE th = CreateThread(NULL,	/* no security attribute */
+						 0,	/* default stack size */
+						 (LPTHREAD_START_ROUTINE)
+						 handle_connection,
+						 (LPVOID) pipe,	/* thread parameter */
+						 0,	/* not suspended */
+						 NULL);	/* returns thread ID */
+			if (!th) {
+				SvcDebugOut("Cannot create thread\n", 0);
+			} else
+				CloseHandle(th);
+		} else {
+			CloseHandle(pipe);
+		}
+	}
+}
Index: winexe/winexesvc/shared.h
===================================================================
--- winexe/winexesvc/shared.h	(revision 0)
+++ winexe/winexesvc/shared.h	(revision 0)
@@ -0,0 +1,14 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+#define SERVICE_NAME "winexesvc"
+
+#define PIPE_NAME "ahexec"
+#define PIPE_NAME_IO "ahexec_stdio%08X"
+#define PIPE_NAME_ERR "ahexec_stderr%08X"
+
+#define CMD_STD_IO_ERR "std_io_err"
+#define CMD_RETURN_CODE "return_code"
Index: winexe/winexesvc/Makefile
===================================================================
--- winexe/winexesvc/Makefile	(revision 0)
+++ winexe/winexesvc/Makefile	(revision 0)
@@ -0,0 +1,20 @@
+CFLAGS=-mno-cygwin -Os
+LDFLAGS=-mno-cygwin -s -Os
+
+CC := $(shell uname | grep -qi linux && echo i386-mingw32-gcc || echo gcc)
+
+LD=$(CC)
+
+all: winexesvc_exe.c
+
+winexesvc.exe: winexesvc.o service.o
+	$(LD) $(LDFLAGS) -o $@ $^
+
+winexesvc_exe.c: winexesvc.exe bin2c.exe
+	./bin2c.exe winexesvc_exe winexesvc.exe > $@
+
+bin2c.exe: bin2c.c
+	gcc -s -o $@ $^
+
+clean:
+	- at rm *.exe *.o winexesvc_exe.c
Index: winexe/winexesvc/winexesvc_exe.c
===================================================================
--- winexe/winexesvc/winexesvc_exe.c	(revision 0)
+++ winexe/winexesvc/winexesvc_exe.c	(revision 0)
@@ -0,0 +1,350 @@
+unsigned int winexesvc_exe_len = 9216;
+unsigned char winexesvc_exe[] = {
+  77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0,184,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,14,31,186,14,
+  0,180,9,205,33,184,1,76,205,33,84,104,105,115,32,112,114,111,103,114,97,109,
+  32,99,97,110,110,111,116,32,98,101,32,114,117,110,32,105,110,32,68,79,83,32,
+  109,111,100,101,46,13,13,10,36,0,0,0,0,0,0,0,80,69,0,0,76,1,5,0,190,89,198,
+  68,0,0,0,0,0,0,0,0,224,0,15,3,11,1,2,56,0,18,0,0,0,14,0,0,0,2,0,0,47,18,0,0,
+  0,16,0,0,0,48,0,0,0,0,64,0,0,16,0,0,0,2,0,0,4,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,
+  0,112,0,0,0,4,0,0,184,114,0,0,3,0,0,0,0,0,32,0,0,16,0,0,0,0,16,0,0,16,0,0,0,
+  0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,152,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,116,101,120,116,0,0,0,224,
+  16,0,0,0,16,0,0,0,18,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,96,46,100,97,
+  116,97,0,0,0,96,0,0,0,0,48,0,0,0,2,0,0,0,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,
+  0,192,46,114,100,97,116,97,0,0,112,2,0,0,0,64,0,0,0,4,0,0,0,24,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,64,0,0,64,46,98,115,115,0,0,0,0,160,0,0,0,0,80,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,192,46,105,100,97,116,97,0,0,152,6,0,0,0,
+  96,0,0,0,8,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,192,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,137,229,131,236,8,199,69,248,0,
+  0,0,0,131,236,12,141,69,248,80,255,53,48,48,64,0,141,69,252,80,104,4,80,64,0,
+  104,0,80,64,0,232,67,14,0,0,131,196,32,201,195,85,137,229,131,236,8,131,61,
+  16,80,64,0,0,116,118,161,16,80,64,0,163,64,48,64,0,131,61,244,97,64,0,0,116,
+  25,131,236,8,255,53,16,80,64,0,161,244,97,64,0,255,112,16,232,246,13,0,0,131,
+  196,16,131,61,244,97,64,0,224,116,28,131,236,8,255,53,16,80,64,0,161,244,97,
+  64,0,131,192,32,255,112,16,232,209,13,0,0,131,196,16,131,61,244,97,64,0,192,
+  116,28,131,236,8,255,53,16,80,64,0,161,244,97,64,0,131,192,64,255,112,16,232,
+  172,13,0,0,131,196,16,232,148,13,0,0,137,194,161,64,48,64,0,137,2,201,195,85,
+  137,229,131,236,24,199,69,248,0,0,0,0,199,69,244,0,0,0,0,139,69,8,139,0,139,
+  0,137,69,240,129,125,240,145,0,0,192,119,23,129,125,240,141,0,0,192,115,113,
+  129,125,240,5,0,0,192,116,28,233,191,0,0,0,129,125,240,147,0,0,192,116,90,
+  129,125,240,148,0,0,192,116,88,233,168,0,0,0,131,236,8,106,0,106,11,232,24,
+  13,0,0,131,196,16,137,69,252,131,125,252,1,117,24,131,236,8,106,1,106,11,232,
+  0,13,0,0,131,196,16,199,69,248,255,255,255,255,235,120,131,125,252,0,116,114,
+  131,236,12,106,11,139,69,252,255,208,131,196,16,199,69,248,255,255,255,255,
+  235,92,199,69,244,1,0,0,0,131,236,8,106,0,106,8,232,197,12,0,0,131,196,16,
+  137,69,252,131,125,252,1,117,35,131,236,8,106,1,106,8,232,173,12,0,0,131,196,
+  16,131,125,244,0,116,5,232,159,11,0,0,199,69,248,255,255,255,255,235,26,131,
+  125,252,0,116,20,131,236,12,106,8,139,69,252,255,208,131,196,16,199,69,248,
+  255,255,255,255,139,69,248,201,194,4,0,85,137,229,131,236,8,131,236,12,104,
+  199,16,64,0,232,2,13,0,0,131,196,12,232,90,11,0,0,232,21,254,255,255,232,66,
+  254,255,255,232,36,11,0,0,131,228,240,131,236,4,131,236,12,232,45,12,0,0,131,
+  196,12,255,48,255,53,4,80,64,0,255,53,0,80,64,0,232,141,10,0,0,131,196,16,
+  137,69,252,232,252,11,0,0,131,236,12,255,117,252,232,193,12,0,0,85,137,229,
+  131,236,8,131,236,12,106,1,161,236,97,64,0,255,208,131,196,16,232,130,255,
+  255,255,85,137,229,131,236,8,131,236,12,106,2,161,236,97,64,0,255,208,131,
+  196,16,232,104,255,255,255,85,137,229,131,236,8,131,236,12,255,117,8,161,4,
+  98,64,0,255,208,131,196,16,201,195,85,137,229,131,236,8,131,236,12,255,117,8,
+  161,248,97,64,0,255,208,131,196,16,201,195,144,144,144,144,144,144,144,144,
+  144,144,144,144,144,85,137,229,49,192,87,252,141,125,204,185,6,0,0,0,131,236,
+  56,199,69,200,0,0,0,0,199,69,196,0,0,0,0,243,170,141,69,200,80,106,0,106,0,
+  106,0,106,0,106,0,106,0,104,32,2,0,0,106,32,106,2,141,69,204,80,198,69,209,5,
+  232,8,13,0,0,49,210,133,192,15,132,142,0,0,0,139,69,200,137,69,248,141,69,
+  196,80,106,0,141,69,220,80,106,1,199,69,220,255,1,31,0,199,69,224,2,0,0,0,
+  199,69,228,0,0,0,0,199,69,240,0,0,0,0,199,69,244,2,0,0,0,232,212,12,0,0,49,
+  210,133,192,117,78,106,20,106,64,232,197,11,0,0,49,210,133,192,137,199,116,
+  61,106,1,80,232,197,12,0,0,49,210,133,192,116,47,106,0,255,117,196,106,1,87,
+  232,194,12,0,0,49,210,133,192,116,28,199,5,64,80,64,0,12,0,0,0,137,61,68,80,
+  64,0,199,5,72,80,64,0,0,0,0,0,178,1,137,208,139,125,252,201,195,85,137,229,
+  87,86,83,80,139,117,12,49,255,139,93,8,131,238,2,120,37,106,0,141,69,240,80,
+  106,1,83,255,117,16,232,100,11,0,0,133,192,116,16,131,125,240,0,116,10,128,
+  59,10,116,5,71,67,78,235,217,198,3,0,141,101,244,91,94,137,248,95,201,195,85,
+  137,229,87,86,83,129,236,4,4,0,0,141,69,16,80,255,117,12,141,157,244,251,255,
+  255,104,0,4,0,0,83,139,117,8,232,220,10,0,0,131,196,16,106,0,141,133,240,251,
+  255,255,80,137,223,252,49,192,131,201,255,242,174,247,209,73,81,83,86,232,11,
+  11,0,0,86,232,21,11,0,0,139,133,240,251,255,255,141,101,244,91,94,95,201,195,
+  85,137,229,87,86,83,131,236,24,106,32,139,117,8,255,118,4,199,69,240,0,0,0,0,
+  232,122,10,0,0,133,192,89,91,137,195,15,132,216,0,0,0,255,53,24,48,64,0,67,
+  83,232,81,10,0,0,57,216,95,90,117,48,161,24,48,64,0,137,69,236,131,201,255,
+  49,192,252,139,125,236,242,174,247,209,141,65,255,128,60,3,32,117,18,141,68,
+  3,1,80,232,19,10,0,0,137,70,24,233,141,0,0,0,255,53,28,48,64,0,83,232,15,10,
+  0,0,57,216,90,89,117,40,49,192,131,201,255,139,61,28,48,64,0,252,242,174,247,
+  209,141,65,255,128,60,3,32,117,15,141,68,3,1,80,232,214,9,0,0,137,70,20,235,
+  83,255,53,32,48,64,0,83,232,213,9,0,0,57,216,89,95,117,45,161,32,48,64,0,137,
+  69,220,131,201,255,49,192,252,139,125,220,242,174,247,209,141,65,255,128,60,
+  3,32,117,15,141,68,3,1,80,232,247,8,0,0,137,70,28,235,20,255,118,4,104,30,64,
+  64,0,255,54,232,176,254,255,255,131,196,12,235,8,90,199,69,240,1,0,0,0,139,
+  69,240,141,101,244,91,94,95,201,195,85,137,229,86,83,106,47,139,93,8,83,232,
+  123,9,0,0,133,192,90,139,117,12,89,117,14,106,92,83,232,106,9,0,0,133,192,90,
+  89,116,9,198,0,0,64,137,94,4,235,9,137,216,199,70,4,57,64,64,0,137,6,106,37,
+  80,232,72,9,0,0,133,192,90,89,116,4,198,0,0,64,137,70,8,141,101,248,91,184,1,
+  0,0,0,94,201,195,85,137,229,86,83,131,236,20,139,93,8,139,83,28,49,246,133,
+  210,116,106,141,69,232,80,82,232,134,255,255,255,133,192,90,89,117,19,104,59,
+  64,64,0,255,51,232,12,254,255,255,91,88,233,43,1,0,0,141,67,16,80,106,0,106,
+  2,255,117,240,255,117,236,255,117,232,232,82,10,0,0,133,192,117,35,232,89,9,
+  0,0,80,255,117,240,255,117,236,255,117,232,104,94,64,64,0,255,51,232,208,253,
+  255,255,131,196,24,233,238,0,0,0,190,1,0,0,0,233,228,0,0,0,131,123,24,0,116,
+  37,141,69,228,80,104,255,0,15,0,232,45,9,0,0,80,232,23,10,0,0,133,192,117,96,
+  232,14,9,0,0,80,104,131,64,64,0,235,22,255,51,232,15,10,0,0,133,192,117,23,
+  232,246,8,0,0,80,104,165,64,64,0,255,51,232,118,253,255,255,233,148,0,0,0,
+  141,69,228,80,106,0,104,255,0,15,0,232,244,8,0,0,80,232,238,9,0,0,133,192,
+  117,23,232,197,8,0,0,80,104,209,64,64,0,255,51,232,69,253,255,255,131,196,12,
+  235,64,141,67,16,80,106,1,255,115,20,106,0,104,0,0,0,2,255,117,228,232,203,9,
+  0,0,133,192,117,23,232,146,8,0,0,80,104,242,64,64,0,255,51,232,18,253,255,
+  255,131,196,12,235,5,190,1,0,0,0,255,117,228,232,163,8,0,0,131,123,24,0,117,
+  32,232,168,9,0,0,133,192,117,23,232,95,8,0,0,80,104,19,65,64,0,255,51,232,
+  223,252,255,255,49,246,131,196,12,141,101,248,91,137,240,94,201,195,85,137,
+  229,87,86,83,129,236,120,1,0,0,106,32,139,117,8,255,118,4,232,171,7,0,0,133,
+  192,89,91,137,133,124,254,255,255,15,132,86,2,0,0,86,255,133,124,254,255,255,
+  232,96,254,255,255,133,192,90,15,132,65,2,0,0,255,54,104,49,65,64,0,141,157,
+  244,254,255,255,83,232,67,7,0,0,104,64,80,64,0,106,0,104,0,1,0,0,104,0,1,0,0,
+  106,1,106,0,106,3,83,232,22,8,0,0,137,70,8,131,196,12,64,117,19,104,75,65,64,
+  0,255,54,232,78,252,255,255,94,95,233,245,1,0,0,255,54,104,104,65,64,0,83,
+  232,253,6,0,0,104,64,80,64,0,106,0,104,0,1,0,0,104,0,1,0,0,106,1,106,0,106,3,
+  83,232,208,7,0,0,137,70,12,131,196,12,64,117,19,104,131,65,64,0,255,54,232,8,
+  252,255,255,89,91,233,167,1,0,0,255,54,104,161,65,64,0,255,54,232,243,251,
+  255,255,106,0,255,118,8,232,172,7,0,0,131,196,12,133,192,117,31,232,80,7,0,0,
+  61,23,2,0,0,116,19,104,178,65,64,0,255,54,232,202,251,255,255,88,90,233,97,1,
+  0,0,106,0,255,118,12,232,124,7,0,0,133,192,117,31,232,35,7,0,0,61,23,2,0,0,
+  116,19,104,207,65,64,0,255,54,232,157,251,255,255,91,95,233,44,1,0,0,106,1,
+  106,1,255,118,8,232,93,7,0,0,106,1,106,1,255,118,12,232,81,7,0,0,141,189,212,
+  254,255,255,252,49,192,185,4,0,0,0,243,171,106,68,106,0,141,157,132,254,255,
+  255,83,199,133,228,254,255,255,12,0,0,0,199,133,236,254,255,255,1,0,0,0,199,
+  133,232,254,255,255,0,0,0,0,232,243,5,0,0,139,70,8,137,133,188,254,255,255,
+  137,133,192,254,255,255,139,70,12,137,133,196,254,255,255,141,133,212,254,
+  255,255,80,83,106,0,106,0,106,0,106,1,106,0,106,0,255,181,124,254,255,255,
+  106,0,255,118,16,129,141,176,254,255,255,0,1,0,0,199,133,132,254,255,255,68,
+  0,0,0,232,179,7,0,0,131,196,12,133,192,116,92,106,255,255,181,212,254,255,
+  255,232,191,6,0,0,141,133,128,254,255,255,80,255,181,212,254,255,255,232,189,
+  6,0,0,255,118,8,232,37,6,0,0,255,118,12,232,29,6,0,0,255,181,212,254,255,255,
+  232,82,6,0,0,255,181,216,254,255,255,232,71,6,0,0,255,181,128,254,255,255,
+  104,237,65,64,0,255,54,232,146,250,255,255,131,196,12,235,27,232,251,5,0,0,
+  80,255,181,124,254,255,255,104,255,65,64,0,255,54,232,117,250,255,255,131,
+  196,16,255,118,12,232,109,6,0,0,255,118,8,232,101,6,0,0,255,118,12,232,253,5,
+  0,0,255,118,8,232,245,5,0,0,141,101,244,91,94,49,192,95,201,195,85,137,229,
+  87,86,83,49,192,252,185,8,0,0,0,141,189,212,251,255,255,129,236,40,4,0,0,243,
+  171,139,69,8,137,133,212,251,255,255,141,133,244,251,255,255,137,133,216,251,
+  255,255,255,117,8,104,0,4,0,0,141,133,244,251,255,255,80,232,189,249,255,255,
+  131,196,12,133,192,15,142,128,0,0,0,190,0,48,64,0,131,61,0,48,64,0,0,116,83,
+  255,54,141,157,244,251,255,255,83,232,191,4,0,0,57,216,95,90,117,33,139,62,
+  49,192,137,189,204,251,255,255,131,201,255,252,242,174,247,209,138,132,41,
+  243,251,255,255,132,192,116,12,60,32,116,8,131,198,8,131,62,0,235,193,131,62,
+  0,116,17,141,133,212,251,255,255,80,255,86,4,133,192,94,117,130,235,31,141,
+  133,244,251,255,255,80,104,30,66,64,0,255,181,212,251,255,255,232,128,249,
+  255,255,131,196,12,233,97,255,255,255,255,181,212,251,255,255,232,208,4,0,0,
+  255,181,212,251,255,255,232,101,5,0,0,255,181,212,251,255,255,232,250,4,0,0,
+  141,101,244,91,94,95,201,195,85,137,229,83,232,25,248,255,255,131,202,255,
+  133,192,116,107,235,4,49,210,235,101,104,64,80,64,0,106,0,104,0,1,0,0,104,0,
+  1,0,0,104,255,0,0,0,106,0,106,3,104,67,66,64,0,232,200,4,0,0,131,248,255,137,
+  195,116,209,106,0,80,232,201,4,0,0,133,192,117,12,232,112,4,0,0,61,23,2,0,0,
+  117,26,106,0,106,0,83,104,133,25,64,0,106,0,106,0,232,246,4,0,0,133,192,116,
+  166,80,235,1,83,232,121,4,0,0,235,155,137,208,139,93,252,201,194,4,0,144,144,
+  144,144,144,144,144,144,144,144,144,144,144,144,85,137,229,139,69,8,131,248,
+  2,116,14,119,5,72,116,33,235,71,131,248,3,116,14,235,64,199,5,84,80,64,0,7,0,
+  0,0,235,52,199,5,84,80,64,0,4,0,0,0,235,40,199,5,92,80,64,0,0,0,0,0,199,5,84,
+  80,64,0,1,0,0,0,199,5,100,80,64,0,0,0,0,0,199,5,104,80,64,0,0,0,0,0,104,80,
+  80,64,0,255,53,112,80,64,0,232,39,5,0,0,133,192,117,5,232,190,3,0,0,201,194,
+  4,0,85,137,229,106,0,106,0,106,0,104,126,26,64,0,106,0,106,0,232,67,4,0,0,
+  133,192,186,1,0,0,0,116,8,80,232,196,3,0,0,49,210,137,208,201,195,85,137,229,
+  80,104,16,27,64,0,104,96,66,64,0,199,5,80,80,64,0,48,0,0,0,199,5,84,80,64,0,
+  2,0,0,0,199,5,88,80,64,0,3,0,0,0,199,5,92,80,64,0,0,0,0,0,199,5,96,80,64,0,0,
+  0,0,0,199,5,100,80,64,0,0,0,0,0,199,5,104,80,64,0,0,0,0,0,232,165,4,0,0,133,
+  192,163,112,80,64,0,15,132,138,0,0,0,141,69,252,80,255,117,12,255,117,8,232,
+  95,255,255,255,131,196,12,133,192,116,61,104,80,80,64,0,163,92,80,64,0,255,
+  53,112,80,64,0,139,69,252,199,5,84,80,64,0,1,0,0,0,199,5,100,80,64,0,0,0,0,0,
+  199,5,104,80,64,0,0,0,0,0,163,96,80,64,0,232,55,4,0,0,235,55,104,80,80,64,0,
+  255,53,112,80,64,0,199,5,84,80,64,0,4,0,0,0,199,5,100,80,64,0,0,0,0,0,199,5,
+  104,80,64,0,0,0,0,0,232,7,4,0,0,133,192,117,5,232,158,2,0,0,201,194,8,0,85,
+  137,229,131,236,16,232,35,1,0,0,141,69,240,80,199,69,240,96,66,64,0,199,69,
+  244,178,27,64,0,199,69,248,0,0,0,0,199,69,252,0,0,0,0,232,234,3,0,0,49,192,
+  201,195,144,144,144,144,144,144,85,137,229,131,236,8,139,69,8,137,69,248,139,
+  69,248,59,69,12,115,35,139,85,248,139,69,16,3,66,4,137,69,252,139,77,252,139,
+  85,252,139,69,248,139,0,3,2,137,1,141,69,248,131,0,8,235,213,201,195,85,137,
+  229,104,0,0,64,0,104,112,66,64,0,104,112,66,64,0,232,176,255,255,255,131,196,
+  12,201,195,144,144,144,144,144,144,144,144,144,144,144,85,137,229,219,227,
+  201,195,144,144,144,144,144,144,144,144,144,85,137,229,131,236,8,161,80,48,
+  64,0,131,56,0,116,18,161,80,48,64,0,139,0,255,208,131,5,80,48,64,0,4,235,228,
+  201,195,85,137,229,131,236,8,161,208,32,64,0,137,69,252,131,125,252,255,117,
+  27,199,69,252,0,0,0,0,139,69,252,131,60,133,212,32,64,0,0,116,7,141,69,252,
+  255,0,235,236,139,69,252,137,69,248,131,125,248,0,116,19,139,69,248,139,4,
+  133,208,32,64,0,255,208,141,69,248,255,8,235,231,131,236,12,104,80,29,64,0,
+  232,148,244,255,255,131,196,16,201,195,85,137,229,131,236,8,131,61,32,80,64,
+  0,0,117,15,199,5,32,80,64,0,1,0,0,0,232,130,255,255,255,201,195,144,144,144,
+  144,144,144,144,144,144,144,144,144,255,37,212,97,64,0,144,144,0,0,0,0,0,0,0,
+  0,255,37,236,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,240,97,64,0,144,144,0,0,
+  0,0,0,0,0,0,255,37,228,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,16,98,64,0,144,
+  144,0,0,0,0,0,0,0,0,255,37,232,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,252,97,
+  64,0,144,144,0,0,0,0,0,0,0,0,255,37,224,97,64,0,144,144,0,0,0,0,0,0,0,0,255,
+  37,12,98,64,0,144,144,0,0,0,0,0,0,0,0,255,37,20,98,64,0,144,144,0,0,0,0,0,0,
+  0,0,255,37,8,98,64,0,144,144,0,0,0,0,0,0,0,0,255,37,28,98,64,0,144,144,0,0,0,
+  0,0,0,0,0,255,37,24,98,64,0,144,144,0,0,0,0,0,0,0,0,255,37,0,98,64,0,144,144,
+  0,0,0,0,0,0,0,0,255,37,192,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,156,97,64,
+  0,144,144,0,0,0,0,0,0,0,0,255,37,180,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,
+  184,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,200,97,64,0,144,144,0,0,0,0,0,0,0,
+  0,255,37,160,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,176,97,64,0,144,144,0,0,
+  0,0,0,0,0,0,255,37,164,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,168,97,64,0,
+  144,144,0,0,0,0,0,0,0,0,255,37,136,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,
+  144,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,140,97,64,0,144,144,0,0,0,0,0,0,0,
+  0,255,37,188,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,196,97,64,0,144,144,0,0,
+  0,0,0,0,0,0,255,37,172,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,152,97,64,0,
+  144,144,0,0,0,0,0,0,0,0,255,37,148,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,72,
+  97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,112,97,64,0,144,144,0,0,0,0,0,0,0,0,
+  255,37,88,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,116,97,64,0,144,144,0,0,0,0,
+  0,0,0,0,255,37,92,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,96,97,64,0,144,144,
+  0,0,0,0,0,0,0,0,255,37,84,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,100,97,64,0,
+  144,144,0,0,0,0,0,0,0,0,255,37,80,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,108,
+  97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,76,97,64,0,144,144,0,0,0,0,0,0,0,0,
+  255,37,120,97,64,0,144,144,0,0,0,0,0,0,0,0,255,37,104,97,64,0,144,144,0,0,0,
+  0,0,0,0,0,255,37,124,97,64,0,144,144,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,
+  255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,
+  0,252,22,64,0,4,64,64,0,41,20,64,0,0,0,0,0,0,0,0,0,8,64,64,0,15,64,64,0,24,
+  64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,64,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,32,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,117,110,0,
+  115,101,116,0,115,121,115,116,101,109,0,105,109,112,108,101,118,101,108,0,
+  114,117,110,97,115,0,101,114,114,111,114,32,85,110,107,110,111,119,110,32,99,
+  111,109,109,97,100,32,40,37,115,41,10,0,46,0,101,114,114,111,114,32,73,110,
+  99,111,114,114,101,99,116,32,114,117,110,97,115,32,99,114,101,100,101,110,
+  116,105,97,108,115,10,0,101,114,114,111,114,32,67,97,110,110,111,116,32,76,
+  111,103,111,110,85,115,101,114,40,37,115,44,37,115,44,37,115,41,32,37,100,10,
+  0,101,114,114,111,114,32,67,97,110,110,111,116,32,79,112,101,110,80,114,111,
+  99,101,115,115,84,111,107,101,110,32,37,100,10,0,101,114,114,111,114,32,67,
+  97,110,110,111,116,32,73,109,112,101,114,115,111,110,97,116,101,78,97,109,
+  101,100,80,105,112,101,67,108,105,101,110,116,32,37,100,10,0,101,114,114,111,
+  114,32,67,97,110,110,111,116,32,79,112,101,110,84,104,114,101,97,100,84,111,
+  107,101,110,32,37,100,10,0,101,114,114,111,114,32,67,97,110,110,111,116,32,
+  68,117,112,108,105,99,97,116,101,32,84,111,107,101,110,32,37,100,10,0,101,
+  114,114,111,114,32,67,97,110,110,111,116,32,82,101,118,101,114,116,84,111,83,
+  101,108,102,32,37,100,10,0,92,92,46,92,112,105,112,101,92,97,104,101,120,101,
+  99,95,115,116,100,105,111,37,48,56,88,0,101,114,114,111,114,32,67,97,110,110,
+  111,116,32,99,114,101,97,116,101,32,105,111,32,112,105,112,101,10,0,92,92,46,
+  92,112,105,112,101,92,97,104,101,120,101,99,95,115,116,100,101,114,114,37,48,
+  56,88,0,101,114,114,111,114,32,67,97,110,110,111,116,32,99,114,101,97,116,
+  101,32,101,114,114,32,112,105,112,101,10,0,115,116,100,95,105,111,95,101,114,
+  114,32,37,48,56,88,10,0,101,114,114,111,114,32,67,111,110,110,101,99,116,78,
+  97,109,101,100,80,105,112,101,40,112,105,111,41,10,0,101,114,114,111,114,32,
+  67,111,110,110,101,99,116,78,97,109,101,100,80,105,112,101,40,112,101,114,
+  114,41,10,0,114,101,116,117,114,110,95,99,111,100,101,32,37,48,56,88,10,0,
+  101,114,114,111,114,32,67,114,101,97,116,105,110,103,32,112,114,111,99,101,
+  115,115,40,37,115,41,32,37,100,10,0,101,114,114,111,114,32,73,103,110,111,
+  114,105,110,103,32,117,110,107,110,111,119,110,32,99,111,109,109,97,110,100,
+  32,40,37,115,41,10,0,92,92,46,92,112,105,112,101,92,97,104,101,120,101,99,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,119,105,110,101,120,101,115,118,99,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,96,0,0,0,0,0,0,0,0,0,0,216,101,0,0,
+  72,97,0,0,168,96,0,0,0,0,0,0,0,0,0,0,44,102,0,0,136,97,0,0,244,96,0,0,0,0,0,
+  0,0,0,0,0,64,102,0,0,212,97,0,0,0,97,0,0,0,0,0,0,0,0,0,0,140,102,0,0,224,97,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,98,0,0,64,98,0,0,88,
+  98,0,0,108,98,0,0,140,98,0,0,172,98,0,0,188,98,0,0,208,98,0,0,228,98,0,0,4,
+  99,0,0,20,99,0,0,40,99,0,0,68,99,0,0,88,99,0,0,0,0,0,0,0,0,0,0,120,99,0,0,
+  136,99,0,0,156,99,0,0,176,99,0,0,192,99,0,0,216,99,0,0,232,99,0,0,252,99,0,0,
+  16,100,0,0,36,100,0,0,60,100,0,0,76,100,0,0,92,100,0,0,104,100,0,0,128,100,0,
+  0,160,100,0,0,184,100,0,0,0,0,0,0,0,0,0,0,196,100,0,0,0,0,0,0,0,0,0,0,208,
+  100,0,0,224,100,0,0,240,100,0,0,0,101,0,0,20,101,0,0,32,101,0,0,40,101,0,0,
+  52,101,0,0,64,101,0,0,80,101,0,0,92,101,0,0,100,101,0,0,112,101,0,0,124,101,
+  0,0,136,101,0,0,148,101,0,0,0,0,0,0,0,0,0,0,36,98,0,0,64,98,0,0,88,98,0,0,
+  108,98,0,0,140,98,0,0,172,98,0,0,188,98,0,0,208,98,0,0,228,98,0,0,4,99,0,0,
+  20,99,0,0,40,99,0,0,68,99,0,0,88,99,0,0,0,0,0,0,0,0,0,0,120,99,0,0,136,99,0,
+  0,156,99,0,0,176,99,0,0,192,99,0,0,216,99,0,0,232,99,0,0,252,99,0,0,16,100,0,
+  0,36,100,0,0,60,100,0,0,76,100,0,0,92,100,0,0,104,100,0,0,128,100,0,0,160,
+  100,0,0,184,100,0,0,0,0,0,0,0,0,0,0,196,100,0,0,0,0,0,0,0,0,0,0,208,100,0,0,
+  224,100,0,0,240,100,0,0,0,101,0,0,20,101,0,0,32,101,0,0,40,101,0,0,52,101,0,
+  0,64,101,0,0,80,101,0,0,92,101,0,0,100,101,0,0,112,101,0,0,124,101,0,0,136,
+  101,0,0,148,101,0,0,0,0,0,0,26,0,65,108,108,111,99,97,116,101,65,110,100,73,
+  110,105,116,105,97,108,105,122,101,83,105,100,0,0,86,0,67,114,101,97,116,101,
+  80,114,111,99,101,115,115,65,115,85,115,101,114,65,0,0,140,0,68,117,112,108,
+  105,99,97,116,101,84,111,107,101,110,69,120,0,0,251,0,73,109,112,101,114,115,
+  111,110,97,116,101,78,97,109,101,100,80,105,112,101,67,108,105,101,110,116,0,
+  0,0,0,254,0,73,110,105,116,105,97,108,105,122,101,83,101,99,117,114,105,116,
+  121,68,101,115,99,114,105,112,116,111,114,0,0,12,1,76,111,103,111,110,85,115,
+  101,114,65,0,0,0,0,101,1,79,112,101,110,80,114,111,99,101,115,115,84,111,107,
+  101,110,0,0,106,1,79,112,101,110,84,104,114,101,97,100,84,111,107,101,110,0,
+  0,0,183,1,82,101,103,105,115,116,101,114,83,101,114,118,105,99,101,67,116,
+  114,108,72,97,110,100,108,101,114,65,0,0,0,193,1,82,101,118,101,114,116,84,
+  111,83,101,108,102,0,0,197,1,83,101,116,69,110,116,114,105,101,115,73,110,65,
+  99,108,65,0,0,211,1,83,101,116,83,101,99,117,114,105,116,121,68,101,115,99,
+  114,105,112,116,111,114,68,97,99,108,0,221,1,83,101,116,83,101,114,118,105,
+  99,101,83,116,97,116,117,115,0,0,227,1,83,116,97,114,116,83,101,114,118,105,
+  99,101,67,116,114,108,68,105,115,112,97,116,99,104,101,114,65,0,0,0,38,0,67,
+  108,111,115,101,72,97,110,100,108,101,0,0,0,46,0,67,111,110,110,101,99,116,
+  78,97,109,101,100,80,105,112,101,0,0,81,0,67,114,101,97,116,101,78,97,109,
+  101,100,80,105,112,101,65,0,0,90,0,67,114,101,97,116,101,84,104,114,101,97,
+  100,0,0,117,0,68,105,115,99,111,110,110,101,99,116,78,97,109,101,100,80,105,
+  112,101,0,0,0,155,0,69,120,105,116,80,114,111,99,101,115,115,0,0,0,203,0,70,
+  108,117,115,104,70,105,108,101,66,117,102,102,101,114,115,0,0,25,1,71,101,
+  116,67,117,114,114,101,110,116,80,114,111,99,101,115,115,0,27,1,71,101,116,
+  67,117,114,114,101,110,116,84,104,114,101,97,100,0,0,48,1,71,101,116,69,120,
+  105,116,67,111,100,101,80,114,111,99,101,115,115,0,0,0,0,67,1,71,101,116,76,
+  97,115,116,69,114,114,111,114,0,0,16,2,76,111,99,97,108,65,108,108,111,99,0,
+  0,0,0,101,2,82,101,97,100,70,105,108,101,0,0,194,2,83,101,116,72,97,110,100,
+  108,101,73,110,102,111,114,109,97,116,105,111,110,0,0,223,2,83,101,116,85,
+  110,104,97,110,100,108,101,100,69,120,99,101,112,116,105,111,110,70,105,108,
+  116,101,114,0,0,0,37,3,87,97,105,116,70,111,114,83,105,110,103,108,101,79,98,
+  106,101,99,116,0,0,0,54,3,87,114,105,116,101,70,105,108,101,0,84,0,95,115,
+  116,114,100,117,112,0,0,0,39,0,95,95,103,101,116,109,97,105,110,97,114,103,
+  115,0,60,0,95,95,112,95,95,101,110,118,105,114,111,110,0,0,62,0,95,95,112,95,
+  95,102,109,111,100,101,0,0,0,0,80,0,95,95,115,101,116,95,97,112,112,95,116,
+  121,112,101,0,0,0,0,121,0,95,99,101,120,105,116,0,0,0,0,233,0,95,105,111,98,
+  0,0,94,1,95,111,110,101,120,105,116,0,0,0,132,1,95,115,101,116,109,111,100,
+  101,0,0,189,1,95,118,115,110,112,114,105,110,116,102,0,0,0,0,28,2,97,116,101,
+  120,105,116,0,0,0,0,30,2,97,116,111,105,0,0,122,2,109,101,109,115,101,116,0,
+  0,0,0,144,2,115,105,103,110,97,108,0,0,0,0,147,2,115,112,114,105,110,116,102,
+  0,0,0,152,2,115,116,114,99,104,114,0,0,0,0,166,2,115,116,114,115,116,114,0,0,
+  0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,
+  0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,0,96,0,0,65,68,86,65,80,73,51,
+  50,46,68,76,76,0,0,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,
+  96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,
+  20,96,0,0,20,96,0,0,20,96,0,0,20,96,0,0,75,69,82,78,69,76,51,50,46,100,108,
+  108,0,0,0,0,40,96,0,0,109,115,118,99,114,116,46,100,108,108,0,0,60,96,0,0,60,
+  96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,
+  60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,60,96,0,0,109,
+  115,118,99,114,116,46,100,108,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
Index: winexe/winexesvc/bin2c.c
===================================================================
--- winexe/winexesvc/bin2c.c	(revision 0)
+++ winexe/winexesvc/bin2c.c	(revision 0)
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+	char buf[256], s[100];
+	int c;
+	FILE *fp;
+	if (argc != 3) {
+		fprintf(stderr, "Usage: %s varname file\n", *argv);
+		return 1;
+	}
+	if (!(fp = fopen(argv[2], "rb"))) {
+		fputs("Cannot open ", stderr);
+		perror(argv[2]);
+		return 1;
+	}
+	fseek(fp, 0, SEEK_END);
+	long len = ftell(fp);
+	fseek(fp, 0, SEEK_SET);
+	printf("unsigned int %s_len = %u;\nunsigned char %s[] = {\n",
+	       argv[1], len, argv[1]);
+	strcpy(buf, "  ");
+	while ((c = getc(fp)) != EOF) {
+		sprintf(s, "%u,", (unsigned char) c);
+		if (strlen(s) + strlen(buf) >= 80)
+			puts(buf), strcpy(buf, "  ");
+		strcat(buf, s);
+	}
+	if (*buf)
+		strcat(buf, "\n");
+	printf("%s};\n", buf);
+	fprintf(stderr, "%s_len = %u\n", argv[1], len);
+	return 0;
+}
Index: winexe/async.c
===================================================================
--- winexe/async.c	(revision 0)
+++ winexe/async.c	(revision 0)
@@ -0,0 +1,248 @@
+/*
+   Copyright (C) Andrzej Hajda 2006
+   Contact: andrzej.hajda at wp.pl
+   License: GNU General Public License version 2
+*/
+
+#include "includes.h"
+#include "libcli/libcli.h"
+#include "winexe.h"
+
+void list_enqueue(struct list *l, const void *data, int size)
+{
+	struct list_item *li =
+	    talloc_size(0, sizeof(struct list_item) + size);
+	memcpy(li->data, data, size);
+	li->size = size;
+	li->next = 0;
+	if (l->end)
+		l->end->next = li;
+	else
+		l->begin = li;
+	l->end = li;
+}
+
+void list_dequeue(struct list *l)
+{
+	struct list_item *li = l->begin;
+	if (!li)
+		return;
+	l->begin = li->next;
+	if (!l->begin)
+		l->end = 0;
+	talloc_free(li);
+}
+
+static void async_read_recv(struct smbcli_request *req)
+{
+	struct async_context *c = req->async.private;
+	NTSTATUS status;
+
+	status = smb_raw_read_recv(c->rreq, c->io_read);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1,
+		      ("ERROR: smb_raw_read_recv - %s\n",
+		       nt_errstr(status)));
+		if (c->cb_error)
+			c->cb_error(c->cb_ctx, ASYNC_READ_RECV, status);
+		return;
+	}
+
+	if (c->cb_read)
+		c->cb_read(c->cb_ctx, c->buffer,
+			   c->io_read->readx.out.nread);
+
+	async_read(c);
+}
+
+static void async_write_recv(struct smbcli_request *req)
+{
+	struct async_context *c = req->async.private;
+	NTSTATUS status;
+
+	status = smb_raw_write_recv(req, c->io_write);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1,
+		      ("ERROR: smb_raw_write_recv - %s\n",
+		       nt_errstr(status)));
+		talloc_free(c->io_write);
+		c->io_write = 0;
+		if (c->cb_error)
+			c->cb_error(c->cb_ctx, ASYNC_WRITE_RECV, status);
+		return;
+	}
+	if (c->wq.begin) {
+		async_write(c, c->wq.begin->data, c->wq.begin->size);
+		list_dequeue(&c->wq);
+	}
+}
+
+static void async_open_recv(struct smbcli_request *req)
+{
+	struct async_context *c = req->async.private;
+	NTSTATUS status;
+
+	status = smb_raw_open_recv(req, c, c->io_open);
+	if (NT_STATUS_IS_OK(status))
+#if 1
+		c->fd = c->io_open->openx.out.file.fnum;
+#else
+		c->fd = c->io_open->ntcreatex.out.file.fnum;
+#endif
+	talloc_free(c->io_open);
+	c->io_open = 0;
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1,
+		      ("ERROR: smb_raw_open_recv - %s\n",
+		       nt_errstr(status)));
+		if (c->cb_error)
+			c->cb_error(c->cb_ctx, ASYNC_OPEN_RECV, status);
+		return;
+	}
+	if (c->cb_open)
+		c->cb_open(c->cb_ctx);
+	async_read(c);
+}
+
+static void async_close_recv(struct smbcli_request *req)
+{
+	struct async_context *c = req->async.private;
+	NTSTATUS status;
+
+	status = smbcli_request_simple_recv(req);
+	talloc_free(c->io_close);
+	c->io_close = 0;
+	if (c->io_open) {
+		talloc_free(c->io_open);
+		c->io_open = 0;
+	}
+	if (c->io_read) {
+		talloc_free(c->io_read);
+		c->io_read = 0;
+	}
+	if (c->io_write) {
+		talloc_free(c->io_write);
+		c->io_write = 0;
+	}
+	if (c->cb_close)
+		c->cb_close(c->cb_ctx);
+}
+
+int async_read(struct async_context *c)
+{
+	if (!c->io_read) {
+		c->io_read = talloc(c->tree, union smb_read);
+		c->io_read->readx.level = RAW_READ_READX;
+		c->io_read->readx.in.file.fnum = c->fd;
+		c->io_read->readx.in.offset = 0;
+		c->io_read->readx.in.mincnt = sizeof(c->buffer);
+		c->io_read->readx.in.maxcnt = sizeof(c->buffer);
+		c->io_read->readx.in.remaining = 0;
+		c->io_read->readx.in.read_for_execute = False;
+		c->io_read->readx.out.data = c->buffer;
+	}
+	c->rreq = smb_raw_read_send(c->tree, c->io_read);
+	if (!c->rreq) {
+		if (c->cb_error)
+			c->cb_error(c->cb_ctx, ASYNC_READ,
+				    NT_STATUS_NO_MEMORY);
+		return 0;
+	}
+	c->rreq->transport->options.request_timeout = 0;
+	c->rreq->async.fn = async_read_recv;
+	c->rreq->async.private = c;
+	return 1;
+}
+
+int async_open(struct async_context *c, const char *fn, int open_mode)
+{
+	DEBUG(1, ("IN: async_open(%s, %d)\n", fn, open_mode));
+	c->io_open = talloc_zero(c, union smb_open);
+	if (!c->io_open)
+		goto failed;
+#if 1
+	c->io_open->openx.level = RAW_OPEN_OPENX;
+	c->io_open->openx.in.flags = 0;
+	c->io_open->openx.in.open_mode = open_mode;
+	c->io_open->openx.in.search_attrs =
+	    FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
+	c->io_open->openx.in.file_attrs = 0;
+	c->io_open->openx.in.write_time = 0;
+	c->io_open->openx.in.open_func = 0;
+	c->io_open->openx.in.size = 0;
+	c->io_open->openx.in.timeout = 0;
+	c->io_open->openx.in.fname = fn;
+#else
+	c->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX;
+        c->io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
+        c->io_open->ntcreatex.in.access_mask = open_mode;
+        c->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+        c->io_open->ntcreatex.in.impersonation    = impersonation;
+        c->io_open->ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE | NTCREATEX_OPTIONS_WRITE_THROUGH;
+        c->io_open->ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC | NTCREATEX_SECURITY_ALL;
+        c->io_open->ntcreatex.in.fname = fn;
+#endif
+	c->rreq = smb_raw_open_send(c->tree, c->io_open);
+	if (!c->rreq)
+		goto failed;
+	c->rreq->async.fn = async_open_recv;
+	c->rreq->async.private = c;
+	return 1;
+      failed:
+	DEBUG(1, ("ERROR: async_open\n"));
+	talloc_free(c);
+	return 0;
+}
+
+int async_write(struct async_context *c, const void *buf, int len)
+{
+	if (c->wreq) {
+		list_enqueue(&c->wq, buf, len);
+		return 0;
+	}
+	if (!c->io_write) {
+		c->io_write = talloc_zero(c, union smb_write);
+		if (!c->io_write)
+			goto failed;
+		c->io_write->write.level = RAW_WRITE_WRITE;
+		c->io_write->write.in.remaining = 0;
+		c->io_write->write.in.file.fnum = c->fd;
+		c->io_write->write.in.offset = 0;
+	}
+	c->io_write->write.in.count = len;
+	c->io_write->write.in.data = buf;
+	struct smbcli_request *req =
+	    smb_raw_write_send(c->tree, c->io_write);
+	if (!req)
+		goto failed;
+	req->async.fn = async_write_recv;
+	req->async.private = c;
+	return 1;
+      failed:
+	DEBUG(1, ("ERROR: async_write\n"));
+	talloc_free(c->io_write);
+	c->io_write = 0;
+	return 0;
+}
+
+int async_close(struct async_context *c)
+{
+	c->io_close = talloc_zero(c, union smb_close);
+	if (!c->io_close)
+		goto failed;
+	c->io_close->close.level = RAW_CLOSE_CLOSE;
+	c->io_close->close.in.file.fnum = c->fd;
+	c->io_close->close.in.write_time = 0;
+	struct smbcli_request *req =
+	    smb_raw_close_send(c->tree, c->io_close);
+	if (!req)
+		goto failed;
+	req->async.fn = async_close_recv;
+	req->async.private = c;
+	return 1;
+      failed:
+	DEBUG(1, ("ERROR: async_close\n"));
+	talloc_free(c->io_close);
+	c->io_close = 0;
+	return 0;
+}
Index: librpc/idl/svcctl.idl
===================================================================
--- librpc/idl/svcctl.idl	(revision 17234)
+++ librpc/idl/svcctl.idl	(working copy)
@@ -165,20 +165,20 @@
 	/*****************/
 	/* Function 0x0c */
 	WERROR svcctl_CreateServiceW([in,ref] policy_handle *scmanager_handle,
-								[in,ref] [string,charset(UTF16)] uint16 *ServiceName,
+								[in] [string,charset(UTF16)] uint16 ServiceName[],
 								[in] [string,charset(UTF16)] uint16 *DisplayName,
 								[in] uint32 desired_access,
 								[in] uint32 type,
 								[in] uint32 start_type,
 								[in] uint32 error_control,
-								[in,ref] [string,charset(UTF16)] uint16 *binary_path,
+								[in] [string,charset(UTF16)] uint16 binary_path[],
 								[in] [string,charset(UTF16)] uint16 *LoadOrderGroupKey,
   								[in,out] uint32 *TagId,
-								[in] [string,charset(UTF16)] uint16 *dependencies,
-								[in] uint32 fix_len_dependencies,
+								[in,size_is(dependencies_size)] uint8 *dependencies,
+								[in] uint32 dependencies_size,
 								[in] [string,charset(UTF16)] uint16 *service_start_name,
-								[in] [string,charset(UTF16)] uint16 *password,
-								[in] uint32 fix_len_password,
+								[in,size_is(password_size)] uint8 *password,
+								[in] uint32 password_size,
 								[out,ref] policy_handle *handle);
 
 	/*****************/
@@ -213,7 +213,7 @@
 	/*****************/
 	/* Function 0x10 */
 	WERROR svcctl_OpenServiceW([in,ref] policy_handle *scmanager_handle,
-							  [in,ref] [string,charset(UTF16)] uint16 *ServiceName,
+							  [in] [string,charset(UTF16)] uint16 ServiceName[],
 							  [in] uint32 access_mask,
 					                  [out,ref] policy_handle *handle);
 


More information about the samba-technical mailing list