/* * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani * * 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. * */ #ifndef _WINNT_TYPES_H_ #define _WINNT_TYPES_H_ #define TRUE 1 #define FALSE 0 #define PASSIVE_LEVEL 0 #define DISPATCH_LEVEL 2 #define DEVICE_LEVEL (DISPATCH_LEVEL + 1) #define STATUS_WAIT_0 0 #define STATUS_SUCCESS 0 #define STATUS_ALERTED 0x00000101 #define STATUS_TIMEOUT 0x00000102 #define STATUS_PENDING 0x00000103 #define STATUS_FAILURE 0xC0000001 #define STATUS_NOT_IMPLEMENTED 0xC0000002 #define STATUS_INVALID_PARAMETER 0xC000000D #define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 #define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 #define STATUS_ACCESS_DENIED 0xC0000022 #define STATUS_BUFFER_TOO_SMALL 0xC0000023 #define STATUS_OBJECT_NAME_INVALID 0xC0000023 #define STATUS_MUTANT_NOT_OWNED 0xC0000046 #define STATUS_RESOURCES 0xC000009A #define STATUS_DELETE_PENDING 0xC0000056 #define STATUS_INSUFFICIENT_RESOURCES 0xC000009A #define STATUS_NOT_SUPPORTED 0xC00000BB #define STATUS_INVALID_PARAMETER_2 0xC00000F0 #define STATUS_NO_MEMORY 0xC0000017 #define STATUS_CANCELLED 0xC0000120 #define STATUS_DEVICE_REMOVED 0xC00002B6 #define STATUS_BUFFER_OVERFLOW 0x80000005 #define SL_PENDING_RETURNED 0x01 #define SL_INVOKE_ON_CANCEL 0x20 #define SL_INVOKE_ON_SUCCESS 0x40 #define SL_INVOKE_ON_ERROR 0x80 #define IRP_MJ_CREATE 0x00 #define IRP_MJ_CREATE_NAMED_PIPE 0x01 #define IRP_MJ_CLOSE 0x02 #define IRP_MJ_READ 0x03 #define IRP_MJ_WRITE 0x04 #define IRP_MJ_DEVICE_CONTROL 0x0E #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0F #define IRP_MJ_POWER 0x16 #define IRP_MJ_SYSTEM_CONTROL 0x0E #define IRP_MJ_PNP 0x1b #define IRP_MJ_MAXIMUM_FUNCTION 0x1b #define IRP_MN_WAIT_WAKE 0x00 #define IRP_MN_POWER_SEQUENCE 0x01 #define IRP_MN_SET_POWER 0x02 #define IRP_MN_QUERY_POWER 0x03 #define IRP_MN_REGINFO 0x08 #define IRP_MN_REGINFO_EX 0x0b #define IRP_MN_START_DEVICE 0x00 #define IRP_MN_QUERY_REMOVE_DEVICE 0x01 #define IRP_MN_REMOVE_DEVICE 0x02 #define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 #define IRP_MN_STOP_DEVICE 0x04 #define IRP_MN_QUERY_STOP_DEVICE 0x05 #define IRP_MN_CANCEL_STOP_DEVICE 0x06 #define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 #define IRP_MN_QUERY_INTERFACE 0x08 #define IRP_BUFFERED_IO 0x00000010 #define IRP_DEALLOCATE_BUFFER 0x00000020 #define IRP_INPUT_OPERATION 0x00000040 #define IRP_DEFFER_IO_COMPLETION 0x00000800 #define THREAD_WAIT_OBJECTS 3 #define MAX_WAIT_OBJECTS 64 #define LOW_PRIORITY 1 #define LOW_REALTIME_PRIORITY 16 #define HIGH_PRIORITY 32 #define MAXIMUM_PRIORITY 32 #define PROCESSOR_FEATURE_MAX 64 #define IO_NO_INCREMENT 0 #define WMIREG_ACTION_REGISTER 1 #define WMIREG_ACTION_DEREGISTER 2 #define WMIREG_ACTION_REREGISTER 3 #define WMIREG_ACTION_UPDATE_GUIDS 4 #define WMIREGISTER 0 #define WMIUPDATE 1 #ifdef CONFIG_X86_64 #define wstdcall #define wfastcall #define noregparm #define KI_USER_SHARED_DATA 0xfffff78000000000 #else #define noregparm __attribute__((regparm(0))) #define wstdcall __attribute__((__stdcall__, regparm(0))) #if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ > 3) || __GNUC__ > 3) #undef fastcall #define wfastcall __attribute__((fastcall)) #else #error "gcc 3.4 or newer should be used for compiling this module" #endif #define KI_USER_SHARED_DATA 0xffdf0000 #endif #define packed __attribute__((packed)) #define no_warn_unused __attribute__((unused)) typedef u8 BOOLEAN; typedef u8 BYTE; typedef u8 *LPBYTE; typedef s8 CHAR; typedef u8 UCHAR; typedef s16 SHORT; typedef u16 USHORT; typedef u16 WORD; typedef s32 INT; typedef u32 UINT; typedef u32 DWORD; typedef s32 LONG; typedef u32 ULONG; typedef s64 LONGLONG; typedef u64 ULONGLONG; typedef u64 ULONGULONG; typedef u64 ULONG64; typedef CHAR CCHAR; typedef USHORT wchar_t; typedef SHORT CSHORT; typedef LONGLONG LARGE_INTEGER; typedef LONG NTSTATUS; typedef LONG KPRIORITY; typedef LARGE_INTEGER PHYSICAL_ADDRESS; typedef UCHAR KIRQL; typedef CHAR KPROCESSOR_MODE; /* ULONG_PTR is 32 bits on 32-bit platforms and 64 bits on 64-bit * platform, which is same as 'unsigned long' in Linux */ typedef unsigned long ULONG_PTR; typedef ULONG_PTR SIZE_T; typedef ULONG_PTR KAFFINITY; typedef ULONG ACCESS_MASK; typedef ULONG_PTR PFN_NUMBER; typedef ULONG SECURITY_INFORMATION; /* non-negative numbers indicate success */ #define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0) struct ansi_string { USHORT length; USHORT max_length; char *buf; }; struct unicode_string { USHORT length; USHORT max_length; wchar_t *buf; }; struct nt_slist { struct nt_slist *next; }; #ifdef CONFIG_X86_64 /* it is not clear how nt_slist_head is used to store pointer to * slists and depth; here we assume 'align' field is used to store * depth and 'region' field is used to store slist pointers */ struct nt_slist_head { union { USHORT depth; ULONGLONG align; }; union { ULONGLONG region; struct nt_slist *next; }; } __attribute__((aligned(16))); typedef struct nt_slist_head nt_slist_header; #else union nt_slist_head { ULONGLONG align; struct { struct nt_slist *next; USHORT depth; USHORT sequence; }; }; typedef union nt_slist_head nt_slist_header; #endif struct nt_list { struct nt_list *next; struct nt_list *prev; }; typedef ULONG_PTR NT_SPIN_LOCK; struct kdpc; typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2) wstdcall; struct kdpc { SHORT type; UCHAR nr_cpu; UCHAR importance; struct nt_list list; DPC func; void *ctx; void *arg1; void *arg2; NT_SPIN_LOCK *lock; }; enum pool_type { NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS, MaxPoolType, NonPagedPoolSession = 32, PagedPoolSession = NonPagedPoolSession + 1, NonPagedPoolMustSucceedSession = PagedPoolSession + 1, DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 }; enum memory_caching_type_orig { MmFrameBufferCached = 2 }; enum memory_caching_type { MmNonCached = FALSE, MmCached = TRUE, MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType }; enum lock_operation { IoReadAccess, IoWriteAccess, IoModifyAccess }; enum mode { KernelMode, UserMode, MaximumMode }; struct mdl { struct mdl *next; CSHORT size; CSHORT flags; /* NdisFreeBuffer doesn't pass pool, so we store pool in * unused field 'process' */ union { void *process; void *pool; }; void *mappedsystemva; void *startva; ULONG bytecount; ULONG byteoffset; }; #define MDL_MAPPED_TO_SYSTEM_VA 0x0001 #define MDL_PAGES_LOCKED 0x0002 #define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 #define MDL_ALLOCATED_FIXED_SIZE 0x0008 #define MDL_PARTIAL 0x0010 #define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 #define MDL_IO_PAGE_READ 0x0040 #define MDL_WRITE_OPERATION 0x0080 #define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 #define MDL_FREE_EXTRA_PTES 0x0200 #define MDL_IO_SPACE 0x0800 #define MDL_NETWORK_HEADER 0x1000 #define MDL_MAPPING_CAN_FAIL 0x2000 #define MDL_ALLOCATED_MUST_SUCCEED 0x4000 #define MDL_POOL_ALLOCATED 0x0400 #define MDL_CACHE_ALLOCATED 0x8000 #define PAGE_START(ptr) ((void *)((ULONG_PTR)(ptr) & ~(PAGE_SIZE - 1))) #define BYTE_OFFSET(ptr) ((ULONG)((ULONG_PTR)(ptr) & (PAGE_SIZE - 1))) #define MmGetMdlByteCount(mdl) ((mdl)->bytecount) #define MmGetMdlVirtualAddress(mdl) ((mdl)->startva + (mdl)->byteoffset) #define MmGetMdlByteOffset(mdl) ((mdl)->byteoffset) #define MmGetSystemAddressForMdl(mdl) ((mdl)->mappedsystemva) #define MmGetSystemAddressForMdlSafe(mdl, priority) ((mdl)->mappedsystemva) #define MmGetMdlPfnArray(mdl) ((PFN_NUMBER *)(mdl + 1)) #define MmInitializeMdl(mdl, baseva, length) \ do { \ (mdl)->next = NULL; \ (mdl)->size = MmSizeOfMdl(baseva, length); \ (mdl)->flags = 0; \ (mdl)->startva = PAGE_START(baseva); \ (mdl)->byteoffset = BYTE_OFFSET(baseva); \ (mdl)->bytecount = length; \ (mdl)->mappedsystemva = baseva; \ DBGTRACE4("%p %p %p %d %d", (mdl), baseva, (mdl)->startva, \ (mdl)->byteoffset, length); \ } while (0) struct kdevice_queue_entry { struct nt_list list; ULONG sort_key; BOOLEAN inserted; }; struct kdevice_queue { USHORT type; USHORT size; struct nt_list list; NT_SPIN_LOCK lock; BOOLEAN busy; }; struct wait_context_block { struct kdevice_queue_entry wait_queue_entry; void *device_routine; void *device_context; ULONG num_regs; void *device_object; void *current_irp; void *buffer_chaining_dpc; }; struct wait_block { struct nt_list list; struct task_struct *thread; void *object; void *thread_waitq; USHORT wait_key; USHORT wait_type; }; struct dispatcher_header { UCHAR type; UCHAR absolute; UCHAR size; UCHAR inserted; LONG signal_state; struct nt_list wait_blocks; }; enum event_type { NotificationEvent, SynchronizationEvent, }; enum timer_type { NotificationTimer = NotificationEvent, SynchronizationTimer = SynchronizationEvent, }; enum dh_type { NotificationObject = NotificationEvent, SynchronizationObject = SynchronizationEvent, MutexObject, SemaphoreObject, ThreadObject, }; enum wait_type { WaitAll, WaitAny }; /* objects that use dispatcher_header have it as the first field, so * whenever we need to initialize dispatcher_header, we can convert * that object into a nt_event and access dispatcher_header */ struct nt_event { struct dispatcher_header dh; }; struct wrap_timer; #define WRAP_TIMER_MAGIC 47697249 struct nt_timer { struct dispatcher_header dh; /* We can't fit Linux timer in this structure. Instead of * padding the nt_timer structure, we replace due_time field * with *wrap_timer and allocate memory for it when nt_timer is * initialized */ union { ULONGLONG due_time; struct wrap_timer *wrap_timer; }; struct nt_list list; struct kdpc *kdpc; union { LONG period; LONG wrap_timer_magic; }; }; struct nt_mutex { struct dispatcher_header dh; struct nt_list list; struct task_struct *owner_thread; BOOLEAN abandoned; BOOLEAN apc_disable; }; struct nt_semaphore { struct dispatcher_header dh; LONG limit; }; struct nt_thread { struct dispatcher_header dh; /* the rest in Windows is a long structure; since this * structure is opaque to drivers, we just define what we * need */ int pid; struct task_struct *task; struct nt_list irps; NT_SPIN_LOCK lock; }; #define set_dh_type(dh, type) ((dh)->type = (type)) #define is_mutex_dh(dh) ((dh)->type == MutexObject) #define is_semaphore_dh(dh) ((dh)->type == SemaphoreObject) #define is_nt_thread_dh(dh) ((dh)->type == ThreadObject) #define IO_TYPE_ADAPTER 1 #define IO_TYPE_CONTROLLER 2 #define IO_TYPE_DEVICE 3 #define IO_TYPE_DRIVER 4 #define IO_TYPE_FILE 5 #define IO_TYPE_IRP 6 #define IO_TYPE_DEVICE_OBJECT_EXTENSION 13 struct irp; struct dev_obj_ext; struct driver_object; struct device_object { CSHORT type; USHORT size; LONG ref_count; struct driver_object *drv_obj; struct device_object *next; struct device_object *attached; struct irp *current_irp; void *io_timer; ULONG flags; ULONG characteristics; void *vpb; void *dev_ext; CCHAR stack_count; union { struct nt_list queue_list; struct wait_context_block wcb; } queue; ULONG align_req; struct kdevice_queue dev_queue; struct kdpc dpc; ULONG active_threads; void *security_desc; struct nt_event lock; USHORT sector_size; USHORT spare1; struct dev_obj_ext *dev_obj_ext; void *reserved; }; struct dev_obj_ext { CSHORT type; CSHORT size; struct device_object *dev_obj; struct device_object *attached_to; }; struct io_status_block { union { NTSTATUS status; void *pointer; }; ULONG_PTR info; }; #ifdef CONFIG_X86_64 struct io_status_block32 { NTSTATUS status; ULONG info; }; #endif #define DEVICE_TYPE ULONG struct driver_extension; typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj, struct irp *irp) wstdcall; struct driver_object { CSHORT type; CSHORT size; struct device_object *dev_obj; ULONG flags; void *start; ULONG driver_size; void *section; struct driver_extension *drv_ext; struct unicode_string name; struct unicode_string *hardware_database; void *fast_io_dispatch; void *init; void *start_io; void (*unload)(struct driver_object *driver) wstdcall; driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; }; struct driver_extension { struct driver_object *drv_obj; NTSTATUS (*add_device)(struct driver_object *drv_obj, struct device_object *dev_obj) wstdcall; ULONG count; struct unicode_string service_key_name; struct nt_list custom_ext; }; struct custom_ext { struct nt_list list; void *client_id; }; struct wrap_bin_file; struct file_object { CSHORT type; CSHORT size; struct device_object *dev_obj; void *volume_parameter_block; void *fs_context; void *fs_context2; void *section_object_pointer; void *private_cache_map; NTSTATUS final_status; union { struct file_object *related_file_object; struct wrap_bin_file *wrap_bin_file; }; BOOLEAN lock_operation; BOOLEAN delete_pending; BOOLEAN read_access; BOOLEAN write_access; BOOLEAN delete_access; BOOLEAN shared_read; BOOLEAN shared_write; BOOLEAN shared_delete; ULONG flags; struct unicode_string _name_; LARGE_INTEGER current_byte_offset; ULONG waiters; ULONG busy; void *last_lock; struct nt_event lock; struct nt_event event; void *completion_context; }; #ifdef CONFIG_X86_64 #define POINTER_ALIGN __attribute__((aligned(8))) #else #define POINTER_ALIGN #endif #define CACHE_ALIGN __attribute__((aligned(128))) enum system_power_state { PowerSystemUnspecified = 0, PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, PowerSystemMaximum, }; enum device_power_state { PowerDeviceUnspecified = 0, PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, PowerDeviceMaximum, }; union power_state { enum system_power_state system_state; enum device_power_state device_state; }; enum power_state_type { SystemPowerState = 0, DevicePowerState, }; enum power_action { PowerActionNone = 0, PowerActionReserved, PowerActionSleep, PowerActionHibernate, PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, PowerActionWarmEject, }; struct guid { ULONG data1; USHORT data2; USHORT data3; UCHAR data4[8]; }; struct nt_interface { USHORT size; USHORT version; void *context; void (*reference)(void *context) wstdcall; void (*dereference)(void *context) wstdcall; }; enum interface_type { InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, PNPBus, MaximumInterfaceType, }; #define CmResourceTypeNull 0 #define CmResourceTypePort 1 #define CmResourceTypeInterrupt 2 #define CmResourceTypeMemory 3 #define CmResourceTypeDma 4 #define CmResourceTypeDeviceSpecific 5 #define CmResourceTypeBusNumber 6 #define CmResourceTypeMaximum 7 #define CmResourceTypeNonArbitrated 128 #define CmResourceTypeConfigData 128 #define CmResourceTypeDevicePrivate 129 #define CmResourceTypePcCardConfig 130 #define CmResourceTypeMfCardConfig 131 enum cm_share_disposition { CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, CmResourceShareDriverExclusive, CmResourceShareShared }; #define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0 #define CM_RESOURCE_INTERRUPT_LATCHED 1 #define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 #define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 #define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 #define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 #define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 #define CM_RESOURCE_MEMORY_24 0x0010 #define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 #define CM_RESOURCE_PORT_MEMORY 0x0000 #define CM_RESOURCE_PORT_IO 0x0001 #define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 #define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 #define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 #define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 #define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 #define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 #define CM_RESOURCE_DMA_8 0x0000 #define CM_RESOURCE_DMA_16 0x0001 #define CM_RESOURCE_DMA_32 0x0002 #define CM_RESOURCE_DMA_8_AND_16 0x0004 #define CM_RESOURCE_DMA_BUS_MASTER 0x0008 #define CM_RESOURCE_DMA_TYPE_A 0x0010 #define CM_RESOURCE_DMA_TYPE_B 0x0020 #define CM_RESOURCE_DMA_TYPE_F 0x0040 #define MAX_RESOURCES 20 #pragma pack(push,4) struct cm_partial_resource_descriptor { UCHAR type; UCHAR share; USHORT flags; union { struct { PHYSICAL_ADDRESS start; ULONG length; } generic; struct { PHYSICAL_ADDRESS start; ULONG length; } port; struct { ULONG level; ULONG vector; KAFFINITY affinity; } interrupt; struct { PHYSICAL_ADDRESS start; ULONG length; } memory; struct { ULONG channel; ULONG port; ULONG reserved1; } dma; struct { ULONG data[3]; } device_private; struct { ULONG start; ULONG length; ULONG reserved; } bus_number; struct { ULONG data_size; ULONG reserved1; ULONG reserved2; } device_specific_data; } u; }; #pragma pack(pop) struct cm_partial_resource_list { USHORT version; USHORT revision; ULONG count; struct cm_partial_resource_descriptor partial_descriptors[1]; }; struct cm_full_resource_descriptor { enum interface_type interface_type; ULONG bus_number; struct cm_partial_resource_list partial_resource_list; }; struct cm_resource_list { ULONG count; struct cm_full_resource_descriptor list[1]; }; enum file_info_class { FileDirectoryInformation = 1, FileBasicInformation = 4, FileStandardInformation = 5, FileNameInformation = 9, FilePositionInformation = 14, FileAlignmentInformation = 17, FileNetworkOpenInformation = 34, FileAttributeTagInformation = 35, FileMaximumInformation = 41, }; enum fs_info_class { FileFsVolumeInformation = 1, /* ... */ FileFsMaximumInformation = 9, }; enum device_relation_type { BusRelations, EjectionRelations, PowerRelations, RemovalRelations, TargetDeviceRelation, SingleBusRelations, }; enum bus_query_id_type { BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, BusQueryDeviceSerialNumber = 4, }; enum device_text_type { DeviceTextDescription = 0, DeviceTextLocationInformation = 1, }; enum device_usage_notification_type { DeviceUsageTypeUndefined, DeviceUsageTypePaging, DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, }; #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 #define CTL_CODE(dev_type, func, method, access) \ (((dev_type) << 16) | ((access) << 14) | ((func) << 2) | (method)) #define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3) #ifndef CONFIG_X86_64 #pragma pack(push,4) #endif struct io_stack_location { UCHAR major_fn; UCHAR minor_fn; UCHAR flags; UCHAR control; union { struct { void *security_context; ULONG options; USHORT POINTER_ALIGN file_attributes; USHORT share_access; ULONG POINTER_ALIGN ea_length; } create; struct { ULONG length; ULONG POINTER_ALIGN key; LARGE_INTEGER byte_offset; } read; struct { ULONG length; ULONG POINTER_ALIGN key; LARGE_INTEGER byte_offset; } write; struct { ULONG length; enum file_info_class POINTER_ALIGN file_info_class; } query_file; struct { ULONG length; enum file_info_class POINTER_ALIGN file_info_class; struct file_object *file_object; union { struct { BOOLEAN replace_if_exists; BOOLEAN advance_only; }; ULONG cluster_count; void *delete_handle; }; } set_file; struct { ULONG length; enum fs_info_class POINTER_ALIGN fs_info_class; } query_volume; struct { ULONG output_buf_len; ULONG POINTER_ALIGN input_buf_len; ULONG POINTER_ALIGN code; void *type3_input_buf; } dev_ioctl; struct { SECURITY_INFORMATION security_info; ULONG POINTER_ALIGN length; } query_security; struct { SECURITY_INFORMATION security_info; void *security_descriptor; } set_security; struct { void *vpb; struct device_object *device_object; } mount_volume; struct { void *vpb; struct device_object *device_object; } verify_volume; struct { void *srb; } scsi; struct { enum device_relation_type type; } query_device_relations; struct { const struct guid *type; USHORT size; USHORT version; struct nt_interface *intf; void *intf_data; } query_intf; struct { void *capabilities; } device_capabilities; struct { void *io_resource_requirement_list; } filter_resource_requirements; struct { ULONG which_space; void *buffer; ULONG offset; ULONG POINTER_ALIGN length; } read_write_config; struct { BOOLEAN lock; } set_lock; struct { enum bus_query_id_type id_type; } query_id; struct { enum device_text_type device_text_type; ULONG POINTER_ALIGN locale_id; } query_device_text; struct { BOOLEAN in_path; BOOLEAN reserved[3]; enum device_usage_notification_type POINTER_ALIGN type; } usage_notification; struct { enum system_power_state power_state; } wait_wake; struct { void *power_sequence; } power_sequence; struct { ULONG sys_context; enum power_state_type POINTER_ALIGN type; union power_state POINTER_ALIGN state; enum power_action POINTER_ALIGN shutdown_type; } power; struct { struct cm_resource_list *allocated_resources; struct cm_resource_list *allocated_resources_translated; } start_device; struct { ULONG_PTR provider_id; void *data_path; ULONG buf_len; void *buf; } wmi; struct { void *arg1; void *arg2; void *arg3; void *arg4; } others; } params; struct device_object *dev_obj; struct file_object *file_obj; NTSTATUS (*completion_routine)(struct device_object *, struct irp *, void *) wstdcall; void *context; }; #ifndef CONFIG_X86_64 #pragma pack(pop) #endif #define URB_FROM_IRP(irp) \ (union nt_urb *)(IoGetCurrentIrpStackLocation(irp)->params.others.arg1) struct kapc { CSHORT type; CSHORT size; ULONG spare0; struct nt_thread *thread; struct nt_list list; void *kernele_routine; void *rundown_routine; void *normal_routine; void *normal_context; void *sys_arg1; void *sys_arg2; CCHAR apc_state_index; KPROCESSOR_MODE apc_mode; BOOLEAN inserted; }; #define IRP_NOCACHE 0x00000001 #define IRP_SYNCHRONOUS_API 0x00000004 #define IRP_ASSOCIATED_IRP 0x00000008 enum urb_state { URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED }; struct wrap_urb { struct nt_list list; enum urb_state state; struct nt_list complete_list; unsigned int flags; struct urb *urb; struct irp *irp; #ifdef USB_DEBUG unsigned int id; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) typeof(((struct urb *)0)->status) urb_status; #endif }; struct irp { SHORT type; USHORT size; struct mdl *mdl; ULONG flags; union { struct irp *master_irp; LONG irp_count; void *system_buffer; } associated_irp; struct nt_list threads; struct io_status_block io_status; KPROCESSOR_MODE requestor_mode; BOOLEAN pending_returned; CHAR stack_count; CHAR current_location; BOOLEAN cancel; KIRQL cancel_irql; CCHAR apc_env; UCHAR alloc_flags; struct io_status_block *user_status; struct nt_event *user_event; union { struct { void *user_apc_routine; void *user_apc_context; } async_params; LARGE_INTEGER alloc_size; } overlay; void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; void *user_buf; union { struct { union { struct kdevice_queue_entry dev_q_entry; struct { void *driver_context[4]; }; }; void *thread; char *aux_buf; struct { struct nt_list list; union { struct io_stack_location * current_stack_location; ULONG packet_type; }; }; struct file_object *file_object; } overlay; struct kapc apc; void *completion_key; } tail; /* ndiswrapper extension */ struct wrap_urb *wrap_urb; struct wrap_device *wd; }; #define IoSizeOfIrp(stack_count) \ ((USHORT)(sizeof(struct irp) + ((stack_count) * \ sizeof(struct io_stack_location)))) #define IoGetCurrentIrpStackLocation(irp) \ (irp)->tail.overlay.current_stack_location #define IoGetNextIrpStackLocation(irp) \ (IoGetCurrentIrpStackLocation(irp) - 1) #define IoGetPreviousIrpStackLocation(irp) \ (IoGetCurrentIrpStackLocation(irp) + 1) #define IoSetNextIrpStackLocation(irp) \ do { \ (irp)->current_location--; \ IoGetCurrentIrpStackLocation(irp)--; \ } while (0) #define IoSkipCurrentIrpStackLocation(irp) \ do { \ (irp)->current_location++; \ IoGetCurrentIrpStackLocation(irp)++; \ } while (0) static inline void IoCopyCurrentIrpStackLocationToNext(struct irp *irp) { struct io_stack_location *next; next = IoGetNextIrpStackLocation(irp); memcpy(next, IoGetCurrentIrpStackLocation(irp), offsetof(struct io_stack_location, completion_routine)); next->control = 0; } static inline void IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, BOOLEAN success, BOOLEAN error, BOOLEAN cancel) { struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); irp_sl->completion_routine = routine; irp_sl->context = context; irp_sl->control = 0; if (success) irp_sl->control |= SL_INVOKE_ON_SUCCESS; if (error) irp_sl->control |= SL_INVOKE_ON_ERROR; if (cancel) irp_sl->control |= SL_INVOKE_ON_CANCEL; } #define IoMarkIrpPending(irp) \ (IoGetCurrentIrpStackLocation((irp))->control |= SL_PENDING_RETURNED) #define IoUnmarkIrpPending(irp) \ (IoGetCurrentIrpStackLocation((irp))->control &= ~SL_PENDING_RETURNED) #define IRP_SL(irp, i) (((struct io_stack_location *)((irp) + 1)) + (i)) #define IRP_DRIVER_CONTEXT(irp) (irp)->tail.overlay.driver_context #define IoIrpThread(irp) ((irp)->tail.overlay.thread) struct wmi_guid_reg_info { struct guid *guid; ULONG instance_count; ULONG flags; }; struct wmilib_context { ULONG guid_count; struct wmi_guid_reg_info *guid_list; void *query_wmi_reg_info; void *query_wmi_data_block; void *set_wmi_data_block; void *set_wmi_data_item; void *execute_wmi_method; void *wmi_function_control; }; enum key_value_information_class { KeyValueBasicInformation, KeyValueFullInformation, KeyValuePartialInformation, KeyValueFullInformationAlign64, KeyValuePartialInformationAlign64 }; struct object_attr { ULONG length; void *root_dir; struct unicode_string *name; ULONG attr; void *security_descriptor; void *security_qos; }; struct file_name_info { ULONG length; wchar_t *name; }; struct file_std_info { LARGE_INTEGER alloc_size; LARGE_INTEGER eof; ULONG num_links; BOOLEAN delete_pending; BOOLEAN dir; }; enum nt_obj_type { NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, NT_OBJ_SEMAPHORE, }; enum common_object_type { OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, }; struct common_object_header { struct nt_list list; enum common_object_type type; UINT size; UINT ref_count; BOOLEAN close_in_process; BOOLEAN permanent; struct unicode_string name; }; #define OBJECT_TO_HEADER(object) \ (struct common_object_header *)((void *)(object) - \ sizeof(struct common_object_header)) #define OBJECT_SIZE(size) \ ((size) + sizeof(struct common_object_header)) #define HEADER_TO_OBJECT(hdr) \ ((void *)(hdr) + sizeof(struct common_object_header)) #define HANDLE_TO_OBJECT(handle) HEADER_TO_OBJECT(handle) #define HANDLE_TO_HEADER(handle) (handle) enum work_queue_type { CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, MaximumWorkQueue }; typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall; struct io_workitem { enum work_queue_type type; struct device_object *dev_obj; NTOS_WORK_FUNC worker_routine; void *context; }; struct io_workitem_entry { struct nt_list list; struct io_workitem *io_workitem; }; enum mm_page_priority { LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 }; enum kinterrupt_mode { LevelSensitive, Latched }; enum ntos_wait_reason { Executive, FreePage, PageIn, PoolAllocation, DelayExecution, Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel, MaximumWaitReason }; typedef enum ntos_wait_reason KWAIT_REASON; typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type, SIZE_T size, ULONG tag) wstdcall; typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall; struct npaged_lookaside_list { nt_slist_header head; USHORT depth; USHORT maxdepth; ULONG totalallocs; union { ULONG allocmisses; ULONG allochits; } u1; ULONG totalfrees; union { ULONG freemisses; ULONG freehits; } u2; enum pool_type pool_type; ULONG tag; ULONG size; LOOKASIDE_ALLOC_FUNC *alloc_func; LOOKASIDE_FREE_FUNC *free_func; struct nt_list list; ULONG lasttotallocs; union { ULONG lastallocmisses; ULONG lastallochits; } u3; ULONG pad[2]; #ifndef CONFIG_X86_64 NT_SPIN_LOCK obsolete; #endif } #ifdef CONFIG_X86_64 CACHE_ALIGN #endif ; enum device_registry_property { DevicePropertyDeviceDescription, DevicePropertyHardwareID, DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, DevicePropertyBootConfigurationTranslated, DevicePropertyClassName, DevicePropertyClassGuid, DevicePropertyDriverKeyName, DevicePropertyManufacturer, DevicePropertyFriendlyName, DevicePropertyLocationInformation, DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, DevicePropertyLegacyBusType, DevicePropertyBusNumber, DevicePropertyEnumeratorName, DevicePropertyAddress, DevicePropertyUINumber, DevicePropertyInstallState, DevicePropertyRemovalPolicy }; enum trace_information_class { TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, AllLoggerHandlesClass, TraceHandleByNameClass }; struct kinterrupt; typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt, void *context) wstdcall; typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall; struct kinterrupt { ULONG vector; KAFFINITY processor_enable_mask; NT_SPIN_LOCK lock; NT_SPIN_LOCK *actual_lock; BOOLEAN shareable; BOOLEAN floating_save; CHAR processor_number; PKSERVICE_ROUTINE service_routine; void *service_context; struct nt_list list; KIRQL irql; KIRQL synch_irql; enum kinterrupt_mode interrupt_mode; }; struct time_fields { CSHORT year; CSHORT month; CSHORT day; CSHORT hour; CSHORT minute; CSHORT second; CSHORT milliseconds; CSHORT weekday; }; struct object_attributes { ULONG length; void *root_dir; struct unicode_string *name; ULONG attributes; void *security_descr; void *security_qos; }; typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1, void *arg2) wstdcall; struct callback_object; struct callback_func { PCALLBACK_FUNCTION func; void *context; struct nt_list list; struct callback_object *object; }; struct callback_object { NT_SPIN_LOCK lock; struct nt_list list; struct nt_list callback_funcs; BOOLEAN allow_multiple_callbacks; struct object_attributes *attributes; }; struct ksystem_time { ULONG low_part; LONG high1_time; LONG high2_time; }; enum nt_product_type { nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server }; enum alt_arch_type { arch_type_standard, arch_type_nex98x86, end_alternatives }; struct kuser_shared_data { ULONG tick_count; ULONG tick_count_multiplier; volatile struct ksystem_time interrupt_time; volatile struct ksystem_time system_time; volatile struct ksystem_time time_zone_bias; USHORT image_number_low; USHORT image_number_high; wchar_t nt_system_root[260]; ULONG max_stack_trace_depth; ULONG crypto_exponent; ULONG time_zone_id; ULONG large_page_min; ULONG reserved2[7]; enum nt_product_type nt_product_type; BOOLEAN product_type_is_valid; ULONG nt_major_version; ULONG nt_minor_version; BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; ULONG reserved1; ULONG reserved3; volatile LONG time_slip; enum alt_arch_type alt_arch_type; LARGE_INTEGER system_expiration_date; ULONG suite_mask; BOOLEAN kdbg_enabled; volatile ULONG active_console; volatile ULONG dismount_count; ULONG com_plus_package; ULONG last_system_rite_event_tick_count; ULONG num_phys_pages; BOOLEAN safe_boot_mode; ULONG trace_log; ULONGLONG fill0; ULONGLONG sys_call[4]; union { volatile struct ksystem_time tick_count; volatile ULONG64 tick_count_quad; } tick; }; #define REG_NONE (0) #define REG_SZ (1) #define REG_EXPAND_SZ (2) #define REG_BINARY (3) #define REG_DWORD (4) #define RTL_REGISTRY_ABSOLUTE 0 #define RTL_REGISTRY_SERVICES 1 #define RTL_REGISTRY_CONTROL 2 #define RTL_REGISTRY_WINDOWS_NT 3 #define RTL_REGISTRY_DEVICEMAP 4 #define RTL_REGISTRY_USER 5 #define RTL_REGISTRY_MAXIMUM 6 #define RTL_REGISTRY_HANDLE 0x40000000 #define RTL_REGISTRY_OPTIONAL 0x80000000 #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 #define RTL_QUERY_REGISTRY_DIRECT 0x00000020 #define RTL_QUERY_REGISTRY_DELETE 0x00000040 typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type, void *data, ULONG length, void *context, void *entry) wstdcall; struct rtl_query_registry_table { PRTL_QUERY_REGISTRY_ROUTINE query_func; ULONG flags; wchar_t *name; void *context; ULONG def_type; void *def_data; ULONG def_length; }; struct io_remove_lock { BOOLEAN removed; BOOLEAN reserved[3]; LONG io_count; struct nt_event remove_event; }; struct io_error_log_packet { UCHAR major_fn_code; UCHAR retry_count; USHORT dump_data_size; USHORT nr_of_strings; USHORT string_offset; USHORT event_category; NTSTATUS error_code; ULONG unique_error_value; NTSTATUS final_status; ULONG sequence_number; ULONG io_control_code; LARGE_INTEGER device_offset; ULONG dump_data[1]; }; /* some of the functions below are slightly different from DDK's * implementation; e.g., Insert functions return appropriate * pointer */ /* instead of using Linux's lists, we implement list manipulation * functions because nt_list is used by drivers and we don't want to * worry about Linux's list being different from nt_list (right now * they are same, but in future they could be different) */ static inline void InitializeListHead(struct nt_list *head) { head->next = head->prev = head; } static inline BOOLEAN IsListEmpty(struct nt_list *head) { if (head == head->next) return TRUE; else return FALSE; } static inline void RemoveEntryList(struct nt_list *entry) { entry->prev->next = entry->next; entry->next->prev = entry->prev; } static inline struct nt_list *RemoveHeadList(struct nt_list *head) { struct nt_list *entry; entry = head->next; if (entry == head) return NULL; else { RemoveEntryList(entry); return entry; } } static inline struct nt_list *RemoveTailList(struct nt_list *head) { struct nt_list *entry; entry = head->prev; if (entry == head) return NULL; else { RemoveEntryList(entry); return entry; } } static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev, struct nt_list *next) { next->prev = entry; entry->next = next; entry->prev = prev; prev->next = entry; } static inline struct nt_list *InsertHeadList(struct nt_list *head, struct nt_list *entry) { struct nt_list *ret; if (IsListEmpty(head)) ret = NULL; else ret = head->next; InsertListEntry(entry, head, head->next); return ret; } static inline struct nt_list *InsertTailList(struct nt_list *head, struct nt_list *entry) { struct nt_list *ret; if (IsListEmpty(head)) ret = NULL; else ret = head->prev; InsertListEntry(entry, head->prev, head); return ret; } #define nt_list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #define nt_list_for_each_entry(pos, head, member) \ for (pos = container_of((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = container_of(pos->member.next, typeof(*pos), member)) #define nt_list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) /* device object flags */ #define DO_VERIFY_VOLUME 0x00000002 #define DO_BUFFERED_IO 0x00000004 #define DO_EXCLUSIVE 0x00000008 #define DO_DIRECT_IO 0x00000010 #define DO_MAP_IO_BUFFER 0x00000020 #define DO_DEVICE_HAS_NAME 0x00000040 #define DO_DEVICE_INITIALIZING 0x00000080 #define DO_SYSTEM_BOOT_PARTITION 0x00000100 #define DO_LONG_TERM_REQUESTS 0x00000200 #define DO_NEVER_LAST_DEVICE 0x00000400 #define DO_SHUTDOWN_REGISTERED 0x00000800 #define DO_BUS_ENUMERATED_DEVICE 0x00001000 #define DO_POWER_PAGABLE 0x00002000 #define DO_POWER_INRUSH 0x00004000 #define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 /* Various supported device types (used with IoCreateDevice()) */ #define FILE_DEVICE_BEEP 0x00000001 #define FILE_DEVICE_CD_ROM 0x00000002 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 #define FILE_DEVICE_CONTROLLER 0x00000004 #define FILE_DEVICE_DATALINK 0x00000005 #define FILE_DEVICE_DFS 0x00000006 #define FILE_DEVICE_DISK 0x00000007 #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 #define FILE_DEVICE_FILE_SYSTEM 0x00000009 #define FILE_DEVICE_INPORT_PORT 0x0000000A #define FILE_DEVICE_KEYBOARD 0x0000000B #define FILE_DEVICE_MAILSLOT 0x0000000C #define FILE_DEVICE_MIDI_IN 0x0000000D #define FILE_DEVICE_MIDI_OUT 0x0000000E #define FILE_DEVICE_MOUSE 0x0000000F #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 #define FILE_DEVICE_NAMED_PIPE 0x00000011 #define FILE_DEVICE_NETWORK 0x00000012 #define FILE_DEVICE_NETWORK_BROWSER 0x00000013 #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 #define FILE_DEVICE_NULL 0x00000015 #define FILE_DEVICE_PARALLEL_PORT 0x00000016 #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 #define FILE_DEVICE_PRINTER 0x00000018 #define FILE_DEVICE_SCANNER 0x00000019 #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A #define FILE_DEVICE_SERIAL_PORT 0x0000001B #define FILE_DEVICE_SCREEN 0x0000001C #define FILE_DEVICE_SOUND 0x0000001D #define FILE_DEVICE_STREAMS 0x0000001E #define FILE_DEVICE_TAPE 0x0000001F #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 #define FILE_DEVICE_TRANSPORT 0x00000021 #define FILE_DEVICE_UNKNOWN 0x00000022 #define FILE_DEVICE_VIDEO 0x00000023 #define FILE_DEVICE_VIRTUAL_DISK 0x00000024 #define FILE_DEVICE_WAVE_IN 0x00000025 #define FILE_DEVICE_WAVE_OUT 0x00000026 #define FILE_DEVICE_8042_PORT 0x00000027 #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 #define FILE_DEVICE_BATTERY 0x00000029 #define FILE_DEVICE_BUS_EXTENDER 0x0000002A #define FILE_DEVICE_MODEM 0x0000002B #define FILE_DEVICE_VDM 0x0000002C #define FILE_DEVICE_MASS_STORAGE 0x0000002D #define FILE_DEVICE_SMB 0x0000002E #define FILE_DEVICE_KS 0x0000002F #define FILE_DEVICE_CHANGER 0x00000030 #define FILE_DEVICE_SMARTCARD 0x00000031 #define FILE_DEVICE_ACPI 0x00000032 #define FILE_DEVICE_DVD 0x00000033 #define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 #define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 #define FILE_DEVICE_DFS_VOLUME 0x00000036 #define FILE_DEVICE_SERENUM 0x00000037 #define FILE_DEVICE_TERMSRV 0x00000038 #define FILE_DEVICE_KSEC 0x00000039 #define FILE_DEVICE_FIPS 0x0000003A /* Device characteristics */ #define FILE_REMOVABLE_MEDIA 0x00000001 #define FILE_READ_ONLY_DEVICE 0x00000002 #define FILE_FLOPPY_DISKETTE 0x00000004 #define FILE_WRITE_ONCE_MEDIA 0x00000008 #define FILE_REMOTE_DEVICE 0x00000010 #define FILE_DEVICE_IS_MOUNTED 0x00000020 #define FILE_VIRTUAL_VOLUME 0x00000040 #define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 #define FILE_DEVICE_SECURE_OPEN 0x00000100 #define FILE_READ_DATA 0x0001 #define FILE_WRITE_DATA 0x0002 #define FILE_SUPERSEDED 0x00000000 #define FILE_OPENED 0x00000001 #define FILE_CREATED 0x00000002 #define FILE_OVERWRITTEN 0x00000003 #define FILE_EXISTS 0x00000004 #define FILE_DOES_NOT_EXIST 0x00000005 #endif /* WINNT_TYPES_H */