Fixed a bug that caused APCs to be "forgotten".
[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 );
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 )
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
343     if (file->flags & FILE_FLAG_OVERLAPPED) return FD_TYPE_OVERLAPPED;
344
345     return FD_TYPE_DEFAULT;
346 }
347
348 static struct async_queue *file_queue_async(struct object *obj, struct async *async, int type, int count)
349 {
350     struct file *file = (struct file *)obj;
351     struct async_queue *q;
352
353     assert( obj->ops == &file_ops );
354
355     if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
356     {
357         set_error ( STATUS_INVALID_HANDLE );
358         return NULL;
359     }
360
361     switch(type)
362     {
363     case ASYNC_TYPE_READ:
364         q = &file->read_q;
365         break;
366     case ASYNC_TYPE_WRITE:
367         q = &file->write_q;
368         break;
369     default:
370         set_error( STATUS_INVALID_PARAMETER );
371         return NULL;
372     }
373
374     if(async && !async->q)
375         async_insert(q, async);
376
377     return q;
378 }
379
380 static void file_destroy( struct object *obj )
381 {
382     struct file *file = (struct file *)obj;
383     assert( obj->ops == &file_ops );
384
385     if (file->name)
386     {
387         /* remove it from the hashing list */
388         struct file **pptr = &file_hash[get_name_hash( file->name )];
389         while (*pptr && *pptr != file) pptr = &(*pptr)->next;
390         assert( *pptr );
391         *pptr = (*pptr)->next;
392         if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
393         free( file->name );
394     }
395     if (file->flags & FILE_FLAG_OVERLAPPED)
396     {
397         destroy_async_queue (&file->read_q);
398         destroy_async_queue (&file->write_q);
399     }
400 }
401
402 /* set the last error depending on errno */
403 void file_set_error(void)
404 {
405     switch (errno)
406     {
407     case EAGAIN:    set_error( STATUS_SHARING_VIOLATION ); break;
408     case EBADF:     set_error( STATUS_INVALID_HANDLE ); break;
409     case ENOSPC:    set_error( STATUS_DISK_FULL ); break;
410     case EACCES:
411     case ESRCH:
412     case EPERM:     set_error( STATUS_ACCESS_DENIED ); break;
413     case EROFS:     set_error( STATUS_MEDIA_WRITE_PROTECTED ); break;
414     case EBUSY:     set_error( STATUS_FILE_LOCK_CONFLICT ); break;
415     case ENOENT:    set_error( STATUS_NO_SUCH_FILE ); break;
416     case EISDIR:    set_error( 0xc0010000 | ERROR_CANNOT_MAKE /* FIXME */ ); break;
417     case ENFILE:
418     case EMFILE:    set_error( STATUS_NO_MORE_FILES ); break;
419     case EEXIST:    set_error( STATUS_OBJECT_NAME_COLLISION ); break;
420     case EINVAL:    set_error( STATUS_INVALID_PARAMETER ); break;
421     case ESPIPE:    set_error( 0xc0010000 | ERROR_SEEK /* FIXME */ ); break;
422     case ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
423     case EIO:       set_error( STATUS_ACCESS_VIOLATION ); break;
424     default:        perror("file_set_error"); set_error( ERROR_UNKNOWN /* FIXME */ ); break;
425     }
426 }
427
428 struct file *get_file_obj( struct process *process, handle_t handle, unsigned int access )
429 {
430     return (struct file *)get_handle_obj( process, handle, access, &file_ops );
431 }
432
433 static int set_file_pointer( handle_t handle, unsigned int *low, int *high, int whence )
434 {
435     struct file *file;
436     off_t result,xto;
437
438     xto = *low+((off_t)*high<<32);
439     if (!(file = get_file_obj( current->process, handle, 0 )))
440         return 0;
441     if ((result = lseek(file->obj.fd,xto,whence))==-1)
442     {
443         /* Check for seek before start of file */
444
445         /* also check EPERM due to SuSE7 2.2.16 lseek() EPERM kernel bug */
446         if (((errno == EINVAL) || (errno == EPERM))
447             && (whence != SEEK_SET) && (*high < 0))
448             set_error( 0xc0010000 | ERROR_NEGATIVE_SEEK /* FIXME */ );
449         else
450             file_set_error();
451         release_object( file );
452         return 0;
453     }
454     *low  = result & 0xffffffff;
455     *high = result >> 32;
456     release_object( file );
457     return 1;
458 }
459
460 static int truncate_file( handle_t handle )
461 {
462     struct file *file;
463     off_t result;
464
465     if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
466         return 0;
467     if (((result = lseek( file->obj.fd, 0, SEEK_CUR )) == -1) ||
468         (ftruncate( file->obj.fd, result ) == -1))
469     {
470         file_set_error();
471         release_object( file );
472         return 0;
473     }
474     release_object( file );
475     return 1;
476 }
477
478 /* try to grow the file to the specified size */
479 int grow_file( struct file *file, int size_high, int size_low )
480 {
481     struct stat st;
482     off_t size = size_low + (((off_t)size_high)<<32);
483
484     if (fstat( file->obj.fd, &st ) == -1)
485     {
486         file_set_error();
487         return 0;
488     }
489     if (st.st_size >= size) return 1;  /* already large enough */
490     if (ftruncate( file->obj.fd, size ) != -1) return 1;
491     file_set_error();
492     return 0;
493 }
494
495 static int set_file_time( handle_t handle, time_t access_time, time_t write_time )
496 {
497     struct file *file;
498     struct utimbuf utimbuf;
499
500     if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
501         return 0;
502     if (!file->name)
503     {
504         set_error( STATUS_INVALID_HANDLE );
505         release_object( file );
506         return 0;
507     }
508     if (!access_time || !write_time)
509     {
510         struct stat st;
511         if (stat( file->name, &st ) == -1) goto error;
512         if (!access_time) access_time = st.st_atime;
513         if (!write_time) write_time = st.st_mtime;
514     }
515     utimbuf.actime  = access_time;
516     utimbuf.modtime = write_time;
517     if (utime( file->name, &utimbuf ) == -1) goto error;
518     release_object( file );
519     return 1;
520  error:
521     file_set_error();
522     release_object( file );
523     return 0;
524 }
525
526 static int file_lock( struct file *file, int offset_high, int offset_low,
527                       int count_high, int count_low )
528 {
529     /* FIXME: implement this */
530     return 1;
531 }
532
533 static int file_unlock( struct file *file, int offset_high, int offset_low,
534                         int count_high, int count_low )
535 {
536     /* FIXME: implement this */
537     return 1;
538 }
539
540 /* create a file */
541 DECL_HANDLER(create_file)
542 {
543     struct file *file;
544
545     reply->handle = 0;
546     if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
547                              req->sharing, req->create, req->attrs, req->drive_type )))
548     {
549         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
550         release_object( file );
551     }
552 }
553
554 /* allocate a file handle for a Unix fd */
555 DECL_HANDLER(alloc_file_handle)
556 {
557     struct file *file;
558     int fd;
559
560     reply->handle = 0;
561     if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
562     {
563         set_error( STATUS_INVALID_HANDLE );
564         return;
565     }
566     if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
567                                     0, DRIVE_UNKNOWN )))
568     {
569         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
570         release_object( file );
571     }
572 }
573
574 /* get a Unix fd to access a file */
575 DECL_HANDLER(get_handle_fd)
576 {
577     struct object *obj;
578
579     reply->fd = -1;
580     reply->type = FD_TYPE_INVALID;
581     if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
582     {
583         int fd = get_handle_fd( current->process, req->handle, req->access );
584         if (fd != -1) reply->fd = fd;
585         else if (!get_error())
586         {
587             if ((fd = obj->ops->get_fd( obj )) != -1)
588                 send_client_fd( current->process, fd, req->handle );
589         }
590         reply->type = obj->ops->get_file_info( obj, NULL );
591         release_object( obj );
592     }
593 }
594
595 /* set a file current position */
596 DECL_HANDLER(set_file_pointer)
597 {
598     int high = req->high;
599     int low  = req->low;
600     set_file_pointer( req->handle, &low, &high, req->whence );
601     reply->new_low  = low;
602     reply->new_high = high;
603 }
604
605 /* truncate (or extend) a file */
606 DECL_HANDLER(truncate_file)
607 {
608     truncate_file( req->handle );
609 }
610
611 /* flush a file buffers */
612 DECL_HANDLER(flush_file)
613 {
614     struct object *obj;
615
616     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
617     {
618         obj->ops->flush( obj );
619         release_object( obj );
620     }
621 }
622
623 /* set a file access and modification times */
624 DECL_HANDLER(set_file_time)
625 {
626     set_file_time( req->handle, req->access_time, req->write_time );
627 }
628
629 /* get a file information */
630 DECL_HANDLER(get_file_info)
631 {
632     struct object *obj;
633
634     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
635     {
636         obj->ops->get_file_info( obj, reply );
637         release_object( obj );
638     }
639 }
640
641 /* lock a region of a file */
642 DECL_HANDLER(lock_file)
643 {
644     struct file *file;
645
646     if ((file = get_file_obj( current->process, req->handle, 0 )))
647     {
648         file_lock( file, req->offset_high, req->offset_low,
649                    req->count_high, req->count_low );
650         release_object( file );
651     }
652 }
653
654 /* unlock a region of a file */
655 DECL_HANDLER(unlock_file)
656 {
657     struct file *file;
658
659     if ((file = get_file_obj( current->process, req->handle, 0 )))
660     {
661         file_unlock( file, req->offset_high, req->offset_low,
662                      req->count_high, req->count_low );
663         release_object( file );
664     }
665 }