/* Editor Settings: expandtabs and use 4 spaces for indentation
 * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
 * -*- mode: c, c-basic-offset: 4 -*- */

/*
 * Copyright Likewise Software
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program 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 General Public License
 * for more details.  You should have received a copy of the GNU General
 * Public License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
 * TERMS AS WELL.  IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
 * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
 * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
 * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE.  IF YOU
 * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
 * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
 * license@likewisesoftware.com
 */

/*
 * Copyright (C) Likewise Software. All rights reserved.
 *
 * Module Name:
 *
 *        ioapi.h
 *
 * Abstract:
 *
 *        IO Manager File API
 *
 * Authors: Danilo Almeida (dalmeida@likewisesoftware.com)
 */

#ifndef __IO_API_H__
#define __IO_API_H__

/**
 * @file lwio/ioapi.h
 * @brief Likewise Iomgr API
 */

#include <lwio/io-types.h>
#include <lwio/lwzct.h>

LW_BEGIN_EXTERN_C

/**
 * @defgroup ioapi Iomgr API
 * @ingroup server
 * @brief Iomgr API
 *
 * The Iomgr API allows making calls directly into the Likewise I/O Manager subsystem.
 */

/*@{*/

/**
 * @name I/O Flags
 */

/**@{*/

/**
 * @brief I/O Flags
 *
 * Additional flags controlling behavior of individual I/O operations.
 */
typedef ULONG IO_FLAGS;

/**
 * @brief I/O Flags pointer
 *
 * Pointer to an #IO_FLAGS.
 */
typedef IO_FLAGS* PIO_FLAGS;

/**
 * @brief Paging I/O flag (#IO_FLAGS)
 *
 * Indicates that a read operation is to satisfy a fault on an executable
 * page for a program or library.  This permits reading from file handles
 * for which only FILE_EXECUTE was granted.
 * @hideinitializer
 */
#define IO_FLAG_PAGING_IO           0x00000001
#ifndef DOXYGEN
// no access check is not yet valid.
#define IO_FLAG_NO_ACCESS_CHECK     0x00000002
#endif
/**
 * @brief Write through flag (#IO_FLAGS)
 *
 * Indicates that a write operation should not complete until the
 * write is stable (e.g. it has been flushed to permanent physical
 * storage such as a hard disk).
 * @hideinitializer
 */
// The write operation should not return until write is stable.
#define IO_FLAG_WRITE_THROUGH       0x00000004

/**
 * @brief Valid I/O flags (#IO_FLAGS)
 *
 * A mask of all valid #IO_FLAGS
 * @hideinitializer
 */
#define IO_FLAGS_VALID_MASK ( \
    IO_FLAG_PAGING_IO | \
    IO_FLAG_NO_ACCESS_CHECK | \
    IO_FLAG_WRITE_THROUGH | \
    0 )

/**@}*/

/**
 * @name Asynchronous I/O Support
 *
 * Asynchronous support functions.  See #IO_ASYNC_CONTROL_BLOCK for details
 * on the life cycle of async operations.
 **/

/**@{*/

/**
 * @brief Cancel asynchronous operation
 *
 * Cancels an outstanding asynchronous operation.  A canceled operation
 * is required to complete as quickly as possible, which may include
 * aborting the operation entirely and completing with @a
 * LW_STATUS_CANCELLED.
 *
 * The cancel context must still be released with #IoDereferenceAsyncCancelContext().
 *
 * @param[in] AsyncCancelContext The async cancel context for the operation to cancel.
 *
 * @retval TRUE  The operation was cancellable and cancellation was requested.
 * @retval FALSE The operation could not be canceled.
 */
BOOLEAN
IoCancelAsyncCancelContext(
    IN PIO_ASYNC_CANCEL_CONTEXT AsyncCancelContext
    );

/**
 * @brief Release async cancel context
 *
 * Releases the async cancel context handle for an operation.
 *
 * @param[in,out] AsyncCancelContext The async cancel context.
 */
VOID
IoDereferenceAsyncCancelContext(
    IN OUT PIO_ASYNC_CANCEL_CONTEXT* AsyncCancelContext
    );

/**@}*/

/**
 * @name Core I/O Operations
 */

/**@{*/

