2 * Copyright 1999, 2000 Juergen Schmied
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.
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.
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
20 #include "wine/port.h"
30 #ifdef HAVE_SYS_ERRNO_H
31 #include <sys/errno.h>
34 #define NONAMELESSUNION
35 #define NONAMELESSSTRUCT
36 #include "wine/unicode.h"
37 #include "wine/debug.h"
38 #include "wine/server.h"
40 #include "ntdll_misc.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
47 /**************************************************************************
48 * NtOpenFile [NTDLL.@]
49 * ZwOpenFile [NTDLL.@]
54 * FileHandle [O] Variable that receives the file handle on return
55 * DesiredAccess [I] Access desired by the caller to the file
56 * ObjectAttributes [I] Structue describing the file to be opened
57 * IoStatusBlock [O] Receives details about the result of the operation
58 * ShareAccess [I] Type of shared access the caller requires
59 * OpenOptions [I] Options for the file open
62 * Success: 0. FileHandle and IoStatusBlock are updated.
63 * Failure: An NTSTATUS error code describing the error.
65 NTSTATUS WINAPI NtOpenFile(
66 OUT PHANDLE FileHandle,
67 ACCESS_MASK DesiredAccess,
68 POBJECT_ATTRIBUTES ObjectAttributes,
69 OUT PIO_STATUS_BLOCK IoStatusBlock,
74 static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
76 FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) partial stub\n",
77 FileHandle, DesiredAccess, ObjectAttributes,
78 IoStatusBlock, ShareAccess, OpenOptions);
80 dump_ObjectAttributes (ObjectAttributes);
82 if(ObjectAttributes->RootDirectory)
84 FIXME("Object root directory unknown %p\n",
85 ObjectAttributes->RootDirectory);
86 return STATUS_OBJECT_NAME_NOT_FOUND;
89 filename = ObjectAttributes->ObjectName->Buffer;
91 /* FIXME: DOSFS stuff should call here, not vice-versa */
92 if(strncmpW(filename, szDosDevices, strlenW(szDosDevices)))
93 return STATUS_OBJECT_NAME_NOT_FOUND;
95 /* FIXME: this calls SetLastError() -> bad */
96 *FileHandle = pCreateFileW( &filename[strlenW(szDosDevices)], DesiredAccess, ShareAccess,
97 NULL, OPEN_EXISTING, 0, 0 );
98 if (*FileHandle == INVALID_HANDLE_VALUE) return STATUS_OBJECT_NAME_NOT_FOUND;
99 return STATUS_SUCCESS;
102 /**************************************************************************
103 * NtCreateFile [NTDLL.@]
104 * ZwCreateFile [NTDLL.@]
106 * Either create a new file or directory, or open an existing file, device,
107 * directory or volume.
110 * FileHandle [O] Points to a variable which receives the file handle on return
111 * DesiredAccess [I] Desired access to the file
112 * ObjectAttributes [I] Structure describing the file
113 * IoStatusBlock [O] Receives information about the operation on return
114 * AllocationSize [I] Initial size of the file in bytes
115 * FileAttributes [I] Attributes to create the file with
116 * ShareAccess [I] Type of shared access the caller would like to the file
117 * CreateDisposition [I] Specifies what to do, depending on whether the file already exists
118 * CreateOptions [I] Options for creating a new file
119 * EaBuffer [I] Undocumented
120 * EaLength [I] Undocumented
123 * Success: 0. FileHandle and IoStatusBlock are updated.
124 * Failure: An NTSTATUS error code describing the error.
126 NTSTATUS WINAPI NtCreateFile(
127 OUT PHANDLE FileHandle,
128 ACCESS_MASK DesiredAccess,
129 POBJECT_ATTRIBUTES ObjectAttributes,
130 OUT PIO_STATUS_BLOCK IoStatusBlock,
131 PLARGE_INTEGER AllocateSize,
132 ULONG FileAttributes,
134 ULONG CreateDisposition,
139 FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
140 FileHandle,DesiredAccess,ObjectAttributes,
141 IoStatusBlock,AllocateSize,FileAttributes,
142 ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
143 dump_ObjectAttributes (ObjectAttributes);
147 /***********************************************************************
148 * Asynchronous file I/O *
150 static DWORD fileio_get_async_count(const async_private *ovp);
151 static void CALLBACK fileio_call_completion_func(ULONG_PTR data);
152 static void fileio_async_cleanup(async_private *ovp);
154 static async_ops fileio_async_ops =
156 fileio_get_async_count, /* get_count */
157 fileio_call_completion_func, /* call_completion */
158 fileio_async_cleanup /* cleanup */
161 static async_ops fileio_nocomp_async_ops =
163 fileio_get_async_count, /* get_count */
164 NULL, /* call_completion */
165 fileio_async_cleanup /* cleanup */
168 typedef struct async_fileio
170 struct async_private async;
175 unsigned long offset;
176 enum fd_type fd_type;
179 static DWORD fileio_get_async_count(const struct async_private *ovp)
181 async_fileio *fileio = (async_fileio*) ovp;
183 if (fileio->count < fileio->async.iosb->Information)
185 return fileio->count - fileio->async.iosb->Information;
188 static void CALLBACK fileio_call_completion_func(ULONG_PTR data)
190 async_fileio *ovp = (async_fileio*) data;
191 TRACE("data: %p\n", ovp);
193 ovp->apc( ovp->apc_user, ovp->async.iosb, ovp->async.iosb->Information );
195 fileio_async_cleanup( &ovp->async );
198 static void fileio_async_cleanup( struct async_private *ovp )
200 RtlFreeHeap( ntdll_get_process_heap(), 0, ovp );
203 /***********************************************************************
204 * FILE_GetUnixHandleType
206 * Retrieve the Unix handle corresponding to a file handle.
207 * Returns -1 on failure.
209 static int FILE_GetUnixHandleType( HANDLE handle, DWORD access, enum fd_type *type, int *flags_ptr, int *fd )
214 ret = wine_server_handle_to_fd( handle, access, fd, type, &flags );
215 if (flags_ptr) *flags_ptr = flags;
216 if (!ret && (((access & GENERIC_READ) && (flags & FD_FLAG_RECV_SHUTDOWN)) ||
217 ((access & GENERIC_WRITE) && (flags & FD_FLAG_SEND_SHUTDOWN))))
220 ret = STATUS_PIPE_DISCONNECTED;
225 /***********************************************************************
226 * FILE_GetNtStatus(void)
228 * Retrieve the Nt Status code from errno.
229 * Try to be consistent with FILE_SetDosError().
231 static DWORD FILE_GetNtStatus(void)
236 TRACE( "errno = %d\n", errno );
239 case EAGAIN: nt = STATUS_SHARING_VIOLATION; break;
240 case EBADF: nt = STATUS_INVALID_HANDLE; break;
241 case ENOSPC: nt = STATUS_DISK_FULL; break;
244 case EACCES: nt = STATUS_ACCESS_DENIED; break;
245 case ENOENT: nt = STATUS_SHARING_VIOLATION; break;
246 case EISDIR: nt = STATUS_FILE_IS_A_DIRECTORY; break;
248 case ENFILE: nt = STATUS_NO_MORE_FILES; break;
250 case ENOTEMPTY: nt = STATUS_DIRECTORY_NOT_EMPTY; break;
251 case EPIPE: nt = STATUS_PIPE_BROKEN; break;
252 case ENOEXEC: /* ?? */
253 case ESPIPE: /* ?? */
254 case EEXIST: /* ?? */
256 FIXME( "Converting errno %d to STATUS_UNSUCCESSFUL\n", err );
257 nt = STATUS_UNSUCCESSFUL;
262 /***********************************************************************
263 * FILE_AsyncReadService (INTERNAL)
265 * This function is called while the client is waiting on the
266 * server, so we can't make any server calls here.
268 static void FILE_AsyncReadService(async_private *ovp)
270 async_fileio *fileio = (async_fileio*) ovp;
271 IO_STATUS_BLOCK* io_status = fileio->async.iosb;
273 int already = io_status->Information;
275 TRACE("%p %p\n", io_status, fileio->buffer );
277 /* check to see if the data is ready (non-blocking) */
279 if ( fileio->fd_type == FD_TYPE_SOCKET )
280 result = read(ovp->fd, &fileio->buffer[already], fileio->count - already);
283 result = pread(ovp->fd, &fileio->buffer[already], fileio->count - already,
284 fileio->offset + already);
285 if ((result < 0) && (errno == ESPIPE))
286 result = read(ovp->fd, &fileio->buffer[already], fileio->count - already);
289 if ((result < 0) && ((errno == EAGAIN) || (errno == EINTR)))
291 TRACE("Deferred read %d\n",errno);
292 io_status->u.Status = STATUS_PENDING;
296 /* check to see if the transfer is complete */
299 io_status->u.Status = FILE_GetNtStatus();
302 else if (result == 0)
304 io_status->u.Status = io_status->Information ? STATUS_SUCCESS : STATUS_END_OF_FILE;
308 io_status->Information += result;
309 if (io_status->Information >= fileio->count || fileio->fd_type == FD_TYPE_SOCKET )
310 io_status->u.Status = STATUS_SUCCESS;
312 io_status->u.Status = STATUS_PENDING;
314 TRACE("read %d more bytes %ld/%d so far\n",
315 result, io_status->Information, fileio->count);
319 /******************************************************************************
320 * NtReadFile [NTDLL.@]
321 * ZwReadFile [NTDLL.@]
323 * Read from an open file handle.
326 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
327 * Event [I] Event to signal upon completion (or NULL)
328 * ApcRoutine [I] Callback to call upon completion (or NULL)
329 * ApcContext [I] Context for ApcRoutine (or NULL)
330 * IoStatusBlock [O] Receives information about the operation on return
331 * Buffer [O] Destination for the data read
332 * Length [I] Size of Buffer
333 * ByteOffset [O] Destination for the new file pointer position (or NULL)
334 * Key [O] Function unknown (may be NULL)
337 * Success: 0. IoStatusBlock is updated, and the Information member contains
338 * The number of bytes read.
339 * Failure: An NTSTATUS error code describing the error.
341 NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
342 PIO_APC_ROUTINE apc, void* apc_user,
343 PIO_STATUS_BLOCK io_status, void* buffer, ULONG length,
344 PLARGE_INTEGER offset, PULONG key)
346 int unix_handle, flags;
349 TRACE("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),partial stub!\n",
350 hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
352 io_status->Information = 0;
353 io_status->u.Status = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type, &flags, &unix_handle );
354 if (io_status->u.Status) return io_status->u.Status;
356 if (flags & FD_FLAG_TIMEOUT)
360 /* this shouldn't happen, but check it */
361 FIXME("NIY-hEvent\n");
362 return STATUS_NOT_IMPLEMENTED;
364 io_status->u.Status = NtCreateEvent(&hEvent, SYNCHRONIZE, NULL, 0, 0);
365 if (io_status->u.Status) return io_status->u.Status;
368 if (flags & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))
373 if (unix_handle < 0) return STATUS_INVALID_HANDLE;
375 ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio));
376 if (!ovp) return STATUS_NO_MEMORY;
378 ovp->async.ops = (apc ? &fileio_async_ops : &fileio_nocomp_async_ops );
379 ovp->async.handle = hFile;
380 ovp->async.fd = unix_handle;
381 ovp->async.type = ASYNC_TYPE_READ;
382 ovp->async.func = FILE_AsyncReadService;
383 ovp->async.event = hEvent;
384 ovp->async.iosb = io_status;
386 if ( offset == NULL )
390 ovp->offset = offset->s.LowPart;
391 if (offset->s.HighPart) FIXME("NIY-high part\n");
394 ovp->apc_user = apc_user;
395 ovp->buffer = buffer;
398 io_status->Information = 0;
399 ret = register_new_async(&ovp->async);
400 if (ret != STATUS_SUCCESS)
402 if (flags & FD_FLAG_TIMEOUT)
404 NtWaitForSingleObject(hEvent, TRUE, NULL);
409 LARGE_INTEGER timeout;
411 /* let some APC be run, this will read some already pending data */
412 timeout.s.LowPart = timeout.s.HighPart = 0;
413 NtDelayExecution( TRUE, &timeout );
415 return io_status->u.Status;
423 /* return SMB_ReadFile(hFile, buffer, length, io_status); */
424 return STATUS_INVALID_HANDLE;
426 case FD_TYPE_DEFAULT:
427 /* normal unix files */
428 if (unix_handle == -1) return STATUS_INVALID_HANDLE;
432 FIXME("Unsupported type of fd %d\n", type);
433 if (unix_handle == -1) close(unix_handle);
434 return STATUS_INVALID_HANDLE;
439 FILE_POSITION_INFORMATION fpi;
441 fpi.CurrentByteOffset = *offset;
442 io_status->u.Status = NtSetInformationFile(hFile, io_status, &fpi, sizeof(fpi),
443 FilePositionInformation);
444 if (io_status->u.Status)
447 return io_status->u.Status;
450 /* code for synchronous reads */
451 while ((io_status->Information = read( unix_handle, buffer, length )) == -1)
453 if ((errno == EAGAIN) || (errno == EINTR)) continue;
454 if (errno == EFAULT) FIXME( "EFAULT handling broken for now\n" );
455 io_status->u.Status = FILE_GetNtStatus();
458 close( unix_handle );
459 return io_status->u.Status;
462 /***********************************************************************
463 * FILE_AsyncWriteService (INTERNAL)
465 * This function is called while the client is waiting on the
466 * server, so we can't make any server calls here.
468 static void FILE_AsyncWriteService(struct async_private *ovp)
470 async_fileio *fileio = (async_fileio *) ovp;
471 PIO_STATUS_BLOCK io_status = fileio->async.iosb;
473 int already = io_status->Information;
475 TRACE("(%p %p)\n",io_status,fileio->buffer);
477 /* write some data (non-blocking) */
479 if ( fileio->fd_type == FD_TYPE_SOCKET )
480 result = write(ovp->fd, &fileio->buffer[already], fileio->count - already);
483 result = pwrite(ovp->fd, &fileio->buffer[already], fileio->count - already,
484 fileio->offset + already);
485 if ((result < 0) && (errno == ESPIPE))
486 result = write(ovp->fd, &fileio->buffer[already], fileio->count - already);
489 if ((result < 0) && ((errno == EAGAIN) || (errno == EINTR)))
491 io_status->u.Status = STATUS_PENDING;
495 /* check to see if the transfer is complete */
498 io_status->u.Status = FILE_GetNtStatus();
502 io_status->Information += result;
503 io_status->u.Status = (io_status->Information < fileio->count) ? STATUS_PENDING : STATUS_SUCCESS;
504 TRACE("wrote %d more bytes %ld/%d so far\n",result,io_status->Information,fileio->count);
507 /******************************************************************************
508 * NtWriteFile [NTDLL.@]
509 * ZwWriteFile [NTDLL.@]
511 * Write to an open file handle.
514 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
515 * Event [I] Event to signal upon completion (or NULL)
516 * ApcRoutine [I] Callback to call upon completion (or NULL)
517 * ApcContext [I] Context for ApcRoutine (or NULL)
518 * IoStatusBlock [O] Receives information about the operation on return
519 * Buffer [I] Source for the data to write
520 * Length [I] Size of Buffer
521 * ByteOffset [O] Destination for the new file pointer position (or NULL)
522 * Key [O] Function unknown (may be NULL)
525 * Success: 0. IoStatusBlock is updated, and the Information member contains
526 * The number of bytes written.
527 * Failure: An NTSTATUS error code describing the error.
529 NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
530 PIO_APC_ROUTINE apc, void* apc_user,
531 PIO_STATUS_BLOCK io_status,
532 const void* buffer, ULONG length,
533 PLARGE_INTEGER offset, PULONG key)
535 int unix_handle, flags;
538 TRACE("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p)!\n",
539 hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
541 TRACE("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),partial stub!\n",
542 hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
544 io_status->Information = 0;
546 io_status->u.Status = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type, &flags, &unix_handle );
547 if (io_status->u.Status) return io_status->u.Status;
549 if (flags & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))
554 if (unix_handle < 0) return STATUS_INVALID_HANDLE;
556 ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio));
557 if (!ovp) return STATUS_NO_MEMORY;
559 ovp->async.ops = (apc ? &fileio_async_ops : &fileio_nocomp_async_ops );
560 ovp->async.handle = hFile;
561 ovp->async.fd = unix_handle;
562 ovp->async.type = ASYNC_TYPE_WRITE;
563 ovp->async.func = FILE_AsyncWriteService;
564 ovp->async.event = hEvent;
565 ovp->async.iosb = io_status;
567 ovp->offset = offset->s.LowPart;
568 if (offset->s.HighPart) FIXME("NIY-high part\n");
570 ovp->apc_user = apc_user;
571 ovp->buffer = (void*)buffer;
574 io_status->Information = 0;
575 ret = register_new_async(&ovp->async);
576 if (ret != STATUS_SUCCESS)
578 if (flags & FD_FLAG_TIMEOUT)
580 NtWaitForSingleObject(hEvent, TRUE, NULL);
585 LARGE_INTEGER timeout;
587 /* let some APC be run, this will write as much data as possible */
588 timeout.s.LowPart = timeout.s.HighPart = 0;
589 NtDelayExecution( TRUE, &timeout );
591 return io_status->u.Status;
598 return STATUS_NOT_IMPLEMENTED;
600 case FD_TYPE_DEFAULT:
601 /* normal unix files */
602 if (unix_handle == -1) return STATUS_INVALID_HANDLE;
606 FIXME("Unsupported type of fd %d\n", type);
607 if (unix_handle == -1) close(unix_handle);
608 return STATUS_INVALID_HANDLE;
613 FILE_POSITION_INFORMATION fpi;
615 fpi.CurrentByteOffset = *offset;
616 io_status->u.Status = NtSetInformationFile(hFile, io_status, &fpi, sizeof(fpi),
617 FilePositionInformation);
618 if (io_status->u.Status)
621 return io_status->u.Status;
625 /* synchronous file write */
626 while ((io_status->Information = write( unix_handle, buffer, length )) == -1)
628 if ((errno == EAGAIN) || (errno == EINTR)) continue;
629 if (errno == EFAULT) FIXME( "EFAULT handling broken for now\n" );
630 if (errno == ENOSPC) io_status->u.Status = STATUS_DISK_FULL;
631 else io_status->u.Status = FILE_GetNtStatus();
634 close( unix_handle );
635 return io_status->u.Status;
638 /**************************************************************************
639 * NtDeviceIoControlFile [NTDLL.@]
640 * ZwDeviceIoControlFile [NTDLL.@]
642 * Perform an I/O control operation on an open file handle.
645 * DeviceHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
646 * Event [I] Event to signal upon completion (or NULL)
647 * ApcRoutine [I] Callback to call upon completion (or NULL)
648 * ApcContext [I] Context for ApcRoutine (or NULL)
649 * IoStatusBlock [O] Receives information about the operation on return
650 * IoControlCode [I] Control code for the operation to perform
651 * InputBuffer [I] Source for any input data required (or NULL)
652 * InputBufferSize [I] Size of InputBuffer
653 * OutputBuffer [O] Source for any output data returned (or NULL)
654 * OutputBufferSize [I] Size of OutputBuffer
657 * Success: 0. IoStatusBlock is updated.
658 * Failure: An NTSTATUS error code describing the error.
660 NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent,
661 PIO_APC_ROUTINE UserApcRoutine,
662 PVOID UserApcContext,
663 PIO_STATUS_BLOCK IoStatusBlock,
666 ULONG InputBufferSize,
668 ULONG OutputBufferSize)
672 TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
673 DeviceHandle, hEvent, UserApcRoutine, UserApcContext,
674 IoStatusBlock, IoControlCode,
675 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize);
677 /* FIXME: clientID hack should disappear */
678 SERVER_START_REQ( get_device_id )
680 req->handle = DeviceHandle;
681 if (!wine_server_call( req )) clientID = reply->id;
685 if (!clientID) return STATUS_INVALID_PARAMETER;
687 if (CDROM_DeviceIoControl(clientID, DeviceHandle, hEvent,
688 UserApcRoutine, UserApcContext,
689 IoStatusBlock, IoControlCode,
690 InputBuffer, InputBufferSize,
691 OutputBuffer, OutputBufferSize) == STATUS_NO_SUCH_DEVICE)
693 /* it wasn't a CDROM */
694 FIXME("Unimplemented dwIoControlCode=%08lx\n", IoControlCode);
695 IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED;
696 IoStatusBlock->Information = 0;
697 if (hEvent) NtSetEvent(hEvent, NULL);
699 return IoStatusBlock->u.Status;
702 /******************************************************************************
703 * NtFsControlFile [NTDLL.@]
704 * ZwFsControlFile [NTDLL.@]
706 NTSTATUS WINAPI NtFsControlFile(
707 IN HANDLE DeviceHandle,
708 IN HANDLE Event OPTIONAL,
709 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
710 IN PVOID ApcContext OPTIONAL,
711 OUT PIO_STATUS_BLOCK IoStatusBlock,
712 IN ULONG IoControlCode,
713 IN PVOID InputBuffer,
714 IN ULONG InputBufferSize,
715 OUT PVOID OutputBuffer,
716 IN ULONG OutputBufferSize)
718 FIXME("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx): stub\n",
719 DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,IoControlCode,
720 InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize);
724 /******************************************************************************
725 * NtSetVolumeInformationFile [NTDLL.@]
726 * ZwSetVolumeInformationFile [NTDLL.@]
728 * Set volume information for an open file handle.
731 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
732 * IoStatusBlock [O] Receives information about the operation on return
733 * FsInformation [I] Source for volume information
734 * Length [I] Size of FsInformation
735 * FsInformationClass [I] Type of volume information to set
738 * Success: 0. IoStatusBlock is updated.
739 * Failure: An NTSTATUS error code describing the error.
741 NTSTATUS WINAPI NtSetVolumeInformationFile(
742 IN HANDLE FileHandle,
743 PIO_STATUS_BLOCK IoStatusBlock,
746 FS_INFORMATION_CLASS FsInformationClass)
748 FIXME("(%p,%p,%p,0x%08lx,0x%08x) stub\n",
749 FileHandle,IoStatusBlock,FsInformation,Length,FsInformationClass);
753 /******************************************************************************
754 * NtQueryInformationFile [NTDLL.@]
755 * ZwQueryInformationFile [NTDLL.@]
757 * Get information about an open file handle.
760 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
761 * IoStatusBlock [O] Receives information about the operation on return
762 * FileInformation [O] Destination for file information
763 * Length [I] Size of FileInformation
764 * FileInformationClass [I] Type of file information to get
767 * Success: 0. IoStatusBlock and FileInformation are updated.
768 * Failure: An NTSTATUS error code describing the error.
770 NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
772 FILE_INFORMATION_CLASS class)
777 time_t ct = 0, wt = 0, at = 0;
779 TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
783 case FileBasicInformation:
785 FILE_BASIC_INFORMATION* fbi = (FILE_BASIC_INFORMATION*)answer;
786 if (sizeof(answer) < sizeof(*fbi)) goto too_small;
788 SERVER_START_REQ( get_file_info )
791 if (!(status = wine_server_call( req )))
793 /* FIXME: which file types are supported ?
794 * Serial ports (FILE_TYPE_CHAR) are not,
795 * and MSDN also says that pipes are not supported.
796 * FILE_TYPE_REMOTE seems to be supported according to
797 * MSDN q234741.txt */
798 if ((reply->type == FILE_TYPE_DISK) ||
799 (reply->type == FILE_TYPE_REMOTE))
801 at = reply->access_time;
802 wt = reply->write_time;
803 ct = reply->change_time;
804 fbi->FileAttributes = reply->attr;
807 else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
813 RtlSecondsSince1970ToTime(wt, &fbi->CreationTime);
814 RtlSecondsSince1970ToTime(wt, &fbi->LastWriteTime);
815 RtlSecondsSince1970ToTime(ct, &fbi->ChangeTime);
816 RtlSecondsSince1970ToTime(at, &fbi->LastAccessTime);
820 case FileStandardInformation:
822 FILE_STANDARD_INFORMATION* fsi = (FILE_STANDARD_INFORMATION*)answer;
823 if (sizeof(answer) < sizeof(*fsi)) goto too_small;
825 SERVER_START_REQ( get_file_info )
828 if (!(status = wine_server_call( req )))
830 /* FIXME: which file types are supported ?
831 * Serial ports (FILE_TYPE_CHAR) are not,
832 * and MSDN also says that pipes are not supported.
833 * FILE_TYPE_REMOTE seems to be supported according to
834 * MSDN q234741.txt */
835 if ((reply->type == FILE_TYPE_DISK) ||
836 (reply->type == FILE_TYPE_REMOTE))
838 fsi->AllocationSize.s.HighPart = reply->alloc_high;
839 fsi->AllocationSize.s.LowPart = reply->alloc_low;
840 fsi->EndOfFile.s.HighPart = reply->size_high;
841 fsi->EndOfFile.s.LowPart = reply->size_low;
842 fsi->NumberOfLinks = reply->links;
843 fsi->DeletePending = FALSE; /* FIXME */
844 fsi->Directory = (reply->attr & FILE_ATTRIBUTE_DIRECTORY);
847 else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
853 case FilePositionInformation:
855 FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
856 if (sizeof(answer) < sizeof(*fpi)) goto too_small;
858 SERVER_START_REQ( set_file_pointer )
863 req->whence = SEEK_CUR;
864 if (!(status = wine_server_call( req )))
866 fpi->CurrentByteOffset.s.HighPart = reply->new_high;
867 fpi->CurrentByteOffset.s.LowPart = reply->new_low;
875 FIXME("Unsupported class (%d)\n", class);
876 return io_status->u.Status = STATUS_NOT_IMPLEMENTED;
878 if (used) memcpy(ptr, answer, min(used, len));
879 io_status->u.Status = status;
880 io_status->Information = len;
883 io_status->Information = 0;
884 return io_status->u.Status = STATUS_BUFFER_TOO_SMALL;
887 /******************************************************************************
888 * NtSetInformationFile [NTDLL.@]
889 * ZwSetInformationFile [NTDLL.@]
891 * Set information about an open file handle.
894 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
895 * IoStatusBlock [O] Receives information about the operation on return
896 * FileInformation [I] Source for file information
897 * Length [I] Size of FileInformation
898 * FileInformationClass [I] Type of file information to set
901 * Success: 0. IoStatusBlock is updated.
902 * Failure: An NTSTATUS error code describing the error.
904 NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
905 PVOID ptr, ULONG len,
906 FILE_INFORMATION_CLASS class)
908 NTSTATUS status = STATUS_INVALID_PARAMETER_3;
910 TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
914 case FilePositionInformation:
915 if (len >= sizeof(FILE_POSITION_INFORMATION))
917 FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr;
919 SERVER_START_REQ( set_file_pointer )
922 req->low = fpi->CurrentByteOffset.s.LowPart;
923 req->high = fpi->CurrentByteOffset.s.HighPart;
924 req->whence = SEEK_SET;
925 status = wine_server_call( req );
928 status = STATUS_SUCCESS;
932 FIXME("Unsupported class (%d)\n", class);
933 return STATUS_NOT_IMPLEMENTED;
935 io_status->u.Status = status;
936 io_status->Information = 0;
940 /******************************************************************************
941 * NtQueryDirectoryFile [NTDLL.@]
942 * ZwQueryDirectoryFile [NTDLL.@]
944 NTSTATUS WINAPI NtQueryDirectoryFile(
945 IN HANDLE FileHandle,
946 IN HANDLE Event OPTIONAL,
947 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
948 IN PVOID ApcContext OPTIONAL,
949 OUT PIO_STATUS_BLOCK IoStatusBlock,
950 OUT PVOID FileInformation,
952 IN FILE_INFORMATION_CLASS FileInformationClass,
953 IN BOOLEAN ReturnSingleEntry,
954 IN PUNICODE_STRING FileName OPTIONAL,
955 IN BOOLEAN RestartScan)
957 FIXME("(%p %p %p %p %p %p 0x%08lx 0x%08x 0x%08x %p 0x%08x\n",
958 FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
959 Length, FileInformationClass, ReturnSingleEntry,
960 debugstr_us(FileName),RestartScan);
964 /******************************************************************************
965 * NtQueryVolumeInformationFile [NTDLL.@]
966 * ZwQueryVolumeInformationFile [NTDLL.@]
968 * Get volume information for an open file handle.
971 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
972 * IoStatusBlock [O] Receives information about the operation on return
973 * FsInformation [O] Destination for volume information
974 * Length [I] Size of FsInformation
975 * FsInformationClass [I] Type of volume information to set
978 * Success: 0. IoStatusBlock and FsInformation are updated.
979 * Failure: An NTSTATUS error code describing the error.
981 NTSTATUS WINAPI NtQueryVolumeInformationFile (
982 IN HANDLE FileHandle,
983 OUT PIO_STATUS_BLOCK IoStatusBlock,
984 OUT PVOID FSInformation,
986 IN FS_INFORMATION_CLASS FSInformationClass)
990 FIXME("(%p %p %p 0x%08lx 0x%08x) stub!\n",
991 FileHandle, IoStatusBlock, FSInformation, Length, FSInformationClass);
993 switch ( FSInformationClass )
995 case FileFsVolumeInformation:
996 len = sizeof( FILE_FS_VOLUME_INFORMATION );
998 case FileFsLabelInformation:
1002 case FileFsSizeInformation:
1003 len = sizeof( FILE_FS_SIZE_INFORMATION );
1006 case FileFsDeviceInformation:
1007 len = sizeof( FILE_FS_DEVICE_INFORMATION );
1009 case FileFsAttributeInformation:
1010 len = sizeof( FILE_FS_ATTRIBUTE_INFORMATION );
1013 case FileFsControlInformation:
1017 case FileFsFullSizeInformation:
1021 case FileFsObjectIdInformation:
1025 case FileFsMaximumInformation:
1031 return STATUS_BUFFER_TOO_SMALL;
1033 switch ( FSInformationClass )
1035 case FileFsVolumeInformation:
1037 case FileFsLabelInformation:
1040 case FileFsSizeInformation:
1043 case FileFsDeviceInformation:
1046 FILE_FS_DEVICE_INFORMATION * DeviceInfo = FSInformation;
1047 DeviceInfo->DeviceType = FILE_DEVICE_DISK;
1048 DeviceInfo->Characteristics = 0;
1051 case FileFsAttributeInformation:
1054 case FileFsControlInformation:
1057 case FileFsFullSizeInformation:
1060 case FileFsObjectIdInformation:
1063 case FileFsMaximumInformation:
1066 IoStatusBlock->u.Status = STATUS_SUCCESS;
1067 IoStatusBlock->Information = len;
1068 return STATUS_SUCCESS;
1071 /******************************************************************
1072 * NtFlushBuffersFile (NTDLL.@)
1074 * Flush any buffered data on an open file handle.
1077 * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
1078 * IoStatusBlock [O] Receives information about the operation on return
1081 * Success: 0. IoStatusBlock is updated.
1082 * Failure: An NTSTATUS error code describing the error.
1084 NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock )
1087 HANDLE hEvent = NULL;
1089 SERVER_START_REQ( flush_file )
1091 req->handle = hFile;
1092 ret = wine_server_call( req );
1093 hEvent = reply->event;
1098 ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
1104 /******************************************************************
1105 * NtLockFile (NTDLL.@)
1109 NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event,
1110 PIO_APC_ROUTINE apc, void* apc_user,
1111 PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset,
1112 PLARGE_INTEGER count, ULONG* key, BOOLEAN dont_wait,
1119 if (apc || io_status || key)
1121 FIXME("Unimplemented yet parameter\n");
1122 return STATUS_NOT_IMPLEMENTED;
1127 SERVER_START_REQ( lock_file )
1129 req->handle = hFile;
1130 req->offset_low = offset->s.LowPart;
1131 req->offset_high = offset->s.HighPart;
1132 req->count_low = count->s.LowPart;
1133 req->count_high = count->s.HighPart;
1134 req->shared = !exclusive;
1135 req->wait = !dont_wait;
1136 ret = wine_server_call( req );
1137 handle = reply->handle;
1138 async = reply->overlapped;
1141 if (ret != STATUS_PENDING)
1143 if (!ret && lock_granted_event) NtSetEvent(lock_granted_event, NULL);
1149 FIXME( "Async I/O lock wait not implemented, might deadlock\n" );
1150 if (handle) NtClose( handle );
1151 return STATUS_PENDING;
1155 NtWaitForSingleObject( handle, FALSE, NULL );
1162 /* Unix lock conflict, sleep a bit and retry */
1163 time.QuadPart = 100 * (ULONGLONG)10000;
1164 time.QuadPart = -time.QuadPart;
1165 NtDelayExecution( FALSE, &time );
1171 /******************************************************************
1172 * NtUnlockFile (NTDLL.@)
1176 NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status,
1177 PLARGE_INTEGER offset, PLARGE_INTEGER count,
1182 TRACE( "%p %lx%08lx %lx%08lx\n",
1183 hFile, offset->s.HighPart, offset->s.LowPart, count->s.HighPart, count->s.LowPart );
1185 if (io_status || key)
1187 FIXME("Unimplemented yet parameter\n");
1188 return STATUS_NOT_IMPLEMENTED;
1191 SERVER_START_REQ( unlock_file )
1193 req->handle = hFile;
1194 req->offset_low = offset->s.LowPart;
1195 req->offset_high = offset->s.HighPart;
1196 req->count_low = count->s.LowPart;
1197 req->count_high = count->s.HighPart;
1198 status = wine_server_call( req );