static gboolean
g_win32_output_stream_close (GOutputStream  *stream,
			     GCancellable   *cancellable,
			     GError        **error)
{
  GWin32OutputStream *win32_stream;
  BOOL res;

  win32_stream = G_WIN32_OUTPUT_STREAM (stream);

  if (!win32_stream->priv->close_handle)
    return TRUE;

  res = CloseHandle (win32_stream->priv->handle);
  if (!res)
    {
      int errsv = GetLastError ();
      gchar *emsg = g_win32_error_message (errsv);

      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_win32_error (errsv),
		   _("Error closing handle: %s"),
		   emsg);
      g_free (emsg);
      return FALSE;
    }

  return TRUE;
}
Beispiel #2
0
SpiceNamedPipe*
spice_win32_user_pipe_new (gchar *name, GError **error)
{
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    PACL dacl = NULL;
    HANDLE pipe;
    SpiceNamedPipe *np = NULL;

    g_return_val_if_fail (name != NULL, NULL);
    g_return_val_if_fail (error != NULL, NULL);

    if (!get_user_security_attributes (&sa, &sd, &dacl))
        return NULL;

    pipe = CreateNamedPipe (name,
                            PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
                            /* FIXME: why is FILE_FLAG_FIRST_PIPE_INSTANCE needed for WRITE_DAC
                             * (apparently needed by SetSecurityInfo). This will prevent
                             * multiple pipe listener....?! */
                            FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
                            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                            PIPE_UNLIMITED_INSTANCES,
                            DEFAULT_PIPE_BUF_SIZE, DEFAULT_PIPE_BUF_SIZE,
                            0, &sa);

    if (pipe == INVALID_HANDLE_VALUE) {
        int errsv = GetLastError ();
        gchar *emsg = g_win32_error_message (errsv);

        g_set_error (error,
                     G_IO_ERROR,
                     g_io_error_from_win32_error (errsv),
                     "Error CreateNamedPipe(): %s",
                     emsg);

        g_free (emsg);
        goto end;
    }

    /* lower integrity on Vista/Win7+ */
    if ((LOBYTE (g_win32_get_windows_version()) > 0x05
            || LOWORD (g_win32_get_windows_version()) > 0x0105) &&
            !spice_win32_set_low_integrity (pipe, error))
        goto end;

    np = SPICE_NAMED_PIPE (g_initable_new (SPICE_TYPE_NAMED_PIPE,
                                           NULL, error, "handle", pipe, NULL));

end:
    LocalFree (dacl);

    return np;
}
Beispiel #3
0
gboolean
spice_win32_set_low_integrity (void* handle, GError **error)
{
    g_return_val_if_fail (handle != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    /* see also http://msdn.microsoft.com/en-us/library/bb625960.aspx */
    PSECURITY_DESCRIPTOR psd = NULL;
    PACL psacl = NULL;
    BOOL sacl_present = FALSE;
    BOOL sacl_defaulted = FALSE;
    char *emsg;
    int errsv;
    gboolean success = FALSE;

    if (!ConvertStringSecurityDescriptorToSecurityDescriptor ("S:(ML;;NW;;;LW)",
            SDDL_REVISION_1, &psd, NULL))
        goto failed;

    if (!GetSecurityDescriptorSacl (psd, &sacl_present, &psacl, &sacl_defaulted))
        goto failed;

    if (SetSecurityInfo (handle, SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION,
                         NULL, NULL, NULL, psacl) != ERROR_SUCCESS)
        goto failed;

    success = TRUE;
    goto end;

failed:
    errsv = GetLastError ();
    emsg = g_win32_error_message (errsv);
    g_set_error (error, G_IO_ERROR,
                 g_io_error_from_win32_error (errsv),
                 "Error setting integrity: %s",
                 emsg);
    g_free (emsg);

end:
    if (psd != NULL)
        LocalFree (psd);

    return success;
}
static gssize
g_win32_input_stream_read (GInputStream  *stream,
			   void          *buffer,
			   gsize          count,
			   GCancellable  *cancellable,
			   GError       **error)
{
  GWin32InputStream *win32_stream;
  BOOL res;
  DWORD nbytes, nread;

  win32_stream = G_WIN32_INPUT_STREAM (stream);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  if (count > G_MAXINT)
    nbytes = G_MAXINT;
  else
    nbytes = count;

  res = ReadFile (win32_stream->priv->handle, buffer, nbytes, &nread, NULL);
  if (!res)
    {
      int errsv = GetLastError ();
      gchar *emsg;

      if (errsv == ERROR_HANDLE_EOF ||
	  errsv == ERROR_BROKEN_PIPE)
	return 0;

      emsg = g_win32_error_message (errsv);
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_win32_error (errsv),
		   _("Error reading from handle: %s"),
		   emsg);
      g_free (emsg);
      return -1;
    }

  return nread;
}
static gssize
g_win32_output_stream_write (GOutputStream  *stream,
			    const void     *buffer,
			    gsize           count,
			    GCancellable   *cancellable,
			    GError        **error)
{
  GWin32OutputStream *win32_stream;
  BOOL res;
  DWORD nbytes, nwritten;

  win32_stream = G_WIN32_OUTPUT_STREAM (stream);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  if (count > G_MAXINT)
    nbytes = G_MAXINT;
  else
    nbytes = count;

  res = WriteFile (win32_stream->priv->handle, buffer, nbytes, &nwritten, NULL);
  if (!res)
    {
      int errsv = GetLastError ();
      gchar *emsg = g_win32_error_message (errsv);

      if (errsv == ERROR_HANDLE_EOF)
	return 0;

      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_win32_error (errsv),
		   _("Error writing to handle: %s"),
		   emsg);
      g_free (emsg);
      return -1;
    }

  return nwritten;
}