/**
 * @brief Create or open file
 *
 * Creates or opens a file.
 *
 * @param[out]    FileHandle               Set to the created file handle on completion.
 * @param[in,out] AsyncControlBlock        Optional async control block.  If specified,
 *                                         @a LW_STATUS_PENDING may be returned and
 *                                         @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock            Filled with result information on completion.
 * @param[in]     SecurityContext          The security context of the caller.
 * @param[in]     FileName                 The file path to create or open.
 * @param[in]     SecurityDescriptor       An optional initial security descriptor.  This is
 *                                         only effective if the file is created or superseded.
 * @param[in]     SecurityQualityOfService Currently unused.  Must be @a NULL.
 * @param[in]     DesiredAccess            A mask of desired access bits.
 * @param[in]     AllocationSize           An optional allocation size, or @a 0.  This is only effective
 *                                         if the file is created or superseded.
 * @param[in]     FileAttributes           A mask of attributes for the created or opened file.
 * @param[in]     ShareAccess              A mask of share access flags.
 * @param[in]     CreateDisposition        The type of create to perform.
 * @param[in]     CreateOptions            A mask of additional create options.
 * @param[in]     EaBuffer                 An optional @a PFILE_FULL_EA_INFORMATION specifying initial EAs.
 *                                         This is only effective if the file is created or superseded.
 * @param[in]     EaLength                 The length of @a EaBuffer, or 0.
 * @param[in]     EcpList                  An optional list of extended create parameters.
 *
 * @retval LW_STATUS_SUCCESS               Success.
 * @retval LW_STATUS_PENDING               The operation will be completed asynchronously by
 *                                         invoking @a AsyncControlBlock->Callback.  The final result
 *                                         status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_OBJECT_PATH_NOT_FOUND A leading path element in @a FileName did
 *                                         not exist.
 * @retval LW_STATUS_OBJECT_NAME_NOT_FOUND The specified file did not exist.
 * @retval LW_STATUS_ACCESS_DENIED         The calling user was denied one or more of the desired
 *                                         access bits.  This will not be returned if @a DesiredAccess
 *                                         contained only MAXIMUM_ALLOWED.
 * @retval LW_STATUS_SHARING_VIOLATION     The given @a ShareAccess flags or those of another
 *                                         open handle did not permit concurrent access to the
 *                                         file with the requested access mask.
 * @retval LW_STATUS_NOT_A_DIRECTORY       @a CreateOptions contained #FILE_DIRECTORY_FILE but
 *                                         the specified path existed and was not a directory.
 * @retval LW_STATUS_FILE_IS_A_DIRECTORY   @a CreateOptions contained #FILE_NON_DIRECTORY_FILE but
 *                                         the specified path existed and was a directory.
 * @retval LW_STATUS_DELETE_PENDING        The file could not be opened because it is pending deletion.
 * @retval ...                             Error.
 */
NTSTATUS
IoCreateFile(
    OUT PIO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_CREATE_SECURITY_CONTEXT SecurityContext,
    IN PIO_FILE_NAME FileName,
    IN OPTIONAL PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
    IN OPTIONAL PVOID SecurityQualityOfService, // TBD
    IN ACCESS_MASK DesiredAccess,
    IN OPTIONAL LONG64 AllocationSize,
    IN FILE_ATTRIBUTES FileAttributes,
    IN FILE_SHARE_FLAGS ShareAccess,
    IN FILE_CREATE_DISPOSITION CreateDisposition,
    IN FILE_CREATE_OPTIONS CreateOptions,
    IN OPTIONAL PVOID EaBuffer, // PFILE_FULL_EA_INFORMATION
    IN ULONG EaLength,
    IN OPTIONAL PIO_ECP_LIST EcpList
    );

/**
 * @brief Retain file handle
 *
 * Increments the reference count of a file handle.
 *
 * @param[in,out] FileHandle The file handle.
 */
VOID
IoRetainFile(
    IN OUT IO_FILE_HANDLE FileHandle
    );

/**
 * @brief Release file handle
 *
 * Decrements the reference count of a file handle.
 * This must not release the final reference if the file handle
 * has not been run down or closed.
 *
 * @param[in,out] FileHandle The file handle.
 */
VOID
IoReleaseFile(
    IN OUT IO_FILE_HANDLE FileHandle
    );

/**
 * @brief Cancel file handle
 *
 * Cancels all outstanding operations on the given handle.
 *
 * @param[in,out] FileHandle The file handle.
 */
VOID
IoCancelFile(
    IN IO_FILE_HANDLE FileHandle
    );

/**
 * @brief Cancel file handle for rundown
 *
 * Cancels all outstanding operations on the given handle.
 * Attempts at subsequent operations will fail with
 * @a LW_STATUS_CANCELLED.
 *
 * @param[in,out] FileHandle The file handle.
 */
VOID
IoCancelForRundownFile(
    IN IO_FILE_HANDLE FileHandle
    );

/**
 * @brief Run down file handle
 *
 * Runs down a file handle.  This cancels all outstanding operations
 * and instructs the underlying driver to close the file, but does
 * not release the file handle.  The caller must still call #IoCloseFile()
 * or #IoAsyncCloseFile() later.
 *
 * @param[in,out] FileHandle        The file handle.
 * @param[in,out] AsyncControlBlock Optional async control block.  If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 *
 * @retval LW_STATUS_SUCCESS  Success.
 * @retval LW_STATUS_PENDING  The operation will be completed asynchronously by
 *                            invoking @a AsyncControlBlock->Callback.  The final result
 *                            status can be obtained from @a IoStatusBlock->Status.
 */
