Reimplemented DebugBreakProcess.
[wine] / server / file.c
1 /*
2  * Server-side file management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include "config.h"
8 #include "wine/port.h"
9
10 #include <assert.h>
11 #include <fcntl.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 #ifdef HAVE_SYS_ERRNO_H
17 #include <sys/errno.h>
18 #endif
19 #include <sys/stat.h>
20 #include <sys/time.h>
21 #include <sys/types.h>
22 #include <time.h>
23 #include <unistd.h>
24 #include <utime.h>
25
26 #include "winerror.h"
27 #include "winbase.h"
28
29 #include "handle.h"
30 #include "thread.h"
31 #include "request.h"
32 #include "async.h"
33
34 struct file
35 {
36     struct object       obj;        /* object header */
37     struct file        *next;       /* next file in hashing list */
38     char               *name;       /* file name */
39     unsigned int        access;     /* file access (GENERIC_READ/WRITE) */
40     unsigned int        flags;      /* flags (FILE_FLAG_*) */
41     unsigned int        sharing;    /* file sharing mode */
42     int                 drive_type; /* type of drive the file is on */
43     struct async_queue  read_q;
44     struct async_queue  write_q;
45 };
46
47 #define NAME_HASH_SIZE 37
48
49 static struct file *file_hash[NAME_HASH_SIZE];
50
51 static void file_dump( struct object *obj, int verbose );
52 static int file_get_poll_events( struct object *obj );
53 static void file_poll_event( struct object *obj, int event );
54 static int file_get_fd( struct object *obj );
55 static int file_flush( struct object *obj );
56 static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
57 static void file_destroy( struct object *obj );
58 static struct async_queue * file_queue_async(struct object *obj, struct async* async, int type, int count);
59
60 static const struct object_ops file_ops =
61 {
62     sizeof(struct file),          /* size */
63     file_dump,                    /* dump */
64     default_poll_add_queue,       /* add_queue */
65     default_poll_remove_queue,    /* remove_queue */
66     default_poll_signaled,        /* signaled */
67     no_satisfied,                 /* satisfied */
68     file_get_poll_events,         /* get_poll_events */
69     file_poll_event,              /* poll_event */
70     file_get_fd,                  /* get_fd */
71     file_flush,                   /* flush */
72     file_get_info,                /* get_file_info */
73     file_queue_async,             /* queue_async */
74     file_destroy                  /* destroy */
75 };
76
77
78 static int get_name_hash( const char *name )
79 {
80     int hash = 0;
81     while (*name) hash ^= (unsigned char)*name++;
82     return hash % NAME_HASH_SIZE;
83 }
84
85 /* check if the desired access is possible without violating */
86 /* the sharing mode of other opens of the same file */
87 static int check_sharing( const char *name, int hash, unsigned int access,
88                           unsigned int sharing )
89 {
90     struct file *file;
91     unsigned int existing_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
92     unsigned int existing_access = 0;
93
94     for (file = file_hash[hash]; file; file = file->next)
95     {
96         if (strcmp( file->name, name )) continue;
97         existing_sharing &= file->sharing;
98         existing_access |= file->access;
99     }
100     if ((access & GENERIC_READ) && !(existing_sharing & FILE_SHARE_READ)) goto error;
101     if ((access & GENERIC_WRITE) && !(existing_sharing & FILE_SHARE_WRITE)) goto error;
102     if ((existing_access & GENERIC_READ) && !(sharing & FILE_SHARE_READ)) goto error;
103     if ((existing_access & GENERIC_WRITE) && !(sharing & FILE_SHARE_WRITE)) goto error;
104     return 1;
105  error:
106     set_error( STATUS_SHARING_VIOLATION );
107     return 0;
108 }
109
110 /* create a file from a file descriptor */
111 /* if the function fails the fd is closed */
112 static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing,
113                                         unsigned int attrs, int drive_type )
114 {
115     struct file *file;
116     if ((file = alloc_object( &file_ops, fd )))
117     {
118         file->name       = NULL;
119         file->next       = NULL;
120         file->access     = access;
121         file->flags      = attrs;
122         file->sharing    = sharing;
123         file->drive_type = drive_type;
124         if (file->flags & FILE_FLAG_OVERLAPPED)
125         {
126             init_async_queue (&file->read_q);
127             init_async_queue (&file->write_q);
128         }
129     }
130     return file;
131 }
132
133
134 static struct file *create_file( const char *nameptr, size_t len, unsigned int access,
135                                  unsigned int sharing, int create, unsigned int attrs,
136                                  int drive_type )
137 {
138     struct file *file;
139     int hash, flags;
140     struct stat st;
141     char *name;
142     int fd = -1;
143     mode_t mode;
144
145     if (!(name = mem_alloc( len + 1 ))) return NULL;
146     memcpy( name, nameptr, len );
147     name[len] = 0;
148
149     /* check sharing mode */
150     hash = get_name_hash( name );
151     if (!check_sharing( name, hash, access, sharing )) goto error;
152
153     switch(create)
154     {
155     case CREATE_NEW:        flags = O_CREAT | O_EXCL; break;
156     case CREATE_ALWAYS:     flags = O_CREAT | O_TRUNC; break;
157     case OPEN_ALWAYS:       flags = O_CREAT; break;
158     case TRUNCATE_EXISTING: flags = O_TRUNC; break;
159     case OPEN_EXISTING:     flags = 0; break;
160     default:                set_error( STATUS_INVALID_PARAMETER ); goto error;
161     }
162     switch(access & (GENERIC_READ | GENERIC_WRITE))
163     {
164     case 0: break;
165     case GENERIC_READ:  flags |= O_RDONLY; break;
166     case GENERIC_WRITE: flags |= O_WRONLY; break;
167     case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
168     }
169     mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666;
170
171     if (len >= 4 &&
172         (!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" )))
173         mode |= 0111;
174
175     /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
176     if ((fd = open( name, flags | O_NONBLOCK | O_LARGEFILE, mode )) == -1 )
177         goto file_error;
178     /* refuse to open a directory */
179     if (fstat( fd, &st ) == -1) goto file_error;
180     if (S_ISDIR(st.st_mode))
181     {
182         set_error( STATUS_ACCESS_DENIED );
183         goto error;
184     }
185
186     if (!(file = create_file_for_fd( fd, access, sharing, attrs, drive_type )))
187     {
188         free( name );
189         return NULL;
190     }
191     file->name = name;
192     file->next = file_hash[hash];
193     file_hash[hash] = file;
194     return file;
195
196  file_error:
197     file_set_error();
198  error:
199     if (fd != -1) close( fd );
200     free( name );
201     return NULL;
202 }
203
204 /* check if two file objects point to the same file */
205 int is_same_file( struct file *file1, struct file *file2 )
206 {
207     return !strcmp( file1->name, file2->name );
208 }
209
210 /* get the type of drive the file is on */
211 int get_file_drive_type( struct file *file )
212 {
213     return file->drive_type;
214 }
215
216 /* Create an anonymous Unix file */
217 int create_anonymous_file(void)
218 {
219     char *name;
220     int fd;
221
222     do
223     {
224         if (!(name = tmpnam(NULL)))
225         {
226             set_error( STATUS_TOO_MANY_OPENED_FILES );
227             return -1;
228         }
229         fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 );
230     } while ((fd == -1) && (errno == EEXIST));
231     if (fd == -1)
232     {
233         file_set_error();
234         return -1;
235     }
236     unlink( name );
237     return fd;
238 }
239
240 /* Create a temp file for anonymous mappings */
241 struct file *create_temp_file( int access )
242 {
243     int fd;
244
245     if ((fd = create_anonymous_file()) == -1) return NULL;
246     return create_file_for_fd( fd, access, 0, 0, DRIVE_FIXED );
247 }
248
249 static void file_dump( struct object *obj, int verbose )
250 {
251     struct file *file = (struct file *)obj;
252     assert( obj->ops == &file_ops );
253     fprintf( stderr, "File fd=%d flags=%08x name='%s'\n", file->obj.fd, file->flags, file->name );
254 }
255
256 static int file_get_poll_events( struct object *obj )
257 {
258     struct file *file = (struct file *)obj;
259     int events = 0;
260     assert( obj->ops == &file_ops );
261     if (file->access & GENERIC_READ) events |= POLLIN;
262     if (file->access & GENERIC_WRITE) events |= POLLOUT;
263     return events;
264 }
265
266 static void file_poll_event( struct object *obj, int event )
267 {
268     struct file *file = (struct file *)obj;
269     assert( obj->ops == &file_ops );
270     if ( file->flags & FILE_FLAG_OVERLAPPED )
271     {
272         if( IS_READY(file->read_q) && (POLLIN & event) )
273         {
274             async_notify(file->read_q.head, STATUS_ALERTED);
275             return;
276         }
277         if( IS_READY(file->write_q) && (POLLOUT & event) )
278         {
279             async_notify(file->write_q.head, STATUS_ALERTED);
280             return;
281         }
282     }
283     default_poll_event( obj, event );
284 }
285
286
287 static int file_get_fd( struct object *obj )
288 {
289     struct file *file = (struct file *)obj;
290     assert( obj->ops == &file_ops );
291     return file->obj.fd;
292 }
293
294 static int file_flush( struct object *obj )
295 {
296     int ret;
297     struct file *file = (struct file *)grab_object(obj);
298     assert( obj->ops == &file_ops );
299
300     ret = (fsync( file->obj.fd ) != -1);
301     if (!ret) file_set_error();
302     release_object( file );
303     return ret;
304 }
305
306 static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
307 {
308     struct stat st;
309     struct file *file = (struct file *)obj;
310     assert( obj->ops == &file_ops );
311
312     if (reply)
313     {
314         if (fstat( file->obj.fd, &st ) == -1)
315         {
316             file_set_error();
317             return FD_TYPE_INVALID;
318         }
319         if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
320             S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR;
321         else reply->type = FILE_TYPE_DISK;
322         if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
323         else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
324         if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
325         reply->access_time = st.st_atime;
326         reply->write_time  = st.st_mtime;
327         if (S_ISDIR(st.st_mode))
328         {
329             reply->size_high = 0;
330             reply->size_low  = 0;
331         }
332         else
333         {
334             reply->size_high = st.st_size >> 32;
335             reply->size_low  = st.st_size & 0xffffffff;
336         }
337         reply->links       = st.st_nlink;
338         reply->index_high  = st.st_dev;
339         reply->index_low   = st.st_ino;
340         reply->serial      = 0; /* FIXME */
341     }
342     *flags = 0;
343     if (file->flags & FILE_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED;
344     return FD_TYPE_DEFAULT;
345 }
346
347 static struct async_queue *file_queue_async(struct object *obj, struct async *async, int type, int count)
348 {
349     struct file *file = (struct file *)obj;
350     struct async_queue *q;
351
352     assert( obj->ops == &file_ops );
353
354     if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
355     {
356         set_error ( STATUS_INVALID_HANDLE );
357         return NULL;
358     }
359
360     switch(type)
361     {
362     case ASYNC_TYPE_READ:
363         q = &file->read_q;
364         break;
365     case ASYNC_TYPE_WRITE:
366         q = &file->write_q;
367         break;
368     default:
369         set_error( STATUS_INVALID_PARAMETER );
370         return NULL;
371     }
372
373     if(async && !async->q)
374         async_insert(q, async);
375
376     return q;
377 }
378
379 static void file_destroy( struct object *obj )
380 {
381     struct file *file = (struct file *)obj;
382     assert( obj->ops == &file_ops );
383
384     if (file->name)
385     {
386         /* remove it from the hashing list */
387         struct file **pptr = &file_hash[get_name_hash( file->name )];
388         while (*pptr && *pptr != file) pptr = &(*pptr)->next;
389         assert( *pptr );
390         *pptr = (*pptr)->next;
391         if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
392         free( file->name );
393     }
394     if (file->flags & FILE_FLAG_OVERLAPPED)
395     {
396         destroy_async_queue (&file->read_q);
397         destroy_async_queue (&file->write_q);
398     }
399 }
400
401 /* set the last error depending on errno */
402 void file_set_error(void)
403 {
404     switch (errno)
405     {
406     case EAGAIN:    set_error( STATUS_SHARING_VIOLATION ); break;
407     case EBADF:     set_error( STATUS_INVALID_HANDLE ); break;
408     case ENOSPC:    set_error( STATUS_DISK_FULL ); break;
409     case EACCES:
410     case ESRCH:
411     case EPERM:     set_error( STATUS_ACCESS_DENIED ); break;
412     case EROFS:     set_error( STATUS_MEDIA_WRITE_PROTECTED ); break;
413     case EBUSY:     set_error( STATUS_FILE_LOCK_CONFLICT ); break;
414     case ENOENT:    set_error( STATUS_NO_SUCH_FILE ); break;
415     case EISDIR:    set_error( 0xc0010000 | ERROR_CANNOT_MAKE /* FIXME */ ); break;
416     case ENFILE:
417     case EMFILE:    set_error( STATUS_NO_MORE_FILES ); break;
418     case EEXIST:    set_error( STATUS_OBJECT_NAME_COLLISION ); break;
419     case EINVAL:    set_error( STATUS_INVALID_PARAMETER ); break;
420     case ESPIPE:    set_error( 0xc0010000 | ERROR_SEEK /* FIXME */ ); break;
421     case ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
422     case EIO:       set_error( STATUS_ACCESS_VIOLATION ); break;
423     default:        perror("file_set_error"); set_error( ERROR_UNKNOWN /* FIXME */ ); break;
424     }
425 }
426
427 struct file *get_file_obj( struct process *process, handle_t handle, unsigned int access )
428 {
429     return (struct file *)get_handle_obj( process, handle, access, &file_ops );
430 }
431
432 static int set_file_pointer( handle_t handle, unsigned int *low, int *high, int whence )
433 {
434     struct file *file;
435     off_t result,xto;
436
437     xto = *low+((off_t)*high<<32);
438     if (!(file = get_file_obj( current->process, handle, 0 )))
439         return 0;
440     if ((result = lseek(file->obj.fd,xto,whence))==-1)
441     {
442         /* Check for seek before start of file */
443
444         /* also check EPERM due to SuSE7 2.2.16 lseek() EPERM kernel bug */
445         if (((errno == EINVAL) || (errno == EPERM))
446             && (whence != SEEK_SET) && (*high < 0))
447             set_error( 0xc0010000 | ERROR_NEGATIVE_SEEK /* FIXME */ );
448         else
449             file_set_error();
450         release_object( file );
451         return 0;
452     }
453     *low  = result & 0xffffffff;
454     *high = result >> 32;
455     release_object( file );
456     return 1;
457 }
458
459 /* extend a file beyond the current end of file */
460 static int extend_file( struct file *file, off_t size )
461 {
462     static const char zero;
463
464     /* extend the file one byte beyond the requested size and then truncate it */
465     /* this should work around ftruncate implementations that can't extend files */
466     if ((lseek( file->obj.fd, size, SEEK_SET ) != -1) &&
467         (write( file->obj.fd, &zero, 1 ) != -1))
468     {
469         ftruncate( file->obj.fd, size );
470         return 1;
471     }
472     file_set_error();
473     return 0;
474 }
475
476 /* truncate file at current position */
477 static int truncate_file( struct file *file )
478 {
479     int ret = 0;
480     off_t pos = lseek( file->obj.fd, 0, SEEK_CUR );
481     off_t eof = lseek( file->obj.fd, 0, SEEK_END );
482
483     if (eof < pos) ret = extend_file( file, pos );
484     else
485     {
486         if (ftruncate( file->obj.fd, pos ) != -1) ret = 1;
487         else file_set_error();
488     }
489     lseek( file->obj.fd, pos, SEEK_SET );  /* restore file pos */
490     return ret;
491 }
492
493 /* try to grow the file to the specified size */
494 int grow_file( struct file *file, int size_high, int size_low )
495 {
496     int ret = 0;
497     struct stat st;
498     off_t old_pos, size = size_low + (((off_t)size_high)<<32);
499
500     if (fstat( file->obj.fd, &st ) == -1)
501     {
502         file_set_error();
503         return 0;
504     }
505     if (st.st_size >= size) return 1;  /* already large enough */
506     old_pos = lseek( file->obj.fd, 0, SEEK_CUR );  /* save old pos */
507     ret = extend_file( file, size );
508     lseek( file->obj.fd, old_pos, SEEK_SET );  /* restore file pos */
509     return ret;
510 }
511
512 static int set_file_time( handle_t handle, time_t access_time, time_t write_time )
513 {
514     struct file *file;
515     struct utimbuf utimbuf;
516
517     if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
518         return 0;
519     if (!file->name)
520     {
521         set_error( STATUS_INVALID_HANDLE );
522         release_object( file );
523         return 0;
524     }
525     if (!access_time || !write_time)
526     {
527         struct stat st;
528         if (stat( file->name, &st ) == -1) goto error;
529         if (!access_time) access_time = st.st_atime;
530         if (!write_time) write_time = st.st_mtime;
531     }
532     utimbuf.actime  = access_time;
533     utimbuf.modtime = write_time;
534     if (utime( file->name, &utimbuf ) == -1) goto error;
535     release_object( file );
536     return 1;
537  error:
538     file_set_error();
539     release_object( file );
540     return 0;
541 }
542
543 static int file_lock( struct file *file, int offset_high, int offset_low,
544                       int count_high, int count_low )
545 {
546     /* FIXME: implement this */
547     return 1;
548 }
549
550 static int file_unlock( struct file *file, int offset_high, int offset_low,
551                         int count_high, int count_low )
552 {
553     /* FIXME: implement this */
554     return 1;
555 }
556
557 /* create a file */
558 DECL_HANDLER(create_file)
559 {
560     struct file *file;
561
562     reply->handle = 0;
563     if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
564                              req->sharing, req->create, req->attrs, req->drive_type )))
565     {
566         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
567         release_object( file );
568     }
569 }
570
571 /* allocate a file handle for a Unix fd */
572 DECL_HANDLER(alloc_file_handle)
573 {
574     struct file *file;
575     int fd;
576
577     reply->handle = 0;
578     if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
579     {
580         set_error( STATUS_INVALID_HANDLE );
581         return;
582     }
583     if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
584                                     0, DRIVE_UNKNOWN )))
585     {
586         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
587         release_object( file );
588     }
589 }
590
591 /* get a Unix fd to access a file */
592 DECL_HANDLER(get_handle_fd)
593 {
594     struct object *obj;
595
596     reply->fd = -1;
597     reply->type = FD_TYPE_INVALID;
598     if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
599     {
600         int fd = get_handle_fd( current->process, req->handle, req->access );
601         if (fd != -1) reply->fd = fd;
602         else if (!get_error())
603         {
604             if ((fd = obj->ops->get_fd( obj )) != -1)
605                 send_client_fd( current->process, fd, req->handle );
606         }
607         reply->type = obj->ops->get_file_info( obj, NULL, &reply->flags );
608         release_object( obj );
609     }
610 }
611
612 /* set a file current position */
613 DECL_HANDLER(set_file_pointer)
614 {
615     int high = req->high;
616     int low  = req->low;
617     set_file_pointer( req->handle, &low, &high, req->whence );
618     reply->new_low  = low;
619     reply->new_high = high;
620 }
621
622 /* truncate (or extend) a file */
623 DECL_HANDLER(truncate_file)
624 {
625     struct file *file;
626
627     if ((file = get_file_obj( current->process, req->handle, GENERIC_WRITE )))
628     {
629         truncate_file( file );
630         release_object( file );
631     }
632 }
633
634 /* flush a file buffers */
635 DECL_HANDLER(flush_file)
636 {
637     struct object *obj;
638
639     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
640     {
641         obj->ops->flush( obj );
642         release_object( obj );
643     }
644 }
645
646 /* set a file access and modification times */
647 DECL_HANDLER(set_file_time)
648 {
649     set_file_time( req->handle, req->access_time, req->write_time );
650 }
651
652 /* get a file information */
653 DECL_HANDLER(get_file_info)
654 {
655     struct object *obj;
656
657     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
658     {
659         int flags;
660         obj->ops->get_file_info( obj, reply, &flags );
661         release_object( obj );
662     }
663 }
664
665 /* lock a region of a file */
666 DECL_HANDLER(lock_file)
667 {
668     struct file *file;
669
670     if ((file = get_file_obj( current->process, req->handle, 0 )))
671     {
672         file_lock( file, req->offset_high, req->offset_low,
673                    req->count_high, req->count_low );
674         release_object( file );
675     }
676 }
677
678 /* unlock a region of a file */
679 DECL_HANDLER(unlock_file)
680 {
681     struct file *file;
682
683     if ((file = get_file_obj( current->process, req->handle, 0 )))
684     {
685         file_unlock( file, req->offset_high, req->offset_low,
686                      req->count_high, req->count_low );
687         release_object( file );
688     }
689 }