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