NTSTATUS
IoRundownFile(
    IN OUT IO_FILE_HANDLE FileHandle,
    IN OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock
    );

/**
 * @brief Close file handle asynchronously
 *
 * Closes a file handle with optional asynchronous behavior.  In addition
 * to all the effects of #IoRundownFile(), the file handle is released.
 *
 * @param[in,out] FileHandle        The file handle.
 * @param[in,out] AsyncControlBlock Optional async control block.  If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 *
 * @retval LW_STATUS_SUCCESS  Success.
 * @retval LW_STATUS_PENDING  The operation will be completed asynchronously by
 *                            invoking @a AsyncControlBlock->Callback.  The final result
 *                            status can be obtained from @a IoStatusBlock->Status.
 */
NTSTATUS
IoAsyncCloseFile(
    IN OUT IO_FILE_HANDLE FileHandle,
    IN OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock
    );

/**
 * @brief Close file handle
 *
 * Closes a file handle.
 *
 * @param[in,out] FileHandle        The file handle.
 */
NTSTATUS
IoCloseFile(
    IN OUT IO_FILE_HANDLE FileHandle
    );

/**
 * @brief Read from file
 *
 * Reads from the specified file handle.
 *
 * @param[in]     FileHandle        The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling read behavior.  The
 *                                  only valid flag is presently #IO_FLAG_PAGING_IO.
 * @param[out]    Buffer            The buffer where the read data should be placed.
 * @param[in]     Length            The number of bytes to read.
 * @param[in]     ByteOffset        An optional byte offset into file from which to read.
 *                                  If not specified, the current file handle position is used.
 * @param[in]     Key               Currently unused.  Must be @a NULL.
 *
 * @retval LW_STATUS_SUCESS             Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_END_OF_FILE        No data was read because the end of the file was reached.
 * @retval LW_STATUS_FILE_LOCK_CONFLICT A conflicting lock prevented the read.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with #FILE_READ_DATA, or if
 *                                      #IO_FLAG_PAGING_IO was specified, #FILE_EXECUTE.
 * @retval ...                          Error.
 */
NTSTATUS
IoReadFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN PVOID Buffer,
    IN ULONG Length,
    IN OPTIONAL PULONG64 ByteOffset,
    IN OPTIONAL PULONG Key
    );

/**
 * @brief Write to file
 *
 * Writes to the specified file handle.
 *
 * @param[in]     FileHandle The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling write behavior.
 * @param[out]    Buffer            The buffer containing data to write.
 * @param[in]     Length            The number of bytes to write.
 * @param[in]     ByteOffset        An optional byte offset into file to which to write.
 *                                  If not specified, the current file handle position is used.
 * @param[in]     Key               Currently unused.  Must be @a NULL.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_DISK_FULL          There was insufficient space on the device containing the file.
 * @retval LW_STATUS_FILE_LOCK_CONFLICT A conflicting lock prevented the write.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with #FILE_WRITE_DATA access.
 * @retval ...                          Error.
 */
NTSTATUS
IoWriteFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN PVOID Buffer,
    IN ULONG Length,
    IN OPTIONAL PULONG64 ByteOffset,
    IN OPTIONAL PULONG Key
    );

/**
 * @brief Send driver-specific control code
 *
 * Sends a control code directly to a driver.
 *
 * @param[in]     FileHandle         A handle to the driver.  This should generally
 *                                   be obtained by using #IoCreateFile() on "/<device>".
 * @param[in,out] AsyncControlBlock  Optional async control block. If specified,
 *                                   @a LW_STATUS_PENDING may be returned and
 *                                   @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock      Filled with result information on completion.
 * @param[in]     IoControlCode      The control code to send.
 * @param[out]    InputBuffer        A buffer containing data to pass to the device.
 * @param[in]     InputBufferLength  The number of bytes to pass to the device.
 * @param[out]    OutputBuffer       A buffer into which output data will be written by the device.
 * @param[in]     OutputBufferLength The length of @a OutputBuffer.
 *
 * @retval LW_STATUS_SUCCESS Success.
 * @retval LW_STATUS_PENDING The operation will be completed asynchronously by
 *                           invoking @a AsyncControlBlock->Callback.  The final result
 *                           status can be obtained from @a IoStatusBlock->Status.
 * @retval ...               Error.
 */
NTSTATUS
IoDeviceIoControlFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG IoControlCode,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength
    );

/**
 * @brief Send filesystem control code
 *
 * Sends a control code to perform an operation on a file, directory,
 * or underlying filesystem.
 *
 * @param[in]     FileHandle         A handle to the driver.  This should generally
 *                                   be obtained by using #IoCreateFile() on "/<device>".
 * @param[in,out] AsyncControlBlock  Optional async control block. If specified,
 *                                   @a LW_STATUS_PENDING may be returned and
 *                                   @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock      Filled with result information on completion.
 * @param[in]     FsControlCode      The control code to send.
 * @param[out]    InputBuffer        A buffer containing data to pass to the device.
 * @param[in]     InputBufferLength  The number of bytes to pass to the device.
 * @param[out]    OutputBuffer       A buffer into which output data will be written by the device.
 * @param[in]     OutputBufferLength The length of @a OutputBuffer.
 *
 * @retval LW_STATUS_SUCCESS Success.
 * @retval LW_STATUS_PENDING The operation will be completed asynchronously by
 *                           invoking @a AsyncControlBlock->Callback.  The final result
 *                           status can be obtained from @a IoStatusBlock->Status.
 * @retval ...               Error.
 */
