1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2008 Novell, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 * Author: Alexander Larsson <alexl@redhat.com>
22 * Author: Tor Lillqvist <tml@novell.com>
23 */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <wchar.h>
30
31 #include "gfile.h"
32 #include "gfileattribute.h"
33 #include "gfileinfo.h"
34 #include "gwinhttpfile.h"
35 #include "gwinhttpfileinputstream.h"
36 #include "gwinhttpfileoutputstream.h"
37 #include "gioerror.h"
38
39 #include "glibintl.h"
40
41 #include "gioalias.h"
42
43 static void g_winhttp_file_file_iface_init (GFileIface *iface);
44
45 #define g_winhttp_file_get_type _g_winhttp_file_get_type
G_DEFINE_TYPE_WITH_CODE(GWinHttpFile,g_winhttp_file,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (G_TYPE_FILE,g_winhttp_file_file_iface_init))46 G_DEFINE_TYPE_WITH_CODE (GWinHttpFile, g_winhttp_file, G_TYPE_OBJECT,
47 G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
48 g_winhttp_file_file_iface_init))
49
50 static void
51 g_winhttp_file_finalize (GObject *object)
52 {
53 GWinHttpFile *file;
54
55 file = G_WINHTTP_FILE (object);
56
57 g_free (file->url.lpszScheme);
58 g_free (file->url.lpszHostName);
59 g_free (file->url.lpszUserName);
60 g_free (file->url.lpszPassword);
61 g_free (file->url.lpszUrlPath);
62 g_free (file->url.lpszExtraInfo);
63
64 g_object_unref (file->vfs);
65
66 G_OBJECT_CLASS (g_winhttp_file_parent_class)->finalize (object);
67 }
68
69 static void
g_winhttp_file_class_init(GWinHttpFileClass * klass)70 g_winhttp_file_class_init (GWinHttpFileClass *klass)
71 {
72 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
73
74 gobject_class->finalize = g_winhttp_file_finalize;
75 }
76
77 static void
g_winhttp_file_init(GWinHttpFile * winhttp)78 g_winhttp_file_init (GWinHttpFile *winhttp)
79 {
80 }
81
82 /**
83 * _g_winhttp_file_new:
84 * @vfs: GWinHttpVfs to use
85 * @uri: URI of the GWinHttpFile to create.
86 *
87 * Returns: new winhttp #GFile.
88 **/
89 GFile *
_g_winhttp_file_new(GWinHttpVfs * vfs,const char * uri)90 _g_winhttp_file_new (GWinHttpVfs *vfs,
91 const char *uri)
92 {
93 wchar_t *wuri;
94 GWinHttpFile *file;
95
96 wuri = g_utf8_to_utf16 (uri, -1, NULL, NULL, NULL);
97
98 if (wuri == NULL)
99 return NULL;
100
101 file = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
102 file->vfs = g_object_ref (vfs);
103
104 memset (&file->url, 0, sizeof (file->url));
105 file->url.dwStructSize = sizeof (file->url);
106 file->url.dwSchemeLength = 1;
107 file->url.dwHostNameLength = 1;
108 file->url.dwUserNameLength = 1;
109 file->url.dwPasswordLength = 1;
110 file->url.dwUrlPathLength = 1;
111 file->url.dwExtraInfoLength = 1;
112
113 if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
114 {
115 g_free (wuri);
116 return NULL;
117 }
118
119 file->url.lpszScheme = g_new (wchar_t, ++file->url.dwSchemeLength);
120 file->url.lpszHostName = g_new (wchar_t, ++file->url.dwHostNameLength);
121 file->url.lpszUserName = g_new (wchar_t, ++file->url.dwUserNameLength);
122 file->url.lpszPassword = g_new (wchar_t, ++file->url.dwPasswordLength);
123 file->url.lpszUrlPath = g_new (wchar_t, ++file->url.dwUrlPathLength);
124 file->url.lpszExtraInfo = g_new (wchar_t, ++file->url.dwExtraInfoLength);
125
126 if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
127 {
128 g_free (file->url.lpszScheme);
129 g_free (file->url.lpszHostName);
130 g_free (file->url.lpszUserName);
131 g_free (file->url.lpszPassword);
132 g_free (file->url.lpszUrlPath);
133 g_free (file->url.lpszExtraInfo);
134 g_free (wuri);
135 return NULL;
136 }
137
138 g_free (wuri);
139 return G_FILE (file);
140 }
141
142 static gboolean
g_winhttp_file_is_native(GFile * file)143 g_winhttp_file_is_native (GFile *file)
144 {
145 return FALSE;
146 }
147
148 static gboolean
g_winhttp_file_has_uri_scheme(GFile * file,const char * uri_scheme)149 g_winhttp_file_has_uri_scheme (GFile *file,
150 const char *uri_scheme)
151 {
152 return (g_ascii_strcasecmp (uri_scheme, "http") == 0 ||
153 g_ascii_strcasecmp (uri_scheme, "https") == 0);
154 }
155
156 static char *
g_winhttp_file_get_uri_scheme(GFile * file)157 g_winhttp_file_get_uri_scheme (GFile *file)
158 {
159 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
160
161 return g_utf16_to_utf8 (winhttp_file->url.lpszScheme, -1, NULL, NULL, NULL);
162 }
163
164 static char *
g_winhttp_file_get_basename(GFile * file)165 g_winhttp_file_get_basename (GFile *file)
166 {
167 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
168 char *basename;
169 char *last_slash;
170 char *retval;
171
172 basename = g_utf16_to_utf8 (winhttp_file->url.lpszUrlPath, -1, NULL, NULL, NULL);
173 last_slash = strrchr (basename, '/');
174 /* If no slash, or only "/" fallback to full path part of URI */
175 if (last_slash == NULL || last_slash[1] == '\0')
176 return basename;
177
178 retval = g_strdup (last_slash + 1);
179 g_free (basename);
180
181 return retval;
182 }
183
184 static char *
g_winhttp_file_get_path(GFile * file)185 g_winhttp_file_get_path (GFile *file)
186 {
187 return NULL;
188 }
189
190 static char *
g_winhttp_file_get_uri(GFile * file)191 g_winhttp_file_get_uri (GFile *file)
192 {
193 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
194 DWORD len;
195 wchar_t *wuri;
196 char *retval;
197
198 len = 0;
199 if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, NULL, &len) &&
200 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
201 return NULL;
202
203 wuri = g_new (wchar_t, ++len);
204
205 if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, wuri, &len))
206 {
207 g_free (wuri);
208 return NULL;
209 }
210
211 retval = g_utf16_to_utf8 (wuri, -1, NULL, NULL, NULL);
212 g_free (wuri);
213
214 if (g_str_has_prefix (retval, "http://:@"))
215 {
216 memmove (retval + 7, retval + 9, strlen (retval) - 9);
217 retval[strlen (retval) - 2] = '\0';
218 }
219 else if (g_str_has_prefix (retval, "https://:@"))
220 {
221 memmove (retval + 8, retval + 10, strlen (retval) - 10);
222 retval[strlen (retval) - 2] = '\0';
223 }
224
225 return retval;
226 }
227
228 static char *
g_winhttp_file_get_parse_name(GFile * file)229 g_winhttp_file_get_parse_name (GFile *file)
230 {
231 /* FIXME: More hair surely needed */
232
233 return g_winhttp_file_get_uri (file);
234 }
235
236 static GFile *
g_winhttp_file_get_parent(GFile * file)237 g_winhttp_file_get_parent (GFile *file)
238 {
239 GWinHttpFile *winhttp_file;
240 char *uri;
241 char *last_slash;
242 GFile *parent;
243
244 winhttp_file = G_WINHTTP_FILE (file);
245
246 uri = g_winhttp_file_get_uri (file);
247 if (uri == NULL)
248 return NULL;
249
250 last_slash = strrchr (uri, '/');
251 if (last_slash == NULL || *(last_slash+1) == 0)
252 {
253 g_free (uri);
254 return NULL;
255 }
256
257 while (last_slash > uri && *last_slash == '/')
258 last_slash--;
259
260 last_slash[1] = '\0';
261
262 parent = _g_winhttp_file_new (winhttp_file->vfs, uri);
263 g_free (uri);
264
265 return parent;
266 }
267
268 static GFile *
g_winhttp_file_dup(GFile * file)269 g_winhttp_file_dup (GFile *file)
270 {
271 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
272 char *uri = g_winhttp_file_get_uri (file);
273 GFile *retval = _g_winhttp_file_new (winhttp_file->vfs, uri);
274
275 g_free (uri);
276
277 return retval;
278 }
279
280 static guint
g_winhttp_file_hash(GFile * file)281 g_winhttp_file_hash (GFile *file)
282 {
283 char *uri = g_winhttp_file_get_uri (file);
284 guint retval = g_str_hash (uri);
285
286 g_free (uri);
287
288 return retval;
289 }
290
291 static gboolean
g_winhttp_file_equal(GFile * file1,GFile * file2)292 g_winhttp_file_equal (GFile *file1,
293 GFile *file2)
294 {
295 char *uri1 = g_winhttp_file_get_uri (file1);
296 char *uri2 = g_winhttp_file_get_uri (file2);
297 gboolean retval = g_str_equal (uri1, uri2);
298
299 g_free (uri1);
300 g_free (uri2);
301
302 return retval;
303 }
304
305 static const char *
match_prefix(const char * path,const char * prefix)306 match_prefix (const char *path,
307 const char *prefix)
308 {
309 int prefix_len;
310
311 prefix_len = strlen (prefix);
312 if (strncmp (path, prefix, prefix_len) != 0)
313 return NULL;
314
315 if (prefix_len > 0 && prefix[prefix_len-1] == '/')
316 prefix_len--;
317
318 return path + prefix_len;
319 }
320
321 static gboolean
g_winhttp_file_prefix_matches(GFile * parent,GFile * descendant)322 g_winhttp_file_prefix_matches (GFile *parent,
323 GFile *descendant)
324 {
325 char *parent_uri = g_winhttp_file_get_uri (parent);
326 char *descendant_uri = g_winhttp_file_get_uri (descendant);
327 const char *remainder;
328 gboolean retval;
329
330 remainder = match_prefix (descendant_uri, parent_uri);
331
332 if (remainder != NULL && *remainder == '/')
333 retval = TRUE;
334 else
335 retval = FALSE;
336
337 g_free (parent_uri);
338 g_free (descendant_uri);
339
340 return retval;
341 }
342
343 static char *
g_winhttp_file_get_relative_path(GFile * parent,GFile * descendant)344 g_winhttp_file_get_relative_path (GFile *parent,
345 GFile *descendant)
346 {
347 char *parent_uri = g_winhttp_file_get_uri (parent);
348 char *descendant_uri = g_winhttp_file_get_uri (descendant);
349 const char *remainder;
350 char *retval;
351
352 remainder = match_prefix (descendant_uri, parent_uri);
353
354 if (remainder != NULL && *remainder == '/')
355 retval = g_strdup (remainder + 1);
356 else
357 retval = NULL;
358
359 g_free (parent_uri);
360 g_free (descendant_uri);
361
362 return retval;
363 }
364
365 static GFile *
g_winhttp_file_resolve_relative_path(GFile * file,const char * relative_path)366 g_winhttp_file_resolve_relative_path (GFile *file,
367 const char *relative_path)
368 {
369 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
370 GWinHttpFile *child;
371 wchar_t *wnew_path = g_utf8_to_utf16 (relative_path, -1, NULL, NULL, NULL);
372
373 if (wnew_path == NULL)
374 return NULL;
375
376 if (*wnew_path != '/')
377 {
378 wchar_t *tmp = g_new (wchar_t, wcslen (winhttp_file->url.lpszUrlPath) + 1 + wcslen (wnew_path) + 1);
379 wcscpy (tmp, winhttp_file->url.lpszUrlPath);
380 wcscat (tmp, L"/");
381 wcscat (tmp, wnew_path);
382
383 g_free (wnew_path);
384 wnew_path = tmp;
385 }
386
387 child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
388 child->vfs = winhttp_file->vfs;
389 child->url = winhttp_file->url;
390 child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
391 child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
392 child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
393 child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
394 child->url.lpszUrlPath = wnew_path;
395 child->url.dwUrlPathLength = wcslen (wnew_path);
396 child->url.lpszExtraInfo = NULL;
397 child->url.dwExtraInfoLength = 0;
398
399 return (GFile *) child;
400 }
401
402 static GFile *
g_winhttp_file_get_child_for_display_name(GFile * file,const char * display_name,GError ** error)403 g_winhttp_file_get_child_for_display_name (GFile *file,
404 const char *display_name,
405 GError **error)
406 {
407 GFile *new_file;
408 char *basename;
409
410 basename = g_locale_from_utf8 (display_name, -1, NULL, NULL, NULL);
411 if (basename == NULL)
412 {
413 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME,
414 _("Invalid filename %s"), display_name);
415 return NULL;
416 }
417
418 new_file = g_file_get_child (file, basename);
419 g_free (basename);
420
421 return new_file;
422 }
423
424 static GFile *
g_winhttp_file_set_display_name(GFile * file,const char * display_name,GCancellable * cancellable,GError ** error)425 g_winhttp_file_set_display_name (GFile *file,
426 const char *display_name,
427 GCancellable *cancellable,
428 GError **error)
429 {
430 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
431 _("Operation not supported"));
432
433 return NULL;
434 }
435
436 static time_t
mktime_utc(SYSTEMTIME * t)437 mktime_utc (SYSTEMTIME *t)
438 {
439 time_t retval;
440
441 static const gint days_before[] =
442 {
443 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
444 };
445
446 if (t->wMonth < 1 || t->wMonth > 12)
447 return (time_t) -1;
448
449 retval = (t->wYear - 1970) * 365;
450 retval += (t->wYear - 1968) / 4;
451 retval += days_before[t->wMonth-1] + t->wDay - 1;
452
453 if (t->wYear % 4 == 0 && t->wMonth < 3)
454 retval -= 1;
455
456 retval = ((((retval * 24) + t->wHour) * 60) + t->wMinute) * 60 + t->wSecond;
457
458 return retval;
459 }
460
461 static GFileInfo *
g_winhttp_file_query_info(GFile * file,const char * attributes,GFileQueryInfoFlags flags,GCancellable * cancellable,GError ** error)462 g_winhttp_file_query_info (GFile *file,
463 const char *attributes,
464 GFileQueryInfoFlags flags,
465 GCancellable *cancellable,
466 GError **error)
467 {
468 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
469 HINTERNET connection, request;
470 const wchar_t *accept_types[] =
471 {
472 L"*/*",
473 NULL,
474 };
475 GFileInfo *info;
476 GFileAttributeMatcher *matcher;
477 char *basename;
478 wchar_t *content_length;
479 wchar_t *content_type;
480 SYSTEMTIME last_modified;
481 DWORD last_modified_len;
482
483 connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
484 (G_WINHTTP_VFS (winhttp_file->vfs)->session,
485 winhttp_file->url.lpszHostName,
486 winhttp_file->url.nPort,
487 0);
488
489 if (connection == NULL)
490 {
491 _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
492
493 return NULL;
494 }
495
496 request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest
497 (connection,
498 L"HEAD",
499 winhttp_file->url.lpszUrlPath,
500 NULL,
501 WINHTTP_NO_REFERER,
502 accept_types,
503 winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
504
505 if (request == NULL)
506 {
507 _g_winhttp_set_error (error, GetLastError (), "HEAD request");
508
509 return NULL;
510 }
511
512 if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpSendRequest
513 (request,
514 NULL, 0,
515 NULL, 0,
516 0,
517 0))
518 {
519 _g_winhttp_set_error (error, GetLastError (), "HEAD request");
520
521 return NULL;
522 }
523
524 if (!_g_winhttp_response (winhttp_file->vfs, request, error, "HEAD request"))
525 return NULL;
526
527 matcher = g_file_attribute_matcher_new (attributes);
528 info = g_file_info_new ();
529 g_file_info_set_attribute_mask (info, matcher);
530
531 basename = g_winhttp_file_get_basename (file);
532 g_file_info_set_name (info, basename);
533 g_free (basename);
534
535 content_length = NULL;
536 if (_g_winhttp_query_header (winhttp_file->vfs,
537 request,
538 "HEAD request",
539 WINHTTP_QUERY_CONTENT_LENGTH,
540 &content_length,
541 NULL))
542 {
543 gint64 cl;
544 int n;
545
546 if (swscanf (content_length, L"%I64d%n", &cl, &n) == 1 &&
547 n == wcslen (content_length))
548 g_file_info_set_size (info, cl);
549
550 g_free (content_length);
551 }
552
553 if (matcher == NULL)
554 return info;
555
556 content_type = NULL;
557 if (_g_winhttp_query_header (winhttp_file->vfs,
558 request,
559 "HEAD request",
560 WINHTTP_QUERY_CONTENT_TYPE,
561 &content_type,
562 NULL))
563 {
564 char *ct = g_utf16_to_utf8 (content_type, -1, NULL, NULL, NULL);
565
566 if (ct != NULL)
567 {
568 char *p = strchr (ct, ';');
569
570 if (p != NULL)
571 {
572 char *tmp = g_strndup (ct, p - ct);
573
574 g_file_info_set_content_type (info, tmp);
575 g_free (tmp);
576 }
577 else
578 g_file_info_set_content_type (info, ct);
579 }
580
581 g_free (ct);
582 }
583
584 last_modified_len = sizeof (last_modified);
585 if (G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpQueryHeaders
586 (request,
587 WINHTTP_QUERY_LAST_MODIFIED | WINHTTP_QUERY_FLAG_SYSTEMTIME,
588 NULL,
589 &last_modified,
590 &last_modified_len,
591 NULL) &&
592 last_modified_len == sizeof (last_modified) &&
593 /* Don't bother comparing to the exact Y2038 moment */
594 last_modified.wYear >= 1970 &&
595 last_modified.wYear < 2038)
596 {
597 GTimeVal tv;
598
599 tv.tv_sec = mktime_utc (&last_modified);
600 tv.tv_usec = last_modified.wMilliseconds * 1000;
601
602 g_file_info_set_modification_time (info, &tv);
603 }
604
605 g_file_attribute_matcher_unref (matcher);
606
607 return info;
608 }
609
610 static GFileInputStream *
g_winhttp_file_read(GFile * file,GCancellable * cancellable,GError ** error)611 g_winhttp_file_read (GFile *file,
612 GCancellable *cancellable,
613 GError **error)
614 {
615 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
616 HINTERNET connection, request;
617 const wchar_t *accept_types[] =
618 {
619 L"*/*",
620 NULL,
621 };
622
623 connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
624 (G_WINHTTP_VFS (winhttp_file->vfs)->session,
625 winhttp_file->url.lpszHostName,
626 winhttp_file->url.nPort,
627 0);
628
629 if (connection == NULL)
630 {
631 _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
632
633 return NULL;
634 }
635
636 request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest
637 (connection,
638 L"GET",
639 winhttp_file->url.lpszUrlPath,
640 NULL,
641 WINHTTP_NO_REFERER,
642 accept_types,
643 winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
644
645 if (request == NULL)
646 {
647 _g_winhttp_set_error (error, GetLastError (), "GET request");
648
649 return NULL;
650 }
651
652 return _g_winhttp_file_input_stream_new (winhttp_file, connection, request);
653 }
654
655 static GFileOutputStream *
g_winhttp_file_create(GFile * file,GFileCreateFlags flags,GCancellable * cancellable,GError ** error)656 g_winhttp_file_create (GFile *file,
657 GFileCreateFlags flags,
658 GCancellable *cancellable,
659 GError **error)
660 {
661 GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
662 HINTERNET connection;
663
664 connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
665 (G_WINHTTP_VFS (winhttp_file->vfs)->session,
666 winhttp_file->url.lpszHostName,
667 winhttp_file->url.nPort,
668 0);
669
670 if (connection == NULL)
671 {
672 _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
673
674 return NULL;
675 }
676
677 return _g_winhttp_file_output_stream_new (winhttp_file, connection);
678 }
679
680 #if 0
681
682 static GFileOutputStream *
683 g_winhttp_file_replace (GFile *file,
684 const char *etag,
685 gboolean make_backup,
686 GFileCreateFlags flags,
687 GCancellable *cancellable,
688 GError **error)
689 {
690 /* FIXME: Implement */
691
692 return NULL;
693 }
694
695
696 static gboolean
697 g_winhttp_file_delete (GFile *file,
698 GCancellable *cancellable,
699 GError **error)
700 {
701 /* FIXME: Implement */
702
703 return FALSE;
704 }
705
706 static gboolean
707 g_winhttp_file_make_directory (GFile *file,
708 GCancellable *cancellable,
709 GError **error)
710 {
711 /* FIXME: Implement */
712
713 return FALSE;
714 }
715
716 static gboolean
717 g_winhttp_file_copy (GFile *source,
718 GFile *destination,
719 GFileCopyFlags flags,
720 GCancellable *cancellable,
721 GFileProgressCallback progress_callback,
722 gpointer progress_callback_data,
723 GError **error)
724 {
725 /* Fall back to default copy?? */
726 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
727 "Copy not supported");
728
729 return FALSE;
730 }
731
732 static gboolean
733 g_winhttp_file_move (GFile *source,
734 GFile *destination,
735 GFileCopyFlags flags,
736 GCancellable *cancellable,
737 GFileProgressCallback progress_callback,
738 gpointer progress_callback_data,
739 GError **error)
740 {
741 /* FIXME: Implement */
742
743 return FALSE;
744 }
745
746 #endif
747
748 static void
g_winhttp_file_file_iface_init(GFileIface * iface)749 g_winhttp_file_file_iface_init (GFileIface *iface)
750 {
751 iface->dup = g_winhttp_file_dup;
752 iface->hash = g_winhttp_file_hash;
753 iface->equal = g_winhttp_file_equal;
754 iface->is_native = g_winhttp_file_is_native;
755 iface->has_uri_scheme = g_winhttp_file_has_uri_scheme;
756 iface->get_uri_scheme = g_winhttp_file_get_uri_scheme;
757 iface->get_basename = g_winhttp_file_get_basename;
758 iface->get_path = g_winhttp_file_get_path;
759 iface->get_uri = g_winhttp_file_get_uri;
760 iface->get_parse_name = g_winhttp_file_get_parse_name;
761 iface->get_parent = g_winhttp_file_get_parent;
762 iface->prefix_matches = g_winhttp_file_prefix_matches;
763 iface->get_relative_path = g_winhttp_file_get_relative_path;
764 iface->resolve_relative_path = g_winhttp_file_resolve_relative_path;
765 iface->get_child_for_display_name = g_winhttp_file_get_child_for_display_name;
766 iface->set_display_name = g_winhttp_file_set_display_name;
767 iface->query_info = g_winhttp_file_query_info;
768 iface->read_fn = g_winhttp_file_read;
769 iface->create = g_winhttp_file_create;
770 #if 0
771 iface->replace = g_winhttp_file_replace;
772 iface->delete_file = g_winhttp_file_delete;
773 iface->make_directory = g_winhttp_file_make_directory;
774 iface->copy = g_winhttp_file_copy;
775 iface->move = g_winhttp_file_move;
776 #endif
777 }
778