Implemented sandbox restarting on NTFS STATUS_LOG_FILE_FULL.
[captive.git] / src / libcaptive / client / file-parent.c
1 /* $Id$
2  * captive vfs 'file' interface to reactos of sandbox parent
3  * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "file-parent.h"        /* self */
23 #include <glib/gmessages.h>
24 #include "../sandbox/parent-File.h"
25 #include "vfs-parent.h"
26 #include "reactos/ntos/types.h" /* for ULONG */
27 #include "parent-connector.h"
28
29
30 static gpointer captive_file_parent_object_parent_class=NULL;
31
32
33 static GnomeVFSResult captive_file_parent_close(CaptiveFileObject *captive_file_object);
34 static GnomeVFSResult captive_file_parent_read(CaptiveFileObject *captive_file_object,
35                 gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return);
36 static GnomeVFSResult captive_file_parent_write(CaptiveFileObject *captive_file_object,
37                 gconstpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_written_return);
38 static GnomeVFSResult captive_file_parent_seek
39                 (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset);
40 static GnomeVFSResult captive_file_parent_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return);
41 static GnomeVFSResult captive_file_parent_remove(CaptiveFileObject *captive_file_object);
42 static GnomeVFSResult captive_file_parent_file_info_get
43                 (CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info);
44 static GnomeVFSResult captive_file_parent_file_info_set
45                 (CaptiveFileObject *captive_file_object,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask);
46 static GnomeVFSResult captive_file_parent_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size);
47 static GnomeVFSResult captive_file_parent_move
48                 (CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace);
49
50
51 static void captive_file_parent_object_dispose(CaptiveFileParentObject *captive_file_parent_object)
52 {
53         g_return_if_fail(captive_file_parent_object!=NULL);
54
55         captive_file_parent_close(CAPTIVE_FILE_OBJECT(captive_file_parent_object));     /* errors ignored */
56
57         if (captive_parent_connector_dispose(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))
58                 return;
59
60         G_OBJECT_CLASS(captive_file_parent_object_parent_class)->dispose((GObject *)captive_file_parent_object);
61 }
62
63 static void captive_file_parent_object_finalize(CaptiveFileParentObject *captive_file_parent_object)
64 {
65         g_return_if_fail(captive_file_parent_object!=NULL);
66
67         captive_parent_connector_finalize(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
68
69         g_free(captive_file_parent_object->pathname);
70         captive_file_parent_object->pathname=NULL;
71
72         G_OBJECT_CLASS(captive_file_parent_object_parent_class)->finalize((GObject *)captive_file_parent_object);
73 }
74
75 static void captive_file_parent_object_class_init(CaptiveFileParentObjectClass *class)
76 {
77 GObjectClass *gobject_class=G_OBJECT_CLASS(class);
78 CaptiveFileObjectClass *captive_file_object_class=CAPTIVE_FILE_OBJECT_CLASS(class);
79
80         captive_file_parent_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class)));
81         gobject_class->dispose=(void (*)(GObject *object))captive_file_parent_object_dispose;
82         gobject_class->finalize=(void (*)(GObject *object))captive_file_parent_object_finalize;
83
84         captive_file_object_class->read=captive_file_parent_read;
85         captive_file_object_class->write=captive_file_parent_write;
86         captive_file_object_class->seek=captive_file_parent_seek;
87         captive_file_object_class->tell=captive_file_parent_tell;
88         captive_file_object_class->remove=captive_file_parent_remove;
89         captive_file_object_class->file_info_get=captive_file_parent_file_info_get;
90         captive_file_object_class->file_info_set=captive_file_parent_file_info_set;
91         captive_file_object_class->truncate=captive_file_parent_truncate;
92         captive_file_object_class->move=captive_file_parent_move;
93 }
94
95
96 static GnomeVFSResult (*captive_file_parent_object_captive_parent_connector_open_orig)
97                 (CaptiveParentConnector *captive_parent_connector);
98 static GnomeVFSResult captive_file_parent_object_captive_parent_connector_open
99                 (CaptiveParentConnector *captive_parent_connector);
100
101 static GnomeVFSResult captive_file_parent_object_captive_parent_connector_close
102                 (CaptiveParentConnector *captive_parent_connector);
103 static GnomeVFSResult (*captive_file_parent_object_captive_parent_connector_close_orig)
104                 (CaptiveParentConnector *captive_parent_connector);
105
106 static G_CONST_RETURN gchar *captive_file_parent_object_captive_parent_connector_get_pathname
107                 (CaptiveParentConnector *captive_parent_connector);
108
109 static void captive_file_parent_object_captive_parent_connector_init(CaptiveParentConnectorIface *captive_parent_connector_iface)
110 {
111         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR_CLASS(captive_parent_connector_iface));
112
113         captive_file_parent_object_captive_parent_connector_open_orig=captive_parent_connector_iface->open;
114         captive_parent_connector_iface->open=captive_file_parent_object_captive_parent_connector_open;
115
116         captive_file_parent_object_captive_parent_connector_close_orig=captive_parent_connector_iface->close;
117         captive_parent_connector_iface->close=captive_file_parent_object_captive_parent_connector_close;
118
119         captive_parent_connector_iface->get_pathname=captive_file_parent_object_captive_parent_connector_get_pathname;
120 }
121
122
123 static void captive_file_parent_object_init(CaptiveFileParentObject *captive_file_parent_object)
124 {
125         g_return_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_parent_object));
126 }
127
128
129 GType captive_file_parent_object_get_type(void)
130 {
131 static GType captive_file_parent_object_type=0;
132
133         if (!captive_file_parent_object_type) {
134 static const GTypeInfo captive_file_parent_object_info={
135                                 sizeof(CaptiveFileParentObjectClass),
136                                 NULL,   /* base_init */
137                                 NULL,   /* base_finalize */
138                                 (GClassInitFunc)captive_file_parent_object_class_init,
139                                 NULL,   /* class_finalize */
140                                 NULL,   /* class_data */
141                                 sizeof(CaptiveFileParentObject),
142                                 5,      /* n_preallocs */
143                                 (GInstanceInitFunc)captive_file_parent_object_init,
144                                 };
145 static const GInterfaceInfo captive_parent_connector_info={
146                                 (GInterfaceInitFunc)captive_file_parent_object_captive_parent_connector_init,   /* interface_init */
147                                 NULL,   /* interface_finalize */
148                                 NULL,   /* interface_data */
149                                 };
150
151                 captive_file_parent_object_type=g_type_register_static(CAPTIVE_FILE_TYPE_OBJECT,
152                                 "CaptiveFileParentObject",&captive_file_parent_object_info,0);
153                 g_type_add_interface_static(captive_file_parent_object_type,
154                                 CAPTIVE_TYPE_PARENT_CONNECTOR,&captive_parent_connector_info);
155                 }
156
157         return captive_file_parent_object_type;
158 }
159
160
161 static void captive_file_parent_init
162                 (CaptiveFileParentObject *captive_file_parent_object,CaptiveVfsObject *captive_vfs_object)
163 {
164         g_return_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_parent_object));
165         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object));
166
167         /* Order of captive_file_init() and captive_parent_connector_init()
168          * should not matter as 'vfs' is passed by value to captive_parent_connector_init().
169          */
170         captive_file_init(CAPTIVE_FILE_OBJECT(captive_file_parent_object),captive_vfs_object);
171
172         captive_parent_connector_init(
173                         CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object),   /* captive_parent_connector */
174                         &captive_file_parent_object->corba_File_object, /* corba_objectp */
175                         CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_FILE_OBJECT(captive_file_parent_object)->vfs));       /* captive_vfs_parent_object */
176 }
177
178 GnomeVFSResult captive_file_parent_new_open(CaptiveFileObject **captive_file_object_return,
179                 CaptiveVfsObject *captive_vfs_object,const gchar *pathname,GnomeVFSOpenMode mode)
180 {
181 CaptiveFileParentObject *captive_file_parent_object;
182 GnomeVFSResult r;
183
184         g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
185         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
186         g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
187
188         captive_file_parent_object=g_object_new(
189                         CAPTIVE_FILE_PARENT_TYPE_OBJECT,        /* object_type */
190                         NULL);  /* first_property_name; FIXME: support properties */
191         captive_file_parent_object->pathname=g_strdup(pathname);
192         captive_file_parent_object->mode=mode;
193
194         captive_file_parent_init(captive_file_parent_object,captive_vfs_object);
195
196         if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
197                 return r;
198
199         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_new_open(captive_file_parent_object))) {
200                 g_object_unref(captive_file_parent_object);
201                 *captive_file_object_return=NULL;
202                 return r;
203                 }
204
205         *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object);
206         return (*captive_file_parent_object_captive_parent_connector_open_orig)
207                         (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
208 }
209
210
211 GnomeVFSResult captive_file_parent_new_create(CaptiveFileObject **captive_file_object_return,
212                 CaptiveVfsObject *captive_vfs_object,const gchar *pathname,GnomeVFSOpenMode mode,gboolean exclusive,guint perm)
213 {
214 CaptiveFileParentObject *captive_file_parent_object;
215 GnomeVFSResult r;
216
217         g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
218         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
219         g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
220
221         captive_file_parent_object=g_object_new(
222                         CAPTIVE_FILE_PARENT_TYPE_OBJECT,        /* object_type */
223                         NULL);  /* first_property_name; FIXME: support properties */
224         captive_file_parent_object->pathname=g_strdup(pathname);
225         captive_file_parent_object->mode=mode;
226
227         captive_file_parent_init(captive_file_parent_object,captive_vfs_object);
228
229         if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
230                 return r;
231
232         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_new_create(captive_file_parent_object,exclusive,perm))) {
233                 g_object_unref(captive_file_parent_object);
234                 *captive_file_object_return=NULL;
235                 return r;
236                 }
237         captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
238
239         *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object);
240         return (*captive_file_parent_object_captive_parent_connector_open_orig)
241                         (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
242 }
243
244
245 static GnomeVFSResult captive_file_parent_close(CaptiveFileObject *captive_file_object)
246 {
247 CaptiveFileParentObject *captive_file_parent_object;
248 GnomeVFSResult r;
249 gint retried=0;
250
251         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
252
253         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
254
255         do {
256                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
257                         break;
258                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
259                                 !=(r=captive_parent_connector_close(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
260                         break;
261                 } while (!retried++);
262         return r;
263 }
264
265
266 static GnomeVFSResult captive_file_parent_object_captive_parent_connector_open
267                 (CaptiveParentConnector *captive_parent_connector)
268 {
269 GnomeVFSResult r;
270
271         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
272         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
273
274         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_new_open(CAPTIVE_FILE_PARENT_OBJECT(captive_parent_connector))))
275                 return r;
276
277         return (*captive_file_parent_object_captive_parent_connector_open_orig)(captive_parent_connector);
278 }
279
280
281 static GnomeVFSResult captive_file_parent_object_captive_parent_connector_close
282                 (CaptiveParentConnector *captive_parent_connector)
283 {
284 GnomeVFSResult r;
285
286         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
287         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
288
289         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_close(CAPTIVE_FILE_PARENT_OBJECT(captive_parent_connector))))
290                 return r;
291
292         return (*captive_file_parent_object_captive_parent_connector_close_orig)(captive_parent_connector);
293 }
294
295
296 static G_CONST_RETURN gchar *captive_file_parent_object_captive_parent_connector_get_pathname
297                 (CaptiveParentConnector *captive_parent_connector)
298 {
299 CaptiveFileParentObject *captive_file_parent_object;
300
301         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),NULL);
302         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_parent_connector),NULL);
303
304         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_parent_connector);
305
306         g_return_val_if_fail(captive_file_parent_object->pathname!=NULL,NULL);
307
308         return captive_file_parent_object->pathname;
309 }
310
311
312 static GnomeVFSResult captive_file_parent_read(CaptiveFileObject *captive_file_object,
313                 gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return)
314 {
315 CaptiveFileParentObject *captive_file_parent_object;
316 GnomeVFSResult r;
317 gint retried=0;
318
319         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
320         g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
321         g_return_val_if_fail(bytes_read_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
322         g_return_val_if_fail(num_bytes==(ULONG)num_bytes,GNOME_VFS_ERROR_BAD_PARAMETERS);
323
324         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
325
326         do {
327                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
328                         return r;
329                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
330                                 !=(r=captive_sandbox_parent_file_read(captive_file_parent_object,buffer,num_bytes,bytes_read_return)))
331                         return r;
332                 } while (!retried++);
333         return r;
334 }
335
336
337 static GnomeVFSResult captive_file_parent_write(CaptiveFileObject *captive_file_object,
338                 gconstpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_written_return)
339 {
340 CaptiveFileParentObject *captive_file_parent_object;
341 GnomeVFSResult r;
342 gint retried=0;
343 gint retried_commit=0;
344
345         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
346         g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
347         g_return_val_if_fail(bytes_written_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
348         g_return_val_if_fail(num_bytes==(ULONG)num_bytes,GNOME_VFS_ERROR_BAD_PARAMETERS);
349
350         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
351
352         do {
353                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
354                         return r;
355                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
356                                 !=(r=captive_sandbox_parent_file_write(captive_file_parent_object,buffer,num_bytes,bytes_written_return))) {
357                         /* Occured: ExRaiseStatus(STATUS_LOG_FILE_FULL); */
358                         if (GNOME_VFS_ERROR_LAUNCH==r) {
359                                 if (!retried_commit++) {
360 puts("committing...");
361                                         if (GNOME_VFS_OK!=(r=captive_vfs_commit(captive_file_object->vfs)))
362                                                 return r;
363 puts("committed");
364                                         retried=0;
365                                         continue;
366                                         }
367                                 }
368                         g_assert(*bytes_written_return==num_bytes);     /* Not GNOME_VFS_ERROR_LAUNCH. */
369                         if (GNOME_VFS_OK==r)
370                                 captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
371                         return r;
372                         }
373                 } while (!retried++);
374         return r;
375 }
376
377
378 static GnomeVFSResult captive_file_parent_seek
379                 (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset)
380 {
381 CaptiveFileParentObject *captive_file_parent_object;
382 GnomeVFSResult r;
383 gint retried=0;
384
385         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
386
387         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
388
389         do {
390                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
391                         return r;
392                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
393                                 !=(r=captive_sandbox_parent_file_seek(captive_file_parent_object,whence,offset)))
394                         return r;
395                 } while (!retried++);
396         return r;
397 }
398
399
400 static GnomeVFSResult captive_file_parent_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return)
401 {
402 CaptiveFileParentObject *captive_file_parent_object;
403 GnomeVFSResult r;
404 gint retried=0;
405
406         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
407         g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
408
409         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
410
411         do {
412                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
413                         return r;
414                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
415                                 !=(r=captive_sandbox_parent_file_tell(captive_file_parent_object,offset_return)))
416                         return r;
417                 } while (!retried++);
418         return r;
419 }
420
421
422 static GnomeVFSResult captive_file_parent_remove(CaptiveFileObject *captive_file_object)
423 {
424 CaptiveFileParentObject *captive_file_parent_object;
425 GnomeVFSResult r;
426 gint retried=0;
427
428         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
429
430         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
431
432         do {
433                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
434                         return r;
435                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
436                                 !=(r=captive_sandbox_parent_file_remove(captive_file_parent_object))) {
437                         if (GNOME_VFS_OK==r)
438                                 captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
439                         return r;
440                         }
441                 } while (!retried++);
442         return r;
443 }
444
445
446 static GnomeVFSResult captive_file_parent_file_info_get
447                 (CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info)
448 {
449 CaptiveFileParentObject *captive_file_parent_object;
450 GnomeVFSResult r;
451 gint retried=0;
452
453         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
454         g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
455
456         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
457
458         do {
459                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
460                         return r;
461                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
462                                 !=(r=captive_sandbox_parent_file_file_info_get(captive_file_parent_object,file_info)))
463                         return r;
464                 } while (!retried++);
465         return r;
466 }
467
468
469 static GnomeVFSResult captive_file_parent_file_info_set
470                 (CaptiveFileObject *captive_file_object,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask)
471 {
472 CaptiveFileParentObject *captive_file_parent_object;
473 GnomeVFSResult r;
474 gint retried=0;
475
476         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
477         g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
478
479         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
480
481         do {
482                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
483                         return r;
484                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
485                                 !=(r=captive_sandbox_parent_file_file_info_set(captive_file_parent_object,info,mask))) {
486                         if (GNOME_VFS_OK==r)
487                                 captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
488                         return r;
489                         }
490                 } while (!retried++);
491         return r;
492 }
493
494
495 static GnomeVFSResult captive_file_parent_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size)
496 {
497 CaptiveFileParentObject *captive_file_parent_object;
498 GnomeVFSResult r;
499 gint retried=0;
500
501         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
502
503         captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object);
504
505         do {
506                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object))))
507                         return r;
508                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
509                                 !=(r=captive_sandbox_parent_file_truncate(captive_file_parent_object,file_size))) {
510                         if (GNOME_VFS_OK==r)
511                                 captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object));
512                         return r;
513                         }
514                 } while (!retried++);
515         return r;
516 }
517
518
519 static GnomeVFSResult captive_file_parent_move
520                 (CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace)
521 {
522 CaptiveFileParentObject *captive_file_parent_object_old;
523 GnomeVFSResult r;
524 gint retried=0;
525
526         g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object_old),GNOME_VFS_ERROR_BAD_PARAMETERS);
527         g_return_val_if_fail(pathname_new!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
528
529         captive_file_parent_object_old=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object_old);
530
531         do {
532                 if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object_old))))
533                         return r;
534                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
535                                 !=(r=captive_sandbox_parent_file_move(captive_file_parent_object_old,pathname_new,force_replace))) {
536                         if (GNOME_VFS_OK==r)
537                                 captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object_old));
538                         return r;
539                         }
540                 } while (!retried++);
541         return r;
542 }