| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2006-2010 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Author: Alexander Larsson <alexl@redhat.com> | 
					
						
							|  |  |  |  * Author: Tor Lillqvist <tml@iki.fi> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <windows.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <io.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <glib.h>
 | 
					
						
							|  |  |  | #include "gioerror.h"
 | 
					
						
							|  |  |  | #include "gwin32inputstream.h"
 | 
					
						
							| 
									
										
										
										
											2013-10-21 14:55:21 -04:00
										 |  |  | #include "giowin32-priv.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | #include "gcancellable.h"
 | 
					
						
							|  |  |  | #include "gasynchelper.h"
 | 
					
						
							|  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2023-11-02 16:28:37 +00:00
										 |  |  |  * GWin32InputStream: | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-11-02 16:28:37 +00:00
										 |  |  |  * `GWin32InputStream` implements [class@Gio.InputStream] for reading from a | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  * Windows file handle. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-09 02:07:26 -05:00
										 |  |  |  * Note that `<gio/gwin32inputstream.h>` belongs to the Windows-specific GIO | 
					
						
							| 
									
										
										
										
											2014-02-05 20:17:46 -05:00
										 |  |  |  * interfaces, thus you have to use the `gio-windows-2.0.pc` pkg-config file | 
					
						
							|  |  |  |  * when using it. | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct _GWin32InputStreamPrivate { | 
					
						
							|  |  |  |   HANDLE handle; | 
					
						
							|  |  |  |   gboolean close_handle; | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  |   gint fd; | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  | enum { | 
					
						
							|  |  |  |   PROP_0, | 
					
						
							|  |  |  |   PROP_HANDLE, | 
					
						
							|  |  |  |   PROP_CLOSE_HANDLE, | 
					
						
							|  |  |  |   LAST_PROP | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  | static GParamSpec *props[LAST_PROP]; | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  | G_DEFINE_TYPE_WITH_PRIVATE (GWin32InputStream, g_win32_input_stream, G_TYPE_INPUT_STREAM) | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_win32_input_stream_set_property (GObject         *object, | 
					
						
							|  |  |  | 				   guint            prop_id, | 
					
						
							|  |  |  | 				   const GValue    *value, | 
					
						
							|  |  |  | 				   GParamSpec      *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GWin32InputStream *win32_stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   win32_stream = G_WIN32_INPUT_STREAM (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PROP_HANDLE: | 
					
						
							|  |  |  |       win32_stream->priv->handle = g_value_get_pointer (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_CLOSE_HANDLE: | 
					
						
							|  |  |  |       win32_stream->priv->close_handle = g_value_get_boolean (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_win32_input_stream_get_property (GObject    *object, | 
					
						
							|  |  |  | 				   guint       prop_id, | 
					
						
							|  |  |  | 				   GValue     *value, | 
					
						
							|  |  |  | 				   GParamSpec *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GWin32InputStream *win32_stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   win32_stream = G_WIN32_INPUT_STREAM (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PROP_HANDLE: | 
					
						
							|  |  |  |       g_value_set_pointer (value, win32_stream->priv->handle); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_CLOSE_HANDLE: | 
					
						
							|  |  |  |       g_value_set_boolean (value, win32_stream->priv->close_handle); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  |   OVERLAPPED overlap = { 0, }; | 
					
						
							|  |  |  |   gssize retval = -1; | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  |   overlap.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (overlap.hEvent != NULL, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   res = ReadFile (win32_stream->priv->handle, buffer, nbytes, &nread, &overlap); | 
					
						
							|  |  |  |   if (res) | 
					
						
							|  |  |  |     retval = nread; | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |     { | 
					
						
							|  |  |  |       int errsv = GetLastError (); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  |       if (errsv == ERROR_IO_PENDING && | 
					
						
							|  |  |  |           _g_win32_overlap_wait_result (win32_stream->priv->handle, | 
					
						
							|  |  |  |                                         &overlap, &nread, cancellable)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           retval = nread; | 
					
						
							|  |  |  |           goto end; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  |       if (g_cancellable_set_error_if_cancelled (cancellable, error)) | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       errsv = GetLastError (); | 
					
						
							| 
									
										
										
										
											2012-08-08 01:08:15 +02:00
										 |  |  |       if (errsv == ERROR_MORE_DATA) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           /* If a named pipe is being read in message mode and the
 | 
					
						
							|  |  |  |            * next message is longer than the nNumberOfBytesToRead | 
					
						
							|  |  |  |            * parameter specifies, ReadFile returns FALSE and | 
					
						
							|  |  |  |            * GetLastError returns ERROR_MORE_DATA */ | 
					
						
							|  |  |  |           retval = nread; | 
					
						
							|  |  |  |           goto end; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       else if (errsv == ERROR_HANDLE_EOF || | 
					
						
							|  |  |  |                errsv == ERROR_BROKEN_PIPE) | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |           /* TODO: the other end of a pipe may call the WriteFile
 | 
					
						
							|  |  |  |            * function with nNumberOfBytesToWrite set to zero. In this | 
					
						
							|  |  |  |            * case, it's not possible for the caller to know if it's | 
					
						
							|  |  |  |            * broken pipe or a read of 0. Perhaps we should add a | 
					
						
							|  |  |  |            * is_broken flag for this win32 case.. */ | 
					
						
							|  |  |  |           retval = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           gchar *emsg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-02 21:45:41 +02:00
										 |  |  | end: | 
					
						
							|  |  |  |   CloseHandle (overlap.hEvent); | 
					
						
							|  |  |  |   return retval; | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | g_win32_input_stream_close (GInputStream  *stream, | 
					
						
							|  |  |  | 			   GCancellable  *cancellable, | 
					
						
							|  |  |  | 			   GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GWin32InputStream *win32_stream; | 
					
						
							|  |  |  |   BOOL res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   win32_stream = G_WIN32_INPUT_STREAM (stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!win32_stream->priv->close_handle) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  |   if (win32_stream->priv->fd != -1) | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  |       if (close (win32_stream->priv->fd) < 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-02-25 17:23:50 +01:00
										 |  |  | 	  int errsv = errno; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  g_set_error (error, G_IO_ERROR, | 
					
						
							|  |  |  | 	               g_io_error_from_errno (errsv), | 
					
						
							|  |  |  | 	               _("Error closing file descriptor: %s"), | 
					
						
							|  |  |  | 	               g_strerror (errsv)); | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       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; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-19 11:32:05 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  | static void | 
					
						
							|  |  |  | g_win32_input_stream_class_init (GWin32InputStreamClass *klass) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | 
					
						
							|  |  |  |   GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gobject_class->get_property = g_win32_input_stream_get_property; | 
					
						
							|  |  |  |   gobject_class->set_property = g_win32_input_stream_set_property; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   stream_class->read_fn = g_win32_input_stream_read; | 
					
						
							|  |  |  |   stream_class->close_fn = g_win32_input_stream_close; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GWin32InputStream:handle: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The handle that the stream reads from. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.26 | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   props[PROP_HANDLE] = | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |     g_param_spec_pointer ("handle", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  |                           G_PARAM_READABLE | | 
					
						
							|  |  |  |                           G_PARAM_WRITABLE | | 
					
						
							|  |  |  |                           G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                           G_PARAM_STATIC_STRINGS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GWin32InputStream:close-handle: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Whether to close the file handle when the stream is closed. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.26 | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   props[PROP_CLOSE_HANDLE] = | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |     g_param_spec_boolean ("close-handle", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2016-02-25 09:56:25 +01:00
										 |  |  |                           TRUE, | 
					
						
							|  |  |  |                           G_PARAM_READABLE | | 
					
						
							|  |  |  |                           G_PARAM_WRITABLE | | 
					
						
							|  |  |  |                           G_PARAM_STATIC_STRINGS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_object_class_install_properties (gobject_class, LAST_PROP, props); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_win32_input_stream_init (GWin32InputStream *win32_stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   win32_stream->priv = g_win32_input_stream_get_instance_private (win32_stream); | 
					
						
							|  |  |  |   win32_stream->priv->handle = NULL; | 
					
						
							|  |  |  |   win32_stream->priv->close_handle = TRUE; | 
					
						
							|  |  |  |   win32_stream->priv->fd = -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_win32_input_stream_new: | 
					
						
							|  |  |  |  * @handle: a Win32 file handle | 
					
						
							|  |  |  |  * @close_handle: %TRUE to close the handle when done | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Creates a new #GWin32InputStream for the given @handle. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * If @close_handle is %TRUE, the handle will be closed | 
					
						
							|  |  |  |  * when the stream is closed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Note that "handle" here means a Win32 HANDLE, not a "file descriptor" | 
					
						
							|  |  |  |  * as used in the Windows C libraries. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: a new #GWin32InputStream | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | GInputStream * | 
					
						
							|  |  |  | g_win32_input_stream_new (void     *handle, | 
					
						
							|  |  |  | 			  gboolean close_handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GWin32InputStream *stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_val_if_fail (handle != NULL, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   stream = g_object_new (G_TYPE_WIN32_INPUT_STREAM, | 
					
						
							|  |  |  | 			 "handle", handle, | 
					
						
							|  |  |  | 			 "close-handle", close_handle, | 
					
						
							|  |  |  | 			 NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return G_INPUT_STREAM (stream); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_win32_input_stream_set_close_handle: | 
					
						
							|  |  |  |  * @stream: a #GWin32InputStream | 
					
						
							|  |  |  |  * @close_handle: %TRUE to close the handle when done | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Sets whether the handle of @stream shall be closed | 
					
						
							|  |  |  |  * when the stream is closed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | g_win32_input_stream_set_close_handle (GWin32InputStream *stream, | 
					
						
							|  |  |  | 				       gboolean          close_handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_if_fail (G_IS_WIN32_INPUT_STREAM (stream)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   close_handle = close_handle != FALSE; | 
					
						
							|  |  |  |   if (stream->priv->close_handle != close_handle) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       stream->priv->close_handle = close_handle; | 
					
						
							|  |  |  |       g_object_notify (G_OBJECT (stream), "close-handle"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_win32_input_stream_get_close_handle: | 
					
						
							|  |  |  |  * @stream: a #GWin32InputStream | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns whether the handle of @stream will be | 
					
						
							|  |  |  |  * closed when the stream is closed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: %TRUE if the handle is closed when done | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_win32_input_stream_get_close_handle (GWin32InputStream *stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_WIN32_INPUT_STREAM (stream), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return stream->priv->close_handle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_win32_input_stream_get_handle: | 
					
						
							|  |  |  |  * @stream: a #GWin32InputStream | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Return the Windows file handle that the stream reads from. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: The file handle of @stream | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void * | 
					
						
							|  |  |  | g_win32_input_stream_get_handle (GWin32InputStream *stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_WIN32_INPUT_STREAM (stream), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return stream->priv->handle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 16:06:10 -04:00
										 |  |  | GInputStream * | 
					
						
							|  |  |  | g_win32_input_stream_new_from_fd (gint      fd, | 
					
						
							|  |  |  | 				  gboolean  close_fd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GWin32InputStream *win32_stream; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   win32_stream = G_WIN32_INPUT_STREAM (g_win32_input_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); | 
					
						
							|  |  |  |   win32_stream->priv->fd = fd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (GInputStream*)win32_stream; | 
					
						
							|  |  |  | } |