Document BSTR functions, add SetOANoCache().
[wine] / server / smb.c
1 /*
2  * Server-side smb network file management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  * Copyright (C) 2000, 2001, 2002 Mike McCormack
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * FIXME: if you can't find something to fix,
22  *          you're not looking hard enough
23  */
24
25 #include "config.h"
26
27 #include <assert.h>
28 #include <fcntl.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <time.h>
36 #include <unistd.h>
37 #ifdef HAVE_UTIME_H
38 #include <utime.h>
39 #endif
40 #ifdef HAVE_TERMIOS_H
41 #include <termios.h>
42 #endif
43 #ifdef HAVE_SYS_IOCTL_H
44 #include <sys/ioctl.h>
45 #endif
46
47 #include "winerror.h"
48 #include "windef.h"
49 #include "winbase.h"
50
51 #include "file.h"
52 #include "handle.h"
53 #include "thread.h"
54 #include "request.h"
55
56 static void smb_dump( struct object *obj, int verbose );
57 static struct fd *smb_get_fd( struct object *obj );
58 static void smb_destroy(struct object *obj);
59
60 static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags );
61 static int smb_get_poll_events( struct fd *fd );
62
63 struct smb
64 {
65     struct object       obj;
66     struct fd          *fd;
67     unsigned int        tree_id;
68     unsigned int        user_id;
69     unsigned int        dialect;
70     unsigned int        file_id;
71     unsigned int        offset;
72 };
73
74 static const struct object_ops smb_ops =
75 {
76     sizeof(struct smb),        /* size */
77     smb_dump,                  /* dump */
78     default_fd_add_queue,      /* add_queue */
79     default_fd_remove_queue,   /* remove_queue */
80     default_fd_signaled,       /* signaled */
81     no_satisfied,              /* satisfied */
82     smb_get_fd,                /* get_fd */
83     smb_destroy                /* destroy */
84 };
85
86 static const struct fd_ops smb_fd_ops =
87 {
88     smb_get_poll_events,       /* get_poll_events */
89     default_poll_event,        /* poll_event */
90     no_flush,                  /* flush */
91     smb_get_info,              /* get_file_info */
92     no_queue_async             /* queue_async */
93 };
94
95 static struct fd *smb_get_fd( struct object *obj )
96 {
97     struct smb *smb = (struct smb *)obj;
98     return (struct fd *)grab_object( smb->fd );
99 }
100
101 static void smb_destroy( struct object *obj)
102 {
103     struct smb *smb = (struct smb *)obj;
104     assert( obj->ops == &smb_ops );
105     if (smb->fd) release_object( smb->fd );
106 }
107
108 static void smb_dump( struct object *obj, int verbose )
109 {
110     struct smb *smb = (struct smb *)obj;
111     assert( obj->ops == &smb_ops );
112     fprintf( stderr, "Smb file fd=%p\n", smb->fd );
113 }
114
115 static struct smb *get_smb_obj( struct process *process, obj_handle_t handle, unsigned int access )
116 {
117     return (struct smb *)get_handle_obj( process, handle, access, &smb_ops );
118 }
119
120 static int smb_get_poll_events( struct fd *fd )
121 {
122     struct smb *smb = get_fd_user( fd );
123     int events = 0;
124     assert( smb->obj.ops == &smb_ops );
125
126     events |= POLLIN;
127
128     /* fprintf(stderr,"poll events are %04x\n",events); */
129
130     return events;
131 }
132
133 static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags )
134 {
135 /*    struct smb *smb = get_fd_user( fd ); */
136 /*    assert( smb->obj.ops == &smb_ops ); */
137
138     if (reply)
139     {
140         reply->type        = FILE_TYPE_CHAR;
141         reply->attr        = 0;
142         reply->access_time = 0;
143         reply->write_time  = 0;
144         reply->size_high   = 0;
145         reply->size_low    = 0;
146         reply->links       = 0;
147         reply->index_high  = 0;
148         reply->index_low   = 0;
149         reply->serial      = 0;
150     }
151
152     *flags = 0;
153
154     return FD_TYPE_SMB;
155 }
156
157 /* create a smb */
158 DECL_HANDLER(create_smb)
159 {
160     struct smb *smb;
161     int fd;
162
163     reply->handle = 0;
164
165     fd = thread_get_inflight_fd( current, req->fd );
166     if (fd == -1)
167     {
168         set_error( STATUS_INVALID_HANDLE );
169         return;
170     }
171
172     if (!(smb = alloc_object( &smb_ops )))
173     {
174         close( fd );
175         return;
176     }
177     smb->tree_id = req->tree_id;
178     smb->user_id = req->user_id;
179     smb->dialect = req->dialect;
180     smb->file_id = req->file_id;
181     smb->offset = 0;
182     if ((smb->fd = create_anonymous_fd( &smb_fd_ops, fd, &smb->obj )))
183     {
184         reply->handle = alloc_handle( current->process, smb, GENERIC_READ, 0);
185     }
186     release_object( smb );
187 }
188
189 DECL_HANDLER(get_smb_info)
190 {
191     struct smb *smb;
192
193     if ((smb = get_smb_obj( current->process, req->handle, 0 )))
194     {
195         if(req->flags & SMBINFO_SET_OFFSET)
196             smb->offset = req->offset;
197
198         reply->tree_id = smb->tree_id;
199         reply->user_id = smb->user_id;
200         reply->dialect = smb->dialect;
201         reply->file_id = smb->file_id;
202         reply->offset  = smb->offset;
203
204         release_object( smb );
205     }
206 }