NTSTATUS
IoFsControlFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG FsControlCode,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength
    );

/**
 * @brief Flush data to stable storage.
 *
 * Flushes all modifications for the given file handle to permanent storage.
 *
 * @param[in]     FileHandle         The file handle.
 * @param[in,out] AsyncControlBlock  Optional async control block. If specified,
 *                                   @a LW_STATUS_PENDING may be returned and
 *                                   @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock      Filled with result information on completion.
 *
 * @retval LW_STATUS_SUCCESS Success.
 * @retval LW_STATUS_PENDING The operation will be completed asynchronously by
 *                           invoking @a AsyncControlBlock->Callback.  The final result
 *                           status can be obtained from @a IoStatusBlock->Status.
 * @retval ...               Error.
 */
NTSTATUS
IoFlushBuffersFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock
    );

/**
 * @brief Query file information
 *
 * Queries for information about a file.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[out]    FileInformation      A buffer which is filled with the requested
 *                                     information.
 * @param[in]     Length               The size of @a FileInformation in bytes.
 * @param[in]     FileInformationClass The type of file information to query.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL   The passed buffer was too small to contain the
 *                                      requested information.
 * @retval LW_STATUS_BUFFER_OVERFLOW    The passed buffer was large enough to contain the fixed
 *                                      portion of the requested info structure, but not the
 *                                      variable-sized trailing portion.
 * @retval LW_STATUS_INVALID_INFO_CLASS The specified information class was invalid.
 * @retval ...                          Error.
 */
NTSTATUS
IoQueryInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
    );

/**
 * @brief Set file information
 *
 * Sets information about a file.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[in]     FileInformation      A buffer which contains the information to set.
 * @param[in]     Length               The size of @a FileInformation in bytes.
 * @param[in]     FileInformationClass The type of file information to query.
 *
 * @retval LW_STATUS_SUCCESS              Success.
 * @retval LW_STATUS_PENDING              The operation will be completed asynchronously by
 *                                        invoking @a AsyncControlBlock->Callback.  The final result
 *                                        status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_INFO_LENGTH_MISMATCH The passed buffer had the wrong length for the specified
 *                                        information class.
 * @retval LW_STATUS_INVALID_INFO_CLASS   The specified information class was invalid.
 * @retval ...                            Error.
 */
NTSTATUS
IoSetInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
    );

/**@}*/

/**
 * @name Additional Operations
 */

/**@{*/

#if 0
NTSTATUS
IoQueryFullAttributesFile(
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FileName,
    OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation
    );
#endif

/**
 * @brief Query directory information
 *
 * Queries information about the entries in a directory.  Repeat calls
 * will continue to return subsequent entries.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[out]    FileInformation      A buffer which is filled with the requested
 *                                     information.
 * @param[in]     Length               The size of @a FileInformation in bytes.
 * @param[in]     FileInformationClass The type of file information to query.
 * @param[in]     ReturnSingleEntry    If @a TRUE, only one entry will be returned.
 * @param[in]     FileSpec             An optional match specification which will constrain
 *                                     the returned entries.
 * @param[in]     RestartScan          Currently unused.  Must be @a FALSE.
 *
 * @retval LW_STATUS_SUCCESS              Success.
 * @retval LW_STATUS_PENDING              The operation will be completed asynchronously by
 *                                        invoking @a AsyncControlBlock->Callback.  The final result
 *                                        status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL     The passed buffer was too small to contain even a single
 *                                        entry of the requested information class.
 * @retval LW_STATUS_INVALID_INFO_CLASS   The specified information class was invalid.
 * @retval LW_STATUS_NO_MORE_ENTRIES      No more entries are available to return.
 * @retval LW_STATUS_NOT_A_DIRECTORY      The specified file was not a directory.
 * @retval ...                            Error.
 */
NTSTATUS
IoQueryDirectoryFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass,
    IN BOOLEAN ReturnSingleEntry,
    IN OPTIONAL PIO_MATCH_FILE_SPEC FileSpec,
    IN BOOLEAN RestartScan
    );

