Use SA_RESTART on NetBSD.
[wine] / dlls / ntdll / file.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20 #include "wine/port.h"
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #ifdef HAVE_SYS_ERRNO_H
30 #include <sys/errno.h>
31 #endif
32
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 #include "wine/server.h"
38 #include "ntdll_misc.h"
39 #include "file.h" /* FIXME */
40
41 #include "winternl.h"
42 #include "winioctl.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
45
46
47 /**************************************************************************
48  *                 NtOpenFile                           [NTDLL.@]
49  *                 ZwOpenFile                           [NTDLL.@]
50  * FUNCTION: Opens a file
51  * ARGUMENTS:
52  *  FileHandle          Variable that receives the file handle on return
53  *  DesiredAccess       Access desired by the caller to the file
54  *  ObjectAttributes    Structue describing the file to be opened
55  *  IoStatusBlock       Receives details about the result of the operation
56  *  ShareAccess         Type of shared access the caller requires
57  *  OpenOptions         Options for the file open
58  */
59 NTSTATUS WINAPI NtOpenFile(
60         OUT PHANDLE FileHandle,
61         ACCESS_MASK DesiredAccess,
62         POBJECT_ATTRIBUTES ObjectAttributes,
63         OUT PIO_STATUS_BLOCK IoStatusBlock,
64         ULONG ShareAccess,
65         ULONG OpenOptions)
66 {
67         LPWSTR filename;
68         static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
69         DOS_FULL_NAME full_name;
70         NTSTATUS r;
71
72         FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) partial stub\n",
73                 FileHandle, DesiredAccess, ObjectAttributes,
74                 IoStatusBlock, ShareAccess, OpenOptions);
75
76         dump_ObjectAttributes (ObjectAttributes);
77
78         if(ObjectAttributes->RootDirectory)
79         {
80                 FIXME("Object root directory unknown %p\n",
81                         ObjectAttributes->RootDirectory);
82                 return STATUS_OBJECT_NAME_NOT_FOUND;
83         }
84
85         filename = ObjectAttributes->ObjectName->Buffer;
86
87         /* FIXME: DOSFS stuff should call here, not vice-versa */
88         if(strncmpW(filename, szDosDevices, strlenW(szDosDevices)))
89                 return STATUS_OBJECT_NAME_NOT_FOUND;
90
91         /* FIXME: this calls SetLastError() -> bad */
92         if(!DOSFS_GetFullName(&filename[strlenW(szDosDevices)], TRUE,
93                                 &full_name))
94                 return STATUS_OBJECT_NAME_NOT_FOUND;
95
96         /* FIXME: modify server protocol so
97                   create file takes an OBJECT_ATTRIBUTES structure */
98         SERVER_START_REQ( create_file )
99         {
100             req->access     = DesiredAccess;
101             req->inherit    = 0;
102             req->sharing    = ShareAccess;
103             req->create     = OPEN_EXISTING;
104             req->attrs      = 0;
105             req->drive_type = GetDriveTypeW( full_name.short_name );
106             wine_server_add_data( req, full_name.long_name, strlen(full_name.long_name) );
107             SetLastError(0);
108             r = wine_server_call( req );
109             *FileHandle = reply->handle;
110         }
111         SERVER_END_REQ;
112
113         return r;
114 }
115
116 /**************************************************************************
117  *              NtCreateFile                            [NTDLL.@]
118  *              ZwCreateFile                            [NTDLL.@]
119  * FUNCTION: Either causes a new file or directory to be created, or it opens
120  *  an existing file, device, directory or volume, giving the caller a handle
121  *  for the file object. This handle can be used by subsequent calls to
122  *  manipulate data within the file or the file object's state of attributes.
123  * ARGUMENTS:
124  *      FileHandle              Points to a variable which receives the file handle on return
125  *      DesiredAccess           Desired access to the file
126  *      ObjectAttributes        Structure describing the file
127  *      IoStatusBlock           Receives information about the operation on return
128  *      AllocationSize          Initial size of the file in bytes
129  *      FileAttributes          Attributes to create the file with
130  *      ShareAccess             Type of shared access the caller would like to the file
131  *      CreateDisposition       Specifies what to do, depending on whether the file already exists
132  *      CreateOptions           Options for creating a new file
133  *      EaBuffer                Undocumented
134  *      EaLength                Undocumented
135  */
136 NTSTATUS WINAPI NtCreateFile(
137         OUT PHANDLE FileHandle,
138         ACCESS_MASK DesiredAccess,
139         POBJECT_ATTRIBUTES ObjectAttributes,
140         OUT PIO_STATUS_BLOCK IoStatusBlock,
141         PLARGE_INTEGER AllocateSize,
142         ULONG FileAttributes,
143         ULONG ShareAccess,
144         ULONG CreateDisposition,
145         ULONG CreateOptions,
146         PVOID EaBuffer,
147         ULONG EaLength)
148 {
149         FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
150         FileHandle,DesiredAccess,ObjectAttributes,
151         IoStatusBlock,AllocateSize,FileAttributes,
152         ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
153         dump_ObjectAttributes (ObjectAttributes);
154         return 0;
155 }
156
157 /* set the last error depending on errno */
158 NTSTATUS NTFILE_errno_to_status(int val)
159 {
160     switch (val)
161     {
162     case EAGAIN:    return ( STATUS_SHARING_VIOLATION );
163     case ESPIPE:
164     case EBADF:     return ( STATUS_INVALID_HANDLE );
165     case ENOSPC:    return ( STATUS_DISK_FULL );
166     case EACCES:
167     case ESRCH:
168     case EPERM:     return ( STATUS_ACCESS_DENIED );
169     case EROFS:     return ( STATUS_MEDIA_WRITE_PROTECTED );
170     case EBUSY:     return ( STATUS_FILE_LOCK_CONFLICT );
171     case ENOENT:    return ( STATUS_NO_SUCH_FILE );
172     case EISDIR:    return ( STATUS_FILE_IS_A_DIRECTORY );
173     case ENFILE:
174     case EMFILE:    return ( STATUS_NO_MORE_FILES );
175     case EEXIST:    return ( STATUS_OBJECT_NAME_COLLISION );
176     case EINVAL:    return ( STATUS_INVALID_PARAMETER );
177     case ENOTEMPTY: return ( STATUS_DIRECTORY_NOT_EMPTY );
178     case EIO:       return ( STATUS_ACCESS_VIOLATION );
179     }
180     perror("file_set_error");
181     return ( STATUS_INVALID_PARAMETER );
182 }
183
184
185 /******************************************************************************
186  *  NtReadFile                                  [NTDLL.@]
187  *  ZwReadFile                                  [NTDLL.@]
188  *
189  * Parameters
190  *   HANDLE32           FileHandle
191  *   HANDLE32           Event           OPTIONAL
192  *   PIO_APC_ROUTINE    ApcRoutine      OPTIONAL
193  *   PVOID              ApcContext      OPTIONAL
194  *   PIO_STATUS_BLOCK   IoStatusBlock
195  *   PVOID              Buffer
196  *   ULONG              Length
197  *   PLARGE_INTEGER     ByteOffset      OPTIONAL
198  *   PULONG             Key             OPTIONAL
199  *
200  * IoStatusBlock->Information contains the number of bytes read on return.
201  */
202 NTSTATUS WINAPI NtReadFile (
203         HANDLE FileHandle,
204         HANDLE EventHandle,
205         PIO_APC_ROUTINE ApcRoutine,
206         PVOID ApcContext,
207         PIO_STATUS_BLOCK IoStatusBlock,
208         PVOID Buffer,
209         ULONG Length,
210         PLARGE_INTEGER ByteOffset,
211         PULONG Key)
212 {
213         int fd, result, flags, ret;
214         enum fd_type type;
215
216         FIXME("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),partial stub!\n",
217                 FileHandle,EventHandle,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
218
219         if (IsBadWritePtr( Buffer, Length ) ||
220             IsBadWritePtr( IoStatusBlock, sizeof *IoStatusBlock) ||
221             IsBadWritePtr( ByteOffset, sizeof *ByteOffset) )
222                 return STATUS_ACCESS_VIOLATION;
223
224         IoStatusBlock->Information = 0;
225
226         ret = wine_server_handle_to_fd( FileHandle, GENERIC_READ, &fd, &type, &flags );
227         if(ret)
228                 return ret;
229
230         /* FIXME: this code only does synchronous reads so far */
231
232         /* FIXME: depending on how libc implements this, between two processes
233               there could be a race condition between the seek and read here */
234         do
235         {
236                 result = pread( fd, Buffer, Length, ByteOffset->QuadPart);
237         }
238         while ( (result == -1) && ((errno == EAGAIN) || (errno == EINTR)) );
239
240         close( fd );
241
242         if (result == -1)
243         {
244                 return IoStatusBlock->u.Status = NTFILE_errno_to_status(errno);
245         }
246
247         IoStatusBlock->Information = result;
248         IoStatusBlock->u.Status = 0;
249
250         return STATUS_SUCCESS;
251 }
252
253 /******************************************************************************
254  *  NtWriteFile                                 [NTDLL.@]
255  *  ZwWriteFile                                 [NTDLL.@]
256  *
257  * Parameters
258  *   HANDLE32           FileHandle
259  *   HANDLE32           Event           OPTIONAL
260  *   PIO_APC_ROUTINE    ApcRoutine      OPTIONAL
261  *   PVOID              ApcContext      OPTIONAL
262  *   PIO_STATUS_BLOCK   IoStatusBlock
263  *   PVOID              Buffer
264  *   ULONG              Length
265  *   PLARGE_INTEGER     ByteOffset      OPTIONAL
266  *   PULONG             Key             OPTIONAL
267  */
268 NTSTATUS WINAPI NtWriteFile (
269         HANDLE FileHandle,
270         HANDLE EventHandle,
271         PIO_APC_ROUTINE ApcRoutine,
272         PVOID ApcContext,
273         PIO_STATUS_BLOCK IoStatusBlock,
274         PVOID Buffer,
275         ULONG Length,
276         PLARGE_INTEGER ByteOffset,
277         PULONG Key)
278 {
279         FIXME("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),stub!\n",
280         FileHandle,EventHandle,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
281         return 0;
282 }
283
284 /**************************************************************************
285  *              NtDeviceIoControlFile                   [NTDLL.@]
286  *              ZwDeviceIoControlFile                   [NTDLL.@]
287  */
288 NTSTATUS WINAPI NtDeviceIoControlFile(
289         IN HANDLE DeviceHandle,
290         IN HANDLE Event OPTIONAL,
291         IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
292         IN PVOID UserApcContext OPTIONAL,
293         OUT PIO_STATUS_BLOCK IoStatusBlock,
294         IN ULONG IoControlCode,
295         IN PVOID InputBuffer,
296         IN ULONG InputBufferSize,
297         OUT PVOID OutputBuffer,
298         IN ULONG OutputBufferSize)
299 {
300         FIXME("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx): empty stub\n",
301         DeviceHandle, Event, UserApcRoutine, UserApcContext,
302         IoStatusBlock, IoControlCode, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize);
303         return 0;
304 }
305
306 /******************************************************************************
307  * NtFsControlFile [NTDLL.@]
308  * ZwFsControlFile [NTDLL.@]
309  */
310 NTSTATUS WINAPI NtFsControlFile(
311         IN HANDLE DeviceHandle,
312         IN HANDLE Event OPTIONAL,
313         IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
314         IN PVOID ApcContext OPTIONAL,
315         OUT PIO_STATUS_BLOCK IoStatusBlock,
316         IN ULONG IoControlCode,
317         IN PVOID InputBuffer,
318         IN ULONG InputBufferSize,
319         OUT PVOID OutputBuffer,
320         IN ULONG OutputBufferSize)
321 {
322         FIXME("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx): stub\n",
323         DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,IoControlCode,
324         InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize);
325         return 0;
326 }
327
328 /******************************************************************************
329  *  NtSetVolumeInformationFile          [NTDLL.@]
330  *  ZwSetVolumeInformationFile          [NTDLL.@]
331  */
332 NTSTATUS WINAPI NtSetVolumeInformationFile(
333         IN HANDLE FileHandle,
334         PIO_STATUS_BLOCK IoStatusBlock,
335         PVOID FsInformation,
336         ULONG Length,
337         FS_INFORMATION_CLASS FsInformationClass)
338 {
339         FIXME("(%p,%p,%p,0x%08lx,0x%08x) stub\n",
340         FileHandle,IoStatusBlock,FsInformation,Length,FsInformationClass);
341         return 0;
342 }
343
344 /******************************************************************************
345  *  NtQueryInformationFile              [NTDLL.@]
346  *  ZwQueryInformationFile              [NTDLL.@]
347  */
348 NTSTATUS WINAPI NtQueryInformationFile(
349         HANDLE FileHandle,
350         PIO_STATUS_BLOCK IoStatusBlock,
351         PVOID FileInformation,
352         ULONG Length,
353         FILE_INFORMATION_CLASS FileInformationClass)
354 {
355         FIXME("(%p,%p,%p,0x%08lx,0x%08x),stub!\n",
356         FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
357         return 0;
358 }
359
360 /******************************************************************************
361  *  NtSetInformationFile                [NTDLL.@]
362  *  ZwSetInformationFile                [NTDLL.@]
363  */
364 NTSTATUS WINAPI NtSetInformationFile(
365         HANDLE FileHandle,
366         PIO_STATUS_BLOCK IoStatusBlock,
367         PVOID FileInformation,
368         ULONG Length,
369         FILE_INFORMATION_CLASS FileInformationClass)
370 {
371         FIXME("(%p,%p,%p,0x%08lx,0x%08x)\n",
372         FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
373         return 0;
374 }
375
376 /******************************************************************************
377  *  NtQueryDirectoryFile        [NTDLL.@]
378  *  ZwQueryDirectoryFile        [NTDLL.@]
379  *  ZwQueryDirectoryFile
380  */
381 NTSTATUS WINAPI NtQueryDirectoryFile(
382         IN HANDLE FileHandle,
383         IN HANDLE Event OPTIONAL,
384         IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
385         IN PVOID ApcContext OPTIONAL,
386         OUT PIO_STATUS_BLOCK IoStatusBlock,
387         OUT PVOID FileInformation,
388         IN ULONG Length,
389         IN FILE_INFORMATION_CLASS FileInformationClass,
390         IN BOOLEAN ReturnSingleEntry,
391         IN PUNICODE_STRING FileName OPTIONAL,
392         IN BOOLEAN RestartScan)
393 {
394         FIXME("(%p %p %p %p %p %p 0x%08lx 0x%08x 0x%08x %p 0x%08x\n",
395         FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
396         Length, FileInformationClass, ReturnSingleEntry,
397         debugstr_us(FileName),RestartScan);
398         return 0;
399 }
400
401 /******************************************************************************
402  *  NtQueryVolumeInformationFile                [NTDLL.@]
403  *  ZwQueryVolumeInformationFile                [NTDLL.@]
404  */
405 NTSTATUS WINAPI NtQueryVolumeInformationFile (
406         IN HANDLE FileHandle,
407         OUT PIO_STATUS_BLOCK IoStatusBlock,
408         OUT PVOID FSInformation,
409         IN ULONG Length,
410         IN FS_INFORMATION_CLASS FSInformationClass)
411 {
412         ULONG len = 0;
413
414         FIXME("(%p %p %p 0x%08lx 0x%08x) stub!\n",
415         FileHandle, IoStatusBlock, FSInformation, Length, FSInformationClass);
416
417         switch ( FSInformationClass )
418         {
419           case FileFsVolumeInformation:
420             len = sizeof( FILE_FS_VOLUME_INFORMATION );
421             break;
422           case FileFsLabelInformation:
423             len = 0;
424             break;
425
426           case FileFsSizeInformation:
427             len = sizeof( FILE_FS_SIZE_INFORMATION );
428             break;
429
430           case FileFsDeviceInformation:
431             len = sizeof( FILE_FS_DEVICE_INFORMATION );
432             break;
433           case FileFsAttributeInformation:
434             len = sizeof( FILE_FS_ATTRIBUTE_INFORMATION );
435             break;
436
437           case FileFsControlInformation:
438             len = 0;
439             break;
440
441           case FileFsFullSizeInformation:
442             len = 0;
443             break;
444
445           case FileFsObjectIdInformation:
446             len = 0;
447             break;
448
449           case FileFsMaximumInformation:
450             len = 0;
451             break;
452         }
453
454         if (Length < len)
455           return STATUS_BUFFER_TOO_SMALL;
456
457         switch ( FSInformationClass )
458         {
459           case FileFsVolumeInformation:
460             break;
461           case FileFsLabelInformation:
462             break;
463
464           case FileFsSizeInformation:
465             break;
466
467           case FileFsDeviceInformation:
468             if (FSInformation)
469             {
470               FILE_FS_DEVICE_INFORMATION * DeviceInfo = FSInformation;
471               DeviceInfo->DeviceType = FILE_DEVICE_DISK;
472               DeviceInfo->Characteristics = 0;
473               break;
474             };
475           case FileFsAttributeInformation:
476             break;
477
478           case FileFsControlInformation:
479             break;
480
481           case FileFsFullSizeInformation:
482             break;
483
484           case FileFsObjectIdInformation:
485             break;
486
487           case FileFsMaximumInformation:
488             break;
489         }
490         IoStatusBlock->DUMMYUNIONNAME.Status = STATUS_SUCCESS;
491         IoStatusBlock->Information = len;
492         return STATUS_SUCCESS;
493 }
494
495 /******************************************************************
496  *              NtFlushBuffersFile  (NTDLL.@)
497  */
498 NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock )
499 {
500     NTSTATUS ret;
501     HANDLE hEvent = NULL;
502
503     SERVER_START_REQ( flush_file )
504     {
505         req->handle = hFile;
506         ret = wine_server_call( req );
507         hEvent = reply->event;
508     }
509     SERVER_END_REQ;
510     if( !ret && hEvent )
511     {
512         ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
513         NtClose( hEvent );
514     }
515     return ret;
516 }