/* * Copyright 1999, 2000 Juergen Schmied * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" #include "wine/port.h" #include #include #include #include #include "ntstatus.h" #define WIN32_NO_STATUS #define NONAMELESSUNION #include "wine/debug.h" #include "wine/server.h" #include "ntdll_misc.h" #include "winternl.h" #include "winioctl.h" #include "ddk/ntddk.h" #include "ddk/ntddser.h" #define WINE_MOUNTMGR_EXTENSIONS #include "ddk/mountmgr.h" WINE_DEFAULT_DEBUG_CHANNEL(ntdll); /************************************************************************** * NtOpenFile [NTDLL.@] * ZwOpenFile [NTDLL.@] * * Open a file. * * PARAMS * handle [O] Variable that receives the file handle on return * access [I] Access desired by the caller to the file * attr [I] Structure describing the file to be opened * io [O] Receives details about the result of the operation * sharing [I] Type of shared access the caller requires * options [I] Options for the file open * * RETURNS * Success: 0. FileHandle and IoStatusBlock are updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtOpenFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io, ULONG sharing, ULONG options ) { return unix_funcs->NtOpenFile( handle, access, attr, io, sharing, options ); } /************************************************************************** * NtCreateFile [NTDLL.@] * ZwCreateFile [NTDLL.@] * * Either create a new file or directory, or open an existing file, device, * directory or volume. * * PARAMS * handle [O] Points to a variable which receives the file handle on return * access [I] Desired access to the file * attr [I] Structure describing the file * io [O] Receives information about the operation on return * alloc_size [I] Initial size of the file in bytes * attributes [I] Attributes to create the file with * sharing [I] Type of shared access the caller would like to the file * disposition [I] Specifies what to do, depending on whether the file already exists * options [I] Options for creating a new file * ea_buffer [I] Pointer to an extended attributes buffer * ea_length [I] Length of ea_buffer * * RETURNS * Success: 0. handle and io are updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io, PLARGE_INTEGER alloc_size, ULONG attributes, ULONG sharing, ULONG disposition, ULONG options, PVOID ea_buffer, ULONG ea_length ) { return unix_funcs->NtCreateFile( handle, access, attr, io, alloc_size, attributes, sharing, disposition, options, ea_buffer, ea_length ); } /****************************************************************************** * NtReadFile [NTDLL.@] * ZwReadFile [NTDLL.@] * * Read from an open file handle. * * PARAMS * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * Event [I] Event to signal upon completion (or NULL) * ApcRoutine [I] Callback to call upon completion (or NULL) * ApcContext [I] Context for ApcRoutine (or NULL) * IoStatusBlock [O] Receives information about the operation on return * Buffer [O] Destination for the data read * Length [I] Size of Buffer * ByteOffset [O] Destination for the new file pointer position (or NULL) * Key [O] Function unknown (may be NULL) * * RETURNS * Success: 0. IoStatusBlock is updated, and the Information member contains * The number of bytes read. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, void* buffer, ULONG length, PLARGE_INTEGER offset, PULONG key) { return unix_funcs->NtReadFile( hFile, hEvent, apc, apc_user, io_status, buffer, length, offset, key ); } /****************************************************************************** * NtReadFileScatter [NTDLL.@] * ZwReadFileScatter [NTDLL.@] */ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, PIO_STATUS_BLOCK io_status, FILE_SEGMENT_ELEMENT *segments, ULONG length, PLARGE_INTEGER offset, PULONG key ) { return unix_funcs->NtReadFileScatter( file, event, apc, apc_user, io_status, segments, length, offset, key ); } /****************************************************************************** * NtWriteFile [NTDLL.@] * ZwWriteFile [NTDLL.@] * * Write to an open file handle. * * PARAMS * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * Event [I] Event to signal upon completion (or NULL) * ApcRoutine [I] Callback to call upon completion (or NULL) * ApcContext [I] Context for ApcRoutine (or NULL) * IoStatusBlock [O] Receives information about the operation on return * Buffer [I] Source for the data to write * Length [I] Size of Buffer * ByteOffset [O] Destination for the new file pointer position (or NULL) * Key [O] Function unknown (may be NULL) * * RETURNS * Success: 0. IoStatusBlock is updated, and the Information member contains * The number of bytes written. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, const void* buffer, ULONG length, PLARGE_INTEGER offset, PULONG key) { return unix_funcs->NtWriteFile( hFile, hEvent, apc, apc_user, io_status, buffer, length, offset, key ); } /****************************************************************************** * NtWriteFileGather [NTDLL.@] * ZwWriteFileGather [NTDLL.@] */ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, PIO_STATUS_BLOCK io_status, FILE_SEGMENT_ELEMENT *segments, ULONG length, PLARGE_INTEGER offset, PULONG key ) { return unix_funcs->NtWriteFileGather( file, event, apc, apc_user, io_status, segments, length, offset, key ); } /************************************************************************** * NtDeviceIoControlFile [NTDLL.@] * ZwDeviceIoControlFile [NTDLL.@] * * Perform an I/O control operation on an open file handle. * * PARAMS * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * event [I] Event to signal upon completion (or NULL) * apc [I] Callback to call upon completion (or NULL) * apc_context [I] Context for ApcRoutine (or NULL) * io [O] Receives information about the operation on return * code [I] Control code for the operation to perform * in_buffer [I] Source for any input data required (or NULL) * in_size [I] Size of InputBuffer * out_buffer [O] Source for any output data returned (or NULL) * out_size [I] Size of OutputBuffer * * RETURNS * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size) { return unix_funcs->NtDeviceIoControlFile( handle, event, apc, apc_context, io, code, in_buffer, in_size, out_buffer, out_size ); } /************************************************************************** * NtFsControlFile [NTDLL.@] * ZwFsControlFile [NTDLL.@] * * Perform a file system control operation on an open file handle. * * PARAMS * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * event [I] Event to signal upon completion (or NULL) * apc [I] Callback to call upon completion (or NULL) * apc_context [I] Context for ApcRoutine (or NULL) * io [O] Receives information about the operation on return * code [I] Control code for the operation to perform * in_buffer [I] Source for any input data required (or NULL) * in_size [I] Size of InputBuffer * out_buffer [O] Source for any output data returned (or NULL) * out_size [I] Size of OutputBuffer * * RETURNS * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size) { return unix_funcs->NtFsControlFile( handle, event, apc, apc_context, io, code, in_buffer, in_size, out_buffer, out_size ); } /****************************************************************************** * NtNotifyChangeDirectoryFile [NTDLL.@] */ NTSTATUS WINAPI NtNotifyChangeDirectoryFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_context, PIO_STATUS_BLOCK iosb, void *buffer, ULONG buffer_size, ULONG filter, BOOLEAN subtree ) { return unix_funcs->NtNotifyChangeDirectoryFile( handle, event, apc, apc_context, iosb, buffer, buffer_size, filter, subtree ); } /****************************************************************************** * NtSetVolumeInformationFile [NTDLL.@] * ZwSetVolumeInformationFile [NTDLL.@] */ NTSTATUS WINAPI NtSetVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, void *info, ULONG length, FS_INFORMATION_CLASS class ) { return unix_funcs->NtSetVolumeInformationFile( handle, io, info, length, class ); } NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) { data_size_t size = 1024; NTSTATUS ret; char *name; for (;;) { name = RtlAllocateHeap( GetProcessHeap(), 0, size + 1 ); if (!name) return STATUS_NO_MEMORY; unix_name->MaximumLength = size + 1; SERVER_START_REQ( get_handle_unix_name ) { req->handle = wine_server_obj_handle( handle ); wine_server_set_reply( req, name, size ); ret = wine_server_call( req ); size = reply->name_len; } SERVER_END_REQ; if (!ret) { name[size] = 0; unix_name->Buffer = name; unix_name->Length = size; break; } RtlFreeHeap( GetProcessHeap(), 0, name ); if (ret != STATUS_BUFFER_OVERFLOW) break; } return ret; } /****************************************************************************** * NtQueryInformationFile [NTDLL.@] * ZwQueryInformationFile [NTDLL.@] * * Get information about an open file handle. * * PARAMS * hFile [I] Handle returned from ZwOpenFile() or ZwCreateFile() * io [O] Receives information about the operation on return * ptr [O] Destination for file information * len [I] Size of FileInformation * class [I] Type of file information to get * * RETURNS * Success: 0. IoStatusBlock and FileInformation are updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, LONG len, FILE_INFORMATION_CLASS class ) { return unix_funcs->NtQueryInformationFile( hFile, io, ptr, len, class ); } /****************************************************************************** * NtSetInformationFile [NTDLL.@] * ZwSetInformationFile [NTDLL.@] * * Set information about an open file handle. * * PARAMS * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * io [O] Receives information about the operation on return * ptr [I] Source for file information * len [I] Size of FileInformation * class [I] Type of file information to set * * RETURNS * Success: 0. io is updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class) { return unix_funcs->NtSetInformationFile( handle, io, ptr, len, class ); } /****************************************************************************** * NtQueryFullAttributesFile (NTDLL.@) */ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_NETWORK_OPEN_INFORMATION *info ) { return unix_funcs->NtQueryFullAttributesFile( attr, info ); } /****************************************************************************** * NtQueryAttributesFile (NTDLL.@) * ZwQueryAttributesFile (NTDLL.@) */ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info ) { return unix_funcs->NtQueryAttributesFile( attr, info ); } /****************************************************************************** * NtQueryVolumeInformationFile [NTDLL.@] * ZwQueryVolumeInformationFile [NTDLL.@] * * Get volume information for an open file handle. * * PARAMS * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * io [O] Receives information about the operation on return * buffer [O] Destination for volume information * length [I] Size of FsInformation * info_class [I] Type of volume information to set * * RETURNS * Success: 0. io and buffer are updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io, PVOID buffer, ULONG length, FS_INFORMATION_CLASS info_class ) { return unix_funcs->NtQueryVolumeInformationFile( handle, io, buffer, length, info_class ); } /****************************************************************** * NtQueryEaFile (NTDLL.@) * * Read extended attributes from NTFS files. * * PARAMS * hFile [I] File handle, must be opened with FILE_READ_EA access * iosb [O] Receives information about the operation on return * buffer [O] Output buffer * length [I] Length of output buffer * single_entry [I] Only read and return one entry * ea_list [I] Optional list with names of EAs to return * ea_list_len [I] Length of ea_list in bytes * ea_index [I] Optional pointer to 1-based index of attribute to return * restart [I] restart EA scan * * RETURNS * Success: 0. Attributes read into buffer * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtQueryEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, ULONG length, BOOLEAN single_entry, PVOID ea_list, ULONG ea_list_len, PULONG ea_index, BOOLEAN restart ) { FIXME("(%p,%p,%p,%d,%d,%p,%d,%p,%d) stub\n", hFile, iosb, buffer, length, single_entry, ea_list, ea_list_len, ea_index, restart); return STATUS_ACCESS_DENIED; } /****************************************************************** * NtSetEaFile (NTDLL.@) * * Update extended attributes for NTFS files. * * PARAMS * hFile [I] File handle, must be opened with FILE_READ_EA access * iosb [O] Receives information about the operation on return * buffer [I] Buffer with EA information * length [I] Length of buffer * * RETURNS * Success: 0. Attributes are updated * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtSetEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, ULONG length ) { FIXME("(%p,%p,%p,%d) stub\n", hFile, iosb, buffer, length); return STATUS_ACCESS_DENIED; } /****************************************************************** * NtFlushBuffersFile (NTDLL.@) * * Flush any buffered data on an open file handle. * * PARAMS * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * IoStatusBlock [O] Receives information about the operation on return * * RETURNS * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK *io ) { return unix_funcs->NtFlushBuffersFile( hFile, io ); } /****************************************************************** * NtLockFile (NTDLL.@) * * */ NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event, PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset, PLARGE_INTEGER count, ULONG* key, BOOLEAN dont_wait, BOOLEAN exclusive ) { NTSTATUS ret; HANDLE handle; BOOLEAN async; static BOOLEAN warn = TRUE; if (apc || io_status || key) { FIXME("Unimplemented yet parameter\n"); return STATUS_NOT_IMPLEMENTED; } if (apc_user && warn) { FIXME("I/O completion on lock not implemented yet\n"); warn = FALSE; } for (;;) { SERVER_START_REQ( lock_file ) { req->handle = wine_server_obj_handle( hFile ); req->offset = offset->QuadPart; req->count = count->QuadPart; req->shared = !exclusive; req->wait = !dont_wait; ret = wine_server_call( req ); handle = wine_server_ptr_handle( reply->handle ); async = reply->overlapped; } SERVER_END_REQ; if (ret != STATUS_PENDING) { if (!ret && lock_granted_event) NtSetEvent(lock_granted_event, NULL); return ret; } if (async) { FIXME( "Async I/O lock wait not implemented, might deadlock\n" ); if (handle) NtClose( handle ); return STATUS_PENDING; } if (handle) { NtWaitForSingleObject( handle, FALSE, NULL ); NtClose( handle ); } else { LARGE_INTEGER time; /* Unix lock conflict, sleep a bit and retry */ time.QuadPart = 100 * (ULONGLONG)10000; time.QuadPart = -time.QuadPart; NtDelayExecution( FALSE, &time ); } } } /****************************************************************** * NtUnlockFile (NTDLL.@) * * */ NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset, PLARGE_INTEGER count, PULONG key ) { NTSTATUS status; TRACE( "%p %x%08x %x%08x\n", hFile, offset->u.HighPart, offset->u.LowPart, count->u.HighPart, count->u.LowPart ); if (io_status || key) { FIXME("Unimplemented yet parameter\n"); return STATUS_NOT_IMPLEMENTED; } SERVER_START_REQ( unlock_file ) { req->handle = wine_server_obj_handle( hFile ); req->offset = offset->QuadPart; req->count = count->QuadPart; status = wine_server_call( req ); } SERVER_END_REQ; return status; } /****************************************************************** * NtCreateNamedPipeFile (NTDLL.@) */ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK iosb, ULONG sharing, ULONG dispo, ULONG options, ULONG pipe_type, ULONG read_mode, ULONG completion_mode, ULONG max_inst, ULONG inbound_quota, ULONG outbound_quota, PLARGE_INTEGER timeout) { return unix_funcs->NtCreateNamedPipeFile( handle, access, attr, iosb, sharing, dispo, options, pipe_type, read_mode, completion_mode, max_inst, inbound_quota, outbound_quota, timeout ); } /****************************************************************** * NtDeleteFile (NTDLL.@) */ NTSTATUS WINAPI NtDeleteFile( OBJECT_ATTRIBUTES *attr ) { return unix_funcs->NtDeleteFile( attr ); } /****************************************************************** * NtCancelIoFileEx (NTDLL.@) * * */ NTSTATUS WINAPI NtCancelIoFileEx( HANDLE hFile, PIO_STATUS_BLOCK iosb, PIO_STATUS_BLOCK io_status ) { TRACE("%p %p %p\n", hFile, iosb, io_status ); SERVER_START_REQ( cancel_async ) { req->handle = wine_server_obj_handle( hFile ); req->iosb = wine_server_client_ptr( iosb ); req->only_thread = FALSE; io_status->u.Status = wine_server_call( req ); } SERVER_END_REQ; return io_status->u.Status; } /****************************************************************** * NtCancelIoFile (NTDLL.@) * * */ NTSTATUS WINAPI NtCancelIoFile( HANDLE hFile, PIO_STATUS_BLOCK io_status ) { TRACE("%p %p\n", hFile, io_status ); SERVER_START_REQ( cancel_async ) { req->handle = wine_server_obj_handle( hFile ); req->iosb = 0; req->only_thread = TRUE; io_status->u.Status = wine_server_call( req ); } SERVER_END_REQ; return io_status->u.Status; } /****************************************************************************** * NtCreateMailslotFile [NTDLL.@] * ZwCreateMailslotFile [NTDLL.@] */ NTSTATUS WINAPI NtCreateMailslotFile( HANDLE *handle, ULONG access, OBJECT_ATTRIBUTES *attr, IO_STATUS_BLOCK *io, ULONG options, ULONG quota, ULONG msg_size, LARGE_INTEGER *timeout ) { return unix_funcs->NtCreateMailslotFile( handle, access, attr, io, options, quota, msg_size, timeout ); }