/* * Copyright (c) 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 * . * * 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@likewise.com */ /* * Module Name: * * iodriver.h * * Abstract: * * IO Manager Driver Header File * * Authors: Danilo Almeida (dalmeida@likewisesoftware.com) * */ #ifndef __IODRIVER_H__ #define __IODRIVER_H__ #include #include struct _IO_DRIVER_OBJECT; typedef struct _IO_DRIVER_OBJECT IO_DRIVER_OBJECT, *PIO_DRIVER_OBJECT; typedef IO_DRIVER_OBJECT *IO_DRIVER_HANDLE, **PIO_DRIVER_HANDLE; struct _IO_DEVICE_OBJECT; typedef struct _IO_DEVICE_OBJECT IO_DEVICE_OBJECT, *PIO_DEVICE_OBJECT; typedef IO_DEVICE_OBJECT *IO_DEVICE_HANDLE, **PIO_DEVICE_HANDLE; typedef ULONG IRP_TYPE; #define IRP_TYPE_UNINITIALIZED 0 #define IRP_TYPE_CREATE 1 #define IRP_TYPE_CLOSE 2 #define IRP_TYPE_READ 3 #define IRP_TYPE_WRITE 4 #define IRP_TYPE_DEVICE_IO_CONTROL 5 #define IRP_TYPE_FS_CONTROL 6 #define IRP_TYPE_FLUSH_BUFFERS 7 #define IRP_TYPE_QUERY_INFORMATION 8 #define IRP_TYPE_SET_INFORMATION 9 #define IRP_TYPE_CREATE_NAMED_PIPE 10 #define IRP_TYPE_CREATE_MAILSLOT 11 // In Windows, DIRECTORY_CONTROL has two subtypes: // - QUERY_DIRECTORY // - READ_CHANGE_DIRECTORY // Here, however, two separate IRPs are used. #define IRP_TYPE_QUERY_DIRECTORY 12 #define IRP_TYPE_READ_DIRECTORY_CHANGE 13 #define IRP_TYPE_QUERY_VOLUME_INFORMATION 14 #define IRP_TYPE_SET_VOLUME_INFORMATION 15 #define IRP_TYPE_LOCK_CONTROL 16 #define IRP_TYPE_QUERY_SECURITY 17 #define IRP_TYPE_SET_SECURITY 18 #if 0 #define IPP_TYPE_QUERY_EA 19 #define IPP_TYPE_SET_EA 20 #define IRP_TYPE_QUERY_QUOTA 21 #define IRP_TYPE_SET_QUOTA 22 #define IRP_TYPE_QUERY_FULL_ATTRIBUTES 23 #define IRP_TYPE_RENAME 24 #define IRP_TYPE_LINK 25 #define IRP_TYPE_UNLINK 26 #endif typedef ULONG IO_LOCK_CONTROL; #define IO_LOCK_CONTROL_LOCK 1 #define IO_LOCK_CONTROL_UNLOCK 2 #define IO_LOCK_CONTROL_UNLOCK_ALL_BY_KEY 3 #define IO_LOCK_CONTROL_UNLOCK_ALL 4 // "Storage" field is so we do not have to allocate // extra memory blocks for small optional parameters // that are provided via pointers. typedef struct _IRP_ARGS_CREATE { IN PIO_CREATE_SECURITY_CONTEXT SecurityContext; IN IO_FILE_NAME FileName; 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 PFILE_FULL_EA_INFORMATION EaBuffer; IN ULONG EaLength; IN OPTIONAL PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor; IN OPTIONAL PVOID SecurityQualityOfService; // TBD IN OPTIONAL PIO_ECP_LIST EcpList; } IRP_ARGS_CREATE, *PIRP_ARGS_CREATE; typedef struct _IRP_ARGS_READ_WRITE { // IN for write, OUT for read IN OUT PVOID Buffer; IN ULONG Length; IN OPTIONAL PLONG64 ByteOffset; IN OPTIONAL PULONG Key; IN BOOLEAN IsPagingIo; struct { LONG64 ByteOffset; ULONG Key; } Storage; } IRP_ARGS_READ_WRITE, *PIRP_ARGS_READ_WRITE; typedef struct _IRP_ARGS_IO_FS_CONTROL { IN ULONG ControlCode; IN PVOID InputBuffer; IN ULONG InputBufferLength; OUT PVOID OutputBuffer; IN ULONG OutputBufferLength; } IRP_ARGS_IO_FS_CONTROL, *PIRP_ARGS_IO_FS_CONTROL; typedef struct _IRP_ARGS_QUERY_SET_INFORMATION { IN OUT PVOID FileInformation; IN ULONG Length; IN FILE_INFORMATION_CLASS FileInformationClass; } IRP_ARGS_QUERY_SET_INFORMATION, *PIRP_ARGS_QUERY_SET_INFORMATION; typedef struct _IRP_ARGS_QUERY_DIRECTORY { OUT PVOID FileInformation; IN ULONG Length; IN FILE_INFORMATION_CLASS FileInformationClass; IN BOOLEAN ReturnSingleEntry; IN OPTIONAL PIO_MATCH_FILE_SPEC FileSpec; IN BOOLEAN RestartScan; struct { IO_MATCH_FILE_SPEC FileSpec; } Storage; } IRP_ARGS_QUERY_DIRECTORY, *PIRP_ARGS_QUERY_DIRECTORY; typedef struct _IRP_ARGS_READ_DIRECTORY_CHANGE { OUT PVOID Buffer; IN ULONG Length; IN BOOLEAN WatchTree; IN FILE_NOTIFY_CHANGE NotifyFilter; IN OPTIONAL PULONG MaxBufferSize; struct { ULONG MaxBufferSize; } Storage; } IRP_ARGS_READ_DIRECTORY_CHANGE, *PIRP_ARGS_READ_DIRECTORY_CHANGE; typedef struct _IRP_ARGS_QUERY_SET_VOLUME_INFORMATION { IN OUT PVOID FsInformation; IN ULONG Length; IN FS_INFORMATION_CLASS FsInformationClass; } IRP_ARGS_QUERY_SET_VOLUME_INFORMATION, *PIRP_ARGS_QUERY_VOLUME_INFORMATION; typedef struct _IRP_ARGS_LOCK_CONTROL { IN IO_LOCK_CONTROL LockControl; IN LONG64 ByteOffset; IN LONG64 Length; IN ULONG Key; IN BOOLEAN FailImmediately; IN BOOLEAN ExclusiveLock; } IRP_ARGS_LOCK_CONTROL, *PIRP_ARGS_LOCK_CONTROL; typedef struct _IRP_ARGS_QUERY_SET_SECURITY { IN SECURITY_INFORMATION SecurityInformation; IN OUT PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor; IN ULONG Length; } IRP_ARGS_QUERY_SET_SECURITY, *PIRP_ARGS_QUERY_SET_SECUIRTY; typedef struct _IRP { IN IRP_TYPE Type; OUT IO_STATUS_BLOCK IoStatusBlock; IN IO_DRIVER_HANDLE DriverHandle; IN IO_DEVICE_HANDLE DeviceHandle; IN IO_FILE_HANDLE FileHandle; union { // IRP_TYPE_CREATE IRP_ARGS_CREATE Create; // IRP_TYPE_READ, IRP_TYPE_WRITE IRP_ARGS_READ_WRITE ReadWrite; // IRP_TYPE_IO_CONTROL, IRP_TYPE_FS_CONTROL IRP_ARGS_IO_FS_CONTROL IoFsControl; // IRP_TYPE_QUERY_INFORMATION, IRP_TYPE_SET_INFORMATION IRP_ARGS_QUERY_SET_INFORMATION QuerySetInformation; // IRP_TYPE_QUERY_DIRECTORY IRP_ARGS_QUERY_DIRECTORY QueryDirectory; // IRP_TYPE_READ_DIRECTORY_CHANGE IRP_ARGS_READ_DIRECTORY_CHANGE ReadDirectoryChange; // IRP_TYPE_QUERY_VOLUME IRP_ARGS_QUERY_SET_VOLUME_INFORMATION QuerySetVolumeInformation; // IRP_TYPE_LOCK_CONTROL IRP_ARGS_LOCK_CONTROL LockControl; // IRP_TYPE_QUERY_SECURITY, IRP_TYPE_SET_SECURITY IRP_ARGS_QUERY_SET_SECURITY QuerySetSecurity; // No args for IRP_TYPE_CLOSE, IRP_TYPE_FLUSH } Args; // TODO: Rename Args to Params? // Internal data at the end... } IRP, *PIRP; typedef VOID (*PIO_IRP_CALLBACK)( IN PIRP Irp, IN PVOID CallbackContext ); typedef VOID (*PIO_DRIVER_SHUTDOWN_CALLBACK)( IN IO_DRIVER_HANDLE DriverHandle ); typedef NTSTATUS (*PIO_DRIVER_DISPATCH_CALLBACK)( IN IO_DEVICE_HANDLE DeviceHandle, IN PIRP Irp ); typedef NTSTATUS (*PIO_DRIVER_ENTRY)( IN IO_DRIVER_HANDLE DriverHandle, IN ULONG InterfaceVersion ); typedef struct _IO_STATIC_DRIVER { PCSTR pszName; PIO_DRIVER_ENTRY pEntry; } IO_STATIC_DRIVER, *PIO_STATIC_DRIVER; #define IO_DRIVER_ENTRY_FUNCTION_NAME "DriverEntry" #define IO_DRIVER_ENTRY_INTERFACE_VERSION 1 // Driver functions // Can only be called in DriverEntry. NTSTATUS IoDriverInitialize( IN OUT IO_DRIVER_HANDLE DriverHandle, IN OPTIONAL PVOID DriverContext, IN PIO_DRIVER_SHUTDOWN_CALLBACK ShutdownCallback, IN PIO_DRIVER_DISPATCH_CALLBACK DispatchCallback ); PCSTR IoDriverGetName( IN IO_DRIVER_HANDLE DriverHandle ); PVOID IoDriverGetContext( IN IO_DRIVER_HANDLE DriverHandle ); // Device functions NTSTATUS IoDeviceCreate( OUT PIO_DEVICE_HANDLE pDeviceHandle, IN IO_DRIVER_HANDLE DriverHandle, IN PCSTR pszName, IN OPTIONAL PVOID DeviceContext ); VOID IoDeviceDelete( IN OUT PIO_DEVICE_HANDLE pDeviceHandle ); PVOID IoDeviceGetContext( IN IO_DEVICE_HANDLE DeviceHandle ); // File functions NTSTATUS IoFileSetContext( IN IO_FILE_HANDLE FileHandle, IN PVOID FileContext ); PVOID IoFileGetContext( IN IO_FILE_HANDLE FileHandle ); // IRP functions for async processing #if 0 BOOLEAN IoIrpIsCancelled( IN PIRP pIrp ); #endif VOID IoIrpMarkPending( IN PIRP pIrp, IN PIO_IRP_CALLBACK CancelCallback, IN OPTIONAL PVOID CancelCallbackContext ); #if 0 VOID IoIrpSetCancelRoutine( IN PIRP pIrp, IN OPTIONAL PIO_IRP_CALLBACK CancelCallback, IN OPTIONAL PVOID CancelCallbackContext ); #endif // must have set IO status block in IRP. VOID IoIrpComplete( IN OUT PIRP Irp ); // Drivrer memory VOID IoMemoryZero( IN OUT PVOID pMemory, IN size_t Size ); PVOID IoMemoryAllocate( IN size_t Size ); VOID IoMemoryFree( IN OUT PVOID pMemory ); #define IO_ALLOCATE(ppMemory, Type, Size) \ ( (*(ppMemory)) = (Type*) IoMemoryAllocate(Size), (*(ppMemory)) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES ) #define IO_FREE(ppMemory) \ do { \ if (*(ppMemory)) \ { \ IoMemoryFree(*(ppMemory)); \ (*(ppMemory)) = NULL; \ } \ } while (0) // // Security Context // PIO_SECURITY_CONTEXT_PROCESS_INFORMATION IoSecurityGetProcessInfo( IN PIO_CREATE_SECURITY_CONTEXT SecurityContext ); PACCESS_TOKEN IoSecurityGetAccessToken( IN PIO_CREATE_SECURITY_CONTEXT SecurityContext ); LW_PIO_CREDS IoSecurityGetCredentials( IN PIO_CREATE_SECURITY_CONTEXT SecurityContext ); VOID IoSecurityDereferenceSecurityContext( IN OUT PIO_CREATE_SECURITY_CONTEXT* SecurityContext ); NTSTATUS IoSecurityCreateSecurityContextFromUidGid( OUT PIO_CREATE_SECURITY_CONTEXT* SecurityContext, IN uid_t Uid, IN gid_t Gid, IN OPTIONAL LW_PIO_CREDS Credentials ); NTSTATUS IoSecurityCreateSecurityContextFromUsername( OUT PIO_CREATE_SECURITY_CONTEXT* SecurityContext, IN PUNICODE_STRING Username ); NTSTATUS IoSecurityCreateSecurityContextFromGssContext( OUT PIO_CREATE_SECURITY_CONTEXT* SecurityContext, IN LW_MAP_SECURITY_GSS_CONTEXT hGssContext ); // // Logging // PCSTR IoGetIrpTypeString( IN IRP_TYPE Type ); #define IO_LOG_ENTER(Format, ...) \ LWIO_LOG_DEBUG("ENTER: " Format, ## __VA_ARGS__) #define IO_LOG_LEAVE(Format, ...) \ LWIO_LOG_DEBUG("LEAVE: " Format, ## __VA_ARGS__) #define IO_LOG_ENTER_LEAVE(Format, ...) \ LWIO_LOG_DEBUG("ENTER/LEAVE: " Format, ## __VA_ARGS__) #define IO_LOG_LEAVE_ON_STATUS_EE(status, EE) \ do { \ if (EE || status) \ { \ IO_LOG_LEAVE("-> 0x%08x (EE = %d)", status, EE); \ } \ } while (0) #define IO_LOG_ENTER_LEAVE_STATUS_EE(status, EE) \ IO_LOG_ENTER_LEAVE("-> 0x%08x (EE = %d)", status, EE) #define IO_LOG_ENTER_LEAVE_STATUS_EE_EX(status, EE, Format, ...) \ IO_LOG_ENTER_LEAVE(Format " -> 0x%08x (EE = %d)", ## __VA_ARGS__, status, EE) #define IO_LOG_LEAVE_STATUS_EE(status, EE) \ IO_LOG_LEAVE("-> 0x%08x (EE = %d)", status, EE) #define IO_LOG_LEAVE_STATUS_EE_EX(status, EE, Format, ...) \ IO_LOG_LEAVE(Format " -> 0x%08x (EE = %d)", ## __VA_ARGS__, status, EE) #ifdef ENABLE_STATIC_DRIVERS #define IO_DRIVER_ENTRY(name) DriverEntry_##name #else #define IO_DRIVER_ENTRY(name) DriverEntry #endif #define IO_STATIC_DRIVER_ENTRY(name) {#name, IO_DRIVER_ENTRY(name)} #define IO_STATIC_DRIVER_END {NULL, NULL} #endif /* __IODRIVER_H__ */ /* local variables: mode: c c-basic-offset: 4 indent-tabs-mode: nil tab-width: 4 end: */