+ stdeh = GetStdHandle (STD_ERROR_HANDLE);
+ GetHandleInformation (stdeh, &stdef);
+ if (stdeh)
+ {
+ if (std_inheritance & GNUNET_OS_INHERIT_STD_ERR)
+ {
+ SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 1);
+ start.hStdError = stdeh;
+ }
+ else
+ SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 0);
+ }
+
+ if (GNUNET_YES == pipe_control)
+ {
+ struct GNUNET_DISK_PipeHandle *childpipe;
+ childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
+ if (NULL == childpipe)
+ return NULL;
+ childpipe_read = GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ);
+ childpipe_write = GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE);
+ GNUNET_DISK_pipe_close (childpipe);
+ if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
+ (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read,
+ &childpipe_read_handle, sizeof (HANDLE))))
+ {
+ if (childpipe_read)
+ GNUNET_DISK_file_close (childpipe_read);
+ if (childpipe_write)
+ GNUNET_DISK_file_close (childpipe_write);
+ GNUNET_free (cmd);
+ return NULL;
+ }
+ /* Unlike *nix variant, we don't dup the handle, so can't close
+ * filehandle right now.
+ */
+ SetHandleInformation (childpipe_read_handle, HANDLE_FLAG_INHERIT, 1);
+ }
+ else
+ {
+ childpipe_read = NULL;
+ childpipe_write = NULL;
+ }
+
+ if (lsocks != NULL && lsocks[0] != INVALID_SOCKET)
+ {
+ lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
+
+ if (lsocks_pipe == NULL)
+ {
+ GNUNET_free (cmd);
+ GNUNET_DISK_pipe_close (lsocks_pipe);
+ if (GNUNET_YES == pipe_control)
+ {
+ GNUNET_DISK_file_close (childpipe_write);
+ GNUNET_DISK_file_close (childpipe_read);
+ }
+ return NULL;
+ }
+ lsocks_write_fd = GNUNET_DISK_pipe_handle (lsocks_pipe,
+ GNUNET_DISK_PIPE_END_WRITE);
+ GNUNET_DISK_internal_file_handle_ (lsocks_write_fd,
+ &lsocks_write, sizeof (HANDLE));
+ GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
+ (lsocks_pipe, GNUNET_DISK_PIPE_END_READ),
+ &lsocks_read, sizeof (HANDLE));
+ }
+ else
+ lsocks_pipe = NULL;
+
+ env_off = 0;
+ if (GNUNET_YES == pipe_control)
+ {
+ GNUNET_asprintf (&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE);
+ GNUNET_asprintf (&our_env[env_off++], "%p", childpipe_read_handle);
+ }
+ if ( (lsocks != NULL) && (lsocks[0] != INVALID_SOCKET))
+ {
+ /*This will tell the child that we're going to send lsocks over the pipe*/
+ GNUNET_asprintf (&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS");
+ GNUNET_asprintf (&our_env[env_off++], "%lu", lsocks_read);
+ }
+ our_env[env_off++] = NULL;
+ env_block = CreateCustomEnvTable (our_env);
+ while (0 > env_off)
+ GNUNET_free_non_null (our_env[--env_off]);
+
+ wpath_len = 0;
+ if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ if (lsocks_pipe)
+ GNUNET_DISK_pipe_close (lsocks_pipe);
+ if (GNUNET_YES == pipe_control)
+ {
+ GNUNET_DISK_file_close (childpipe_write);
+ GNUNET_DISK_file_close (childpipe_read);
+ }
+ return NULL;
+ }
+
+ wcmd_len = 0;
+ if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ free (wpath);
+ if (lsocks_pipe)
+ GNUNET_DISK_pipe_close (lsocks_pipe);
+ if (GNUNET_YES == pipe_control)
+ {
+ GNUNET_DISK_file_close (childpipe_write);
+ GNUNET_DISK_file_close (childpipe_read);
+ }
+ return NULL;
+ }
+
+ bresult = CreateProcessW (wpath, wcmd, NULL, NULL, GNUNET_YES,
+ DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc);
+ error_code = GetLastError ();
+
+ if ((NULL == pipe_stdin) && (stdih))
+ SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, stdif);
+
+
+ if ((NULL == pipe_stdout) && (stdoh))
+ SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, stdof);
+
+ if (stdeh)
+ SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, stdef);
+
+ if (!bresult)
+ LOG (GNUNET_ERROR_TYPE_ERROR, "CreateProcess(%s, %s) failed: %lu\n", path, cmd, error_code);
+
+ GNUNET_free (env_block);