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