/**
 * @brief Read directory change notifications
 *
 * Reads change notifications for a directory.  If no
 * notifications have occurred since the last read, this
 * operation will wait until notifications become available.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[out]    Buffer               A buffer which is filled with change information.
 * @param[in]     Length               The size of @a Buffer in bytes.
 * @param[in]     WatchTree            If @a TRUE, recursive subdirectories will also be monitored.
 * @param[in]     NotifyFilter         A mask of notification events to watch for.
 * @param[in]     MaxBufferSize        An optional maximum internal buffer size.
 *                                     If specified, this provides a hint for how large an internal
 *                                     notification buffer to maintain for events that occur between
 *                                     reads.
 *
 * @retval LW_STATUS_SUCCESS              Success.
 * @retval LW_STATUS_PENDING              The operation will be completed asynchronously by
 *                                        invoking @a AsyncControlBlock->Callback.  The final result
 *                                        status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL     The passed buffer was too small to contain even a single
 *                                        notification.
 * @retval LW_STATUS_NOT_A_DIRECTORY      The specified file was not a directory.
 * @retval LW_STATUS_NOTIFY_ENUM_DIR      Change notifications have been lost; the application
 *                                        should re-enumerate the directory.
 * @retval ...
 */
NTSTATUS
IoReadDirectoryChangeFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID Buffer,
    IN ULONG Length,
    IN BOOLEAN WatchTree,
    IN FILE_NOTIFY_CHANGE NotifyFilter,
    IN OPTIONAL PULONG MaxBufferSize
    );

/**
 * @brief Common function signature for "Query File Info" and
 *        "Query Volume Info"
 */
typedef NTSTATUS (IO_QUERY_FILE_OR_VOLUME_INFO_FUNC)(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID Information,
    IN ULONG Length,
    IN ULONG InformationClass
    );
typedef IO_QUERY_FILE_OR_VOLUME_INFO_FUNC* PIO_QUERY_FILE_OR_VOLUME_INFO_FUNC;

/**
 * @brief Query volume information
 *
 * Queries for information about the physical volume on which a file resides.
 *
 * @param[in]     FileHandle           A file handle.  It is used only synecdochically to refer
 *                                     to the underlying volume.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[out]    FsInformation        A buffer which is filled with the requested
 *                                     information.
 * @param[in]     Length               The size of @a FsInformation in bytes.
 * @param[in]     FsInformationClass   The type of volume information to query.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL   The passed buffer was too small to contain the
 *                                      requested information.
 * @retval LW_STATUS_BUFFER_OVERFLOW    The passed buffer was large enough to contain the fixed
 *                                      portion of the requested info structure, but not the
 *                                      variable-sized trailing portion.
 * @retval LW_STATUS_INVALID_INFO_CLASS The specified information class was invalid.
 * @retval ...                          Error.
 */
NTSTATUS
IoQueryVolumeInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID FsInformation,
    IN ULONG Length,
    IN FS_INFORMATION_CLASS FsInformationClass
    );

/**
 * @brief Set volume information
 *
 * Sets information about the physical volume on which a file resides.
 *
 * @param[in]     FileHandle           A file handle.  It is used only synecdochically to refer
 *                                     to the underlying volume.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[in]     FsInformation        A buffer which is filled with the requested
 *                                     information.
 * @param[in]     Length               The size of @a FsInformation in bytes.
 * @param[in]     FsInformationClass   The type of volume information to query.
 *
 * @retval LW_STATUS_SUCCESS              Success.
 * @retval LW_STATUS_PENDING              The operation will be completed asynchronously by
 *                                        invoking @a AsyncControlBlock->Callback.  The final result
 *                                        status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_INFO_LENGTH_MISMATCH The passed buffer had the wrong length for the specified
 *                                        information class.
 * @retval LW_STATUS_INVALID_INFO_CLASS   The specified information class was invalid.
 * @retval ...                            Error.
 */
NTSTATUS
IoSetVolumeInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID FsInformation,
    IN ULONG Length,
    IN FS_INFORMATION_CLASS FsInformationClass
    );

/**
 * @brief Lock file region
 *
 * Locks a region within a file.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[in]     ByteOffset           The offset within the file of the region to lock.
 * @param[in]     Length               The length of the region.
 * @param[in]     Key                  Currently unused.  Must be @a 0.
 * @param[in]     FailImmediately      If @a TRUE, a conflicting lock will cause the operation
 *                                     to fail immediately rather than waiting for it to be
 *                                     unlocked.
 * @param[in]     ExclusiveLock        If @a TRUE, the lock is exclusive.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_INVALID_LOCK_RANGE The specified range is invalid.
 * @retval LW_STATUS_LOCK_NOT_GRANTED   The lock could not be granted due to a conflict.
 * @retval ...                          Error.
 */
NTSTATUS
IoLockFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG64 ByteOffset,
    IN ULONG64 Length,
    IN ULONG Key,
    IN BOOLEAN FailImmediately,
    IN BOOLEAN ExclusiveLock
    );

/**
 * @brief Unlock file region
 *
 * Unlocks a region within a file.
 *
 * @param[in]     FileHandle           The file handle.
 * @param[in,out] AsyncControlBlock    Optional async control block. If specified,
 *                                     @a LW_STATUS_PENDING may be returned and
 *                                     @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock        Filled with result information on completion.
 * @param[in]     ByteOffset           The offset within the file of the region to lock.
 * @param[in]     Length               The length of the region.
 * @param[in]     Key                  Currently unused.  Must be @a 0.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_INVALID_LOCK_RANGE The specified range is invalid.
 * @retval LW_STATUS_RANGE_NOT_LOCKED   The specified range did not contain a lock.
 * @retval ...                          Error.
 */
NTSTATUS
IoUnlockFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG64 ByteOffset,
    IN ULONG64 Length,
    IN ULONG Key
    );

/**@}*/

//
// Namespace Operations
//
// These are in flux due NT vs POSIX issues.
//

#if 0
NTSTATUS
IoRemoveDirectoryFile(
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FileName
    );

NTSTATUS
IoDeleteFile(
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FileName
    );

NTSTATUS
IoLinkFile(
    IN PIO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME LinkName
    );

NTSTATUS
IoRenameFile(
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FromName,
    IN PIO_FILE_NAME ToName
    );
#endif

/**
 * @name Advanced Operations
 */

/**@{*/

/**
 * @brief Query file extended attributes.
 *
 * Queries extended attributes for a file.  Repeat calls will
 * return further results.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[out]    Buffer              A buffer which is filled with requests EAs.
 * @param[in]     Length              The length of @a Buffer.
 * @param[in]     ReturnSingleEntry   Currently unused.  Must be @a FALSE.
 * @param[in]     EaList              A list of EAs to query.  If @a NULL, all EAs are queried.
 * @param[in]     EaListLength        The length of @a EaList, or @a 0.
 * @param[in]     EaIndex             Currently unused.  Must be @a NULL.
 * @param[in]     RestartScan         Current unused.  Must be @a FALSE.
 *
 * @retval LW_STATUS_SUCCESS              Success.
 * @retval LW_STATUS_PENDING              The operation will be completed asynchronously by
 *                                        invoking @a AsyncControlBlock->Callback.  The final result
 *                                        status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL     The passed buffer was too small to contain the
 *                                        requested information.
 * @retval LW_STATUS_EA_LIST_INCONSISTENT The EA list was malformed.
 * @retval LW_STATUS_INVALID_EA_NAME      The EA list contained an invalid EA name.
 * @retval ...                            Error.
 */
NTSTATUS
IoQueryEaFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PFILE_FULL_EA_INFORMATION Buffer,
    IN ULONG Length,
    IN BOOLEAN ReturnSingleEntry,
    IN PFILE_GET_EA_INFORMATION EaList,
    IN ULONG EaListLength,
    IN OPTIONAL PULONG EaIndex,
    IN BOOLEAN RestartScan
    );

/**
 * @brief Set file extended attributes.
 *
 * Sets extended attributes for a file.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[out]    Buffer              A list of EAs to set.
 * @param[in]     Length              The length of @a Buffer.
 *
 * @retval LW_STATUS_SUCCESS               Success.
 * @retval LW_STATUS_PENDING               The operation will be completed asynchronously by
 *                                         invoking @a AsyncControlBlock->Callback.  The final result
 *                                         status can be obtained from @a IoStatusBlock->Status.
 *                                         requested information.
 * @retval LW_STATUS_EA_LIST_INCONSISTENT  The EA list was malformed.
 * @retval LW_STATUS_INVALID_EA_FLAG       The EA list contained an invalid EA flag.
 * @retval LW_STATUS_INVALID_EA_NAME       The EA list contained an invalid EA name.
 * @retval ...                             Error.
 */
NTSTATUS
IoSetEaFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PFILE_FULL_EA_INFORMATION Buffer,
    IN ULONG Length
    );

/**
 * @brief Query quota information
 *
 * Enumerates information about quotas on a file.  At least one of @a SidList
 * and @a StartSid must be NULL.  If both are NULL, all quotas are enumerated.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[out]    Buffer              A buffer to fill with quota information.
 * @param[in]     Length              The size of @a Buffer in bytes.
 * @param[in]     ReturnSingleEntry   If @a TRUE, only a single quota entry will be returned.
 * @param[in]     SidList             If provided, contains a list of SIDs for which quota
 *                                    information should be returned.
 * @param[in]     SidListLength       The size in bytes of @a SidList, or @a 0.
 * @param[in]     StartSid            If provided, contains a single SID from which enumeration
 *                                    should proceed.
 * @param[in]     RestartScan         If @a TRUE, enumeration will be restarted.
 *
 * @retval LW_STATUS_SUCCESS                 Success.
 * @retval LW_STATUS_PENDING                 The operation will be completed asynchronously by
 *                                           invoking @a AsyncControlBlock->Callback.  The final result
 *                                           status can be obtained from @a IoStatusBlock->Status.
 *                                           requested information.
 * @retval LW_STATUS_INVALID_DEVICE_REQUEST  Quotas are not enabled on the underlying volume.
 * @retval LW_STATUS_INVALID_SID             @a StartSid contained an invalid SID.
 * @retval LW_STATUS_QUOTA_LIST_INCONSISTENT @a SidList was not properly formed.
 * @retval LW_STATUS_BUFFER_TOO_SMALL        The provided buffer was too small to hold even a single entry.
 */
NTSTATUS
IoQueryQuotaInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PFILE_QUOTA_INFORMATION Buffer,
    IN ULONG Length,
    IN BOOLEAN ReturnSingleEntry,
    IN OPTIONAL PFILE_GET_QUOTA_INFORMATION SidList,
    IN ULONG SidListLength,
    IN OPTIONAL PFILE_GET_QUOTA_INFORMATION StartSid,
    IN BOOLEAN RestartScan
    );

/**
 * @brief Set quota information
 *
 * Sets quota information on a file.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[out]    Buffer              The quota information to set.
 * @param[in]     Length              The size of @a Buffer in bytes.
 *
 * @retval LW_STATUS_SUCCESS                 Success.
 * @retval LW_STATUS_PENDING                 The operation will be completed asynchronously by
 *                                           invoking @a AsyncControlBlock->Callback.  The final result
 *                                           status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_INVALID_DEVICE_REQUEST  Quotas are not enabled on the underlying volume.
 * @retval LW_STATUS_QUOTA_LIST_INCONSISTENT @a Buffer was not properly formed.
 * @retval LW_STATUS_BUFFER_TOO_SMALL        The provided buffer was too small to hold even a single entry.
 */
NTSTATUS
IoSetQuotaInformationFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PFILE_QUOTA_INFORMATION Buffer,
    IN ULONG Length
    );

/**
 * @brief Query file security descriptor
 *
 * Queries the security descriptor for a file.  The provide handle must
 * have been opened with @a READ_CONTROL access to parts of the security
 * descriptor other than the SACL.  For the SACL, @a ACCESS_SYSTEM_SECURITY
 * is required.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[in]     SecurityInformation A mask indicating which parts of the security descriptor
 *                                    should be queried.
 * @param[out]    SecurityDescriptor  A buffer which is filled with the requested
 *                                    information.
 * @param[in]     Length              The size of @a SecurityDescriptor in bytes.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_BUFFER_TOO_SMALL   The passed buffer was too small to contain the
 *                                      requested information.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with appropriate access to read
 *                                      the requested information.
 * @retval ...                          Error.
 */
NTSTATUS
IoQuerySecurityFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN SECURITY_INFORMATION SecurityInformation,
    OUT PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
    IN OUT PULONG Length
    );

/**
 * @brief Update file security descriptor
 *
 * Updates the security descriptor for a file.  To write the owner
 * or primary group, @a WRITE_OWNER access is required on the provided handle.
 * To write the DACL, @a WRITE_DAC access is necessary.  To write the SACL,
 * @a ACCESS_SYSTEM_SECURITY is required.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[in,out] AsyncControlBlock   Optional async control block. If specified,
 *                                    @a LW_STATUS_PENDING may be returned and
 *                                    @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock       Filled with result information on completion.
 * @param[in]     SecurityInformation A mask indicating which parts of the security descriptor
 *                                    should be updated.
 * @param[in]     SecurityDescriptor  A buffer which contains the security descriptor information
 *                                    to be set.
 * @param[in]     Length              The size of @a SecurityDescriptor in bytes.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with appropriate access to write
 *                                      the requested information.
 * @retval ...                          Error.
 */
NTSTATUS
IoSetSecurityFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN SECURITY_INFORMATION SecurityInformation,
    IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
    IN OUT PULONG Length
    );

/**@}*/

/**
 * @name ZCT (Zero-Copy Transfer) Operations
 */

/**@{*/

/**
 * @brief Get the ZCT entry types supported for read/write operations.
 *
 * Returns the ZCT entry types supported by the underlying file system
 * on a given handle for ZCT read and write operations.
 *
 * @param[in]     FileHandle          The file handle.
 * @param[out]    ZctReadMask         ZCT entry types for reading the file.
 * @param[out]    ZctWriteMask         ZCT entry types for writing the file.
 */
VOID
IoGetZctSupportMaskFile(
    IN IO_FILE_HANDLE FileHandle,
    OUT OPTIONAL PLW_ZCT_ENTRY_MASK ZctReadMask,
    OUT OPTIONAL PLW_ZCT_ENTRY_MASK ZctWriteMask
    );

/**
 * @brief Prepare for reading from a file using ZCT
 *
 * Updates a ZCT vector by adding entries representing the data in the file.
 *
 * @param[in]     FileHandle        The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling read behavior.  The
 *                                  only valid flag is presently #IO_FLAG_PAGING_IO.
 * @param[in,out] Zct               The ZCT vector to which ZCT entries/buffers for
 *                                  the desired data from the file are appended.
 * @param[in]     Length            The number of bytes to read.
 * @param[in]     ByteOffset        An optional byte offset into file from which to read.
 *                                  If not specified, the current file handle position is used.
 * @param[in]     Key               Currently unused.  Must be @a NULL.
 * @param[out]    CompletionContext Returns a context pointer that is passed back to
 *                                  the file system in #IoCompleteZctReadFile.
 *
 * @retval LW_STATUS_SUCESS             Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_NOT_SUPPORTED      ZCT is not supported for this operation.  (The
 *                                      caller can retry as a normal operation.)
 * @retval LW_STATUS_END_OF_FILE        No data was read because the end of the file was reached.
 * @retval LW_STATUS_FILE_LOCK_CONFLICT A conflicting lock prevented the read.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with #FILE_READ_DATA, or if
 *                                      #IO_FLAG_PAGING_IO was specified, #FILE_EXECUTE.
 * @retval ...                          Error.
 */
NTSTATUS
IoPrepareZctReadFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN OUT PLW_ZCT_VECTOR Zct,
    IN ULONG Length,
    IN OPTIONAL PULONG64 ByteOffset,
    IN OPTIONAL PULONG Key,
    OUT PVOID* CompletionContext
    );

/**
 * @brief Complete reading from a file using ZCT
 *
 * Indicates to the file system that the ZCT operation is complete.
 * This allows the file system to reclaim any resources reserved for
 * the ZCT operation.
 *
 * @param[in]     FileHandle        The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling read behavior.
 * @param[in]     CompletionContext Context pointer from #IoPrepareZctReadFile.
 *
 * @retval LW_STATUS_SUCESS             Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval ...                          Error.
 */
NTSTATUS
IoCompleteZctReadFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN PVOID CompletionContext
    );

/**
 * @brief Prepare for writing a file using ZCT
 *
 * Updates a ZCT vector by adding entries representing the location in the file
 * into which the data is to be written.
 *
 * @param[in]     FileHandle The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling write behavior.
 * @param[in,out] Zct               The ZCT vector to which ZCT entries/buffers into
 *                                  which to write the data.
 * @param[in]     Length            The number of bytes to write.
 * @param[in]     ByteOffset        An optional byte offset into file to which to write.
 *                                  If not specified, the current file handle position is used.
 * @param[in]     Key               Currently unused.  Must be @a NULL.
 * @param[out]    CompletionContext Returns a context pointer that is passed back to
 *                                  the file system in #IoCompleteZctReadFile.
 *
 * @retval LW_STATUS_SUCCESS            Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval LW_STATUS_NOT_SUPPORTED      ZCT is not supported for this operation.  (The
 *                                      caller can retry as a normal operation.)
 * @retval LW_STATUS_DISK_FULL          There was insufficient space on the device containing the file.
 * @retval LW_STATUS_FILE_LOCK_CONFLICT A conflicting lock prevented the write.
 * @retval LW_STATUS_ACCESS_DENIED      The handle was not opened with #FILE_WRITE_DATA access.
 * @retval ...                          Error.
 */
NTSTATUS
IoPrepareZctWriteFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN OUT PLW_ZCT_VECTOR Zct,
    IN ULONG Length,
    IN OPTIONAL PULONG64 ByteOffset,
    IN OPTIONAL PULONG Key,
    OUT PVOID* CompletionContext
    );

/**
 * @brief Complete wrting to a file using ZCT.
 *
 * Indicates to the file system that the ZCT operation is complete.
 * This allows the file system to reclaim any resources reserved for
 * the ZCT operation (and commit the write as appropriate).
 *
 * @param[in]     FileHandle        The handle to read from.
 * @param[in,out] AsyncControlBlock Optional async control block. If specified,
 *                                  @a LW_STATUS_PENDING may be returned and
 *                                  @a AsyncControlBlock->AsyncCancelContext set.
 * @param[out]    IoStatusBlock     Filled with result information on completion.
 * @param[in]     IoFlags           Additional flags controlling read behavior.
 * @param[in]     CompletionContext Context pointer from #IoPrepareZctReadFile.
 * @param[in]     BytesTransferred  Actual number of bytes written into the ZCT
 *                                  buffers provided in #IoPrepareZctWriteFile.
 *
 * @retval LW_STATUS_SUCESS             Success.
 * @retval LW_STATUS_PENDING            The operation will be completed asynchronously by
 *                                      invoking @a AsyncControlBlock->Callback.  The final result
 *                                      status can be obtained from @a IoStatusBlock->Status.
 * @retval ...                          Error.
 */
NTSTATUS
IoCompleteZctWriteFile(
    IN IO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN IO_FLAGS IoFlags,
    IN PVOID CompletionContext,
    IN ULONG BytesTransferred
    );

/**@}*/

/*@}*/

LW_END_EXTERN_C


#endif /* __IO_API_H__ */


/*
local variables:
mode: c
c-basic-offset: 4
indent-tabs-mode: nil
tab-width: 4
end:
*/
