📄 ntoskernel.h
字号:
#define wrap_kmem_cache_create(name, size, align, flags) \ kmem_cache_create(name, size, align, flags, NULL)#endif#include "winnt_types.h"#include "ndiswrapper.h"#include "pe_linker.h"#include "wrapmem.h"#include "lin2win.h"#include "loader.h"#include "compat.h"#if !defined(CONFIG_USB) && defined(CONFIG_USB_MODULE)#define CONFIG_USB 1#endif#if defined(DISABLE_USB)#undef CONFIG_USB#undef CONFIG_USB_MODULE#endif/* TICK is 100ns */#define TICKSPERSEC 10000000#define TICKSPERMSEC 10000#define SECSPERDAY 86400#define TICKSPERJIFFY ((TICKSPERSEC + HZ - 1) / HZ)#define int_div_round(x, y) (((x) + (y - 1)) / (y))/* 1601 to 1970 is 369 years plus 89 leap days */#define SECS_1601_TO_1970 ((369 * 365 + 89) * (u64)SECSPERDAY)#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)/* 100ns units to HZ; if sys_time is negative, relative to current * clock, otherwise from year 1601 */#define SYSTEM_TIME_TO_HZ(sys_time) \ (((sys_time) <= 0) ? \ int_div_round(((u64)HZ * (-(sys_time))), TICKSPERSEC) : \ int_div_round(((s64)HZ * ((sys_time) - ticks_1601())), TICKSPERSEC))#define MSEC_TO_HZ(ms) int_div_round((ms * HZ), 1000)#define USEC_TO_HZ(us) int_div_round((us * HZ), 1000000)extern u64 wrap_ticks_to_boot;static inline u64 ticks_1601(void){ return wrap_ticks_to_boot + (u64)jiffies * TICKSPERJIFFY;}typedef void (*generic_func)(void);struct wrap_export { const char *name; generic_func func;};#ifdef CONFIG_X86_64#define WIN_SYMBOL(name, argc) \ {#name, (generic_func) win2lin_ ## name ## _ ## argc}#define WIN_WIN_SYMBOL(name, argc) \ {#name, (generic_func) win2lin__win_ ## name ## _ ## argc}#define WIN_FUNC_DECL(name, argc) \ typeof(name) win2lin_ ## name ## _ ## argc;#define WIN_FUNC_PTR(name, argc) win2lin_ ## name ## _ ## argc#else#define WIN_SYMBOL(name, argc) {#name, (generic_func)name}#define WIN_WIN_SYMBOL(name, argc) {#name, (generic_func)_win_ ## name}#define WIN_FUNC_DECL(name, argc)#define WIN_FUNC_PTR(name, argc) name#endif#define WIN_FUNC(name, argc) name/* map name s to f - if f is different from s */#define WIN_SYMBOL_MAP(s, f)#define POOL_TAG(A, B, C, D) \ ((ULONG)((A) + ((B) << 8) + ((C) << 16) + ((D) << 24)))struct pe_image { char name[MAX_DRIVER_NAME_LEN]; UINT (*entry)(struct driver_object *, struct unicode_string *) wstdcall; void *image; int size; int type; IMAGE_NT_HEADERS *nt_hdr; IMAGE_OPTIONAL_HEADER *opt_hdr;};struct ndis_mp_block;struct wrap_timer { struct nt_slist slist; struct timer_list timer; struct nt_timer *nt_timer; long repeat;#ifdef TIMER_DEBUG unsigned long wrap_timer_magic;#endif};struct ntos_work_item { struct nt_list list; void *arg1; void *arg2; NTOS_WORK_FUNC func;};struct wrap_device_setting { struct nt_list list; char name[MAX_SETTING_NAME_LEN]; char value[MAX_SETTING_VALUE_LEN]; void *encoded;};struct wrap_bin_file { char name[MAX_DRIVER_NAME_LEN]; size_t size; void *data;};#define WRAP_DRIVER_CLIENT_ID 1struct wrap_driver { struct nt_list list; struct driver_object *drv_obj; char name[MAX_DRIVER_NAME_LEN]; char version[MAX_SETTING_VALUE_LEN]; unsigned short num_pe_images; struct pe_image pe_images[MAX_DRIVER_PE_IMAGES]; unsigned short num_bin_files; struct wrap_bin_file *bin_files; struct nt_list wrap_devices; struct nt_list settings; int dev_type; struct wrap_ndis_driver *ndis_driver;};enum hw_status { HW_INITIALIZED = 1, HW_SUSPENDED, HW_HALTED, HW_PRESENT,};struct wrap_device { /* first part is (de)initialized once by loader */ struct nt_list list; int dev_bus; int vendor; int device; int subvendor; int subdevice; char conf_file_name[MAX_DRIVER_NAME_LEN]; char driver_name[MAX_DRIVER_NAME_LEN]; struct wrap_driver *driver; struct nt_list settings; /* rest should be (de)initialized when a device is * (un)plugged */ struct cm_resource_list *resource_list; unsigned long hw_status; struct device_object *pdo; union { struct { struct pci_dev *pdev; enum device_power_state wake_state;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9) u32 pci_state[16];#endif } pci; struct { struct usb_device *udev; struct usb_interface *intf; int num_alloc_urbs; struct nt_list wrap_urb_list; } usb; }; union { struct wrap_ndis_device *wnd; };};#define wrap_is_pci_bus(dev_bus) \ (WRAP_BUS(dev_bus) == WRAP_PCI_BUS || \ WRAP_BUS(dev_bus) == WRAP_PCMCIA_BUS)#ifdef CONFIG_USB/* earlier versions of ndiswrapper used 0 as USB_BUS */#define wrap_is_usb_bus(dev_bus) \ (WRAP_BUS(dev_bus) == WRAP_USB_BUS || \ WRAP_BUS(dev_bus) == WRAP_INTERNAL_BUS)#else#define wrap_is_usb_bus(dev_bus) 0#endif#define wrap_is_bluetooth_device(dev_bus) \ (WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE1 || \ WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE2)#ifdef WRAP_WQ#define NTOS_WQ 1#endif#define NTOS_WQ 1#ifdef NTOS_WQextern workqueue_struct_t *ntos_wq;#define schedule_ntos_work(work_struct) queue_work(ntos_wq, work_struct)#define schedule_work(work_struct) queue_work(ntos_wq, work_struct)#else#define schedule_ntos_work(work_struct) schedule_work(work_struct)#endifextern workqueue_struct_t *ndis_wq;#define schedule_ndis_work(work_struct) queue_work(ndis_wq, work_struct)extern workqueue_struct_t *wrapndis_wq;#define schedule_wrapndis_work(work_struct) queue_work(wrapndis_wq, work_struct)#define atomic_unary_op(var, size, oper) \do { \ if (size == 1) \ __asm__ __volatile__( \ LOCK_PREFIX oper "b %b0\n\t" : "+m" (var)); \ else if (size == 2) \ __asm__ __volatile__( \ LOCK_PREFIX oper "w %w0\n\t" : "+m" (var)); \ else if (size == 4) \ __asm__ __volatile__( \ LOCK_PREFIX oper "l %0\n\t" : "+m" (var)); \ else if (size == 8) \ __asm__ __volatile__( \ LOCK_PREFIX oper "q %q0\n\t" : "+m" (var)); \ else { \ extern void _invalid_op_size_(void); \ _invalid_op_size_(); \ } \} while (0)#define atomic_inc_var_size(var, size) atomic_unary_op(var, size, "inc")#define atomic_inc_var(var) atomic_inc_var_size(var, sizeof(var))#define atomic_dec_var_size(var, size) atomic_unary_op(var, size, "dec")#define atomic_dec_var(var) atomic_dec_var_size(var, sizeof(var))#define pre_atomic_add(var, i) \({ \ typeof(var) pre; \ __asm__ __volatile__( \ LOCK_PREFIX "xadd %0, %1\n\t" \ : "=r"(pre), "+m"(var) \ : "0"(i)); \ pre; \})#define post_atomic_add(var, i) (pre_atomic_add(var, i) + i)#ifndef in_atomic#define in_atomic() in_interrupt()#endif#ifndef preempt_enable_no_resched#define preempt_enable_no_resched() preempt_enable()#endif//#define DEBUG_IRQL 1#ifdef DEBUG_IRQL#define assert_irql(cond) \do { \ KIRQL _irql_ = current_irql(); \ if (!(cond)) { \ WARNING("assertion '%s' failed: %d", #cond, _irql_); \ DBG_BLOCK(4) { \ dump_stack(); \ } \ } \} while (0)#else#define assert_irql(cond) do { } while (0)#endif/* When preempt is enabled, we should preempt_disable to raise IRQL to * DISPATCH_LEVEL, to be consistent with the semantics. However, using * a mutex instead, so that only ndiswrapper threads run one at a time * on a processor when at DISPATCH_LEVEL seems to be enough. So that * is what we will use until we learn otherwise. If * preempt_(en|dis)able is required for some reason, comment out * following #define. */#define WRAP_PREEMPT 1#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_RT)#ifndef WRAP_PREEMPT#define WRAP_PREEMPT 1#endif#endif#ifdef WRAP_PREEMPTtypedef struct { int count; struct mutex lock;#ifdef CONFIG_SMP typeof(current->cpus_allowed) cpus_allowed;#endif struct task_struct *task;} irql_info_t;DECLARE_PER_CPU(irql_info_t, irql_info);static inline KIRQL raise_irql(KIRQL newirql){ irql_info_t *info; assert(newirql == DISPATCH_LEVEL); info = &get_cpu_var(irql_info); if (info->task == current) { assert(info->count > 0); assert(mutex_is_locked(&info->lock));#if defined(CONFIG_SMP) && defined(DEBUG) do { cpumask_t cpumask; cpumask = cpumask_of_cpu(smp_processor_id()); cpus_xor(cpumask, cpumask, current->cpus_allowed); assert(cpus_empty(cpumask)); } while (0);#endif info->count++; put_cpu_var(irql_info); return DISPATCH_LEVEL; } /* TODO: is this enough to pin down to current cpu? */#ifdef CONFIG_SMP assert(task_cpu(current) == smp_processor_id()); info->cpus_allowed = current->cpus_allowed; current->cpus_allowed = cpumask_of_cpu(smp_processor_id());#endif put_cpu_var(irql_info); mutex_lock(&info->lock); assert(info->count == 0); assert(info->task == NULL); info->count = 1; info->task = current; return PASSIVE_LEVEL;}static inline void lower_irql(KIRQL oldirql){ irql_info_t *info; assert(oldirql <= DISPATCH_LEVEL); info = &get_cpu_var(irql_info); assert(info->task == current); assert(mutex_is_locked(&info->lock)); assert(info->count > 0); if (--info->count == 0) { info->task = NULL;#ifdef CONFIG_SMP current->cpus_allowed = info->cpus_allowed;#endif mutex_unlock(&info->lock); } put_cpu_var(irql_info);}static inline KIRQL current_irql(void){ int count; if (in_irq() || irqs_disabled()) EXIT4(return DIRQL); if (in_atomic() || in_interrupt()) EXIT4(return SOFT_IRQL); count = get_cpu_var(irql_info).count; put_cpu_var(irql_info); if (count) EXIT6(return DISPATCH_LEVEL); else EXIT6(return PASSIVE_LEVEL);}#elsestatic inline KIRQL current_irql(void){ if (in_irq() || irqs_disabled()) EXIT4(return DIRQL); if (in_interrupt()) EXIT4(return SOFT_IRQL); if (in_atomic()) EXIT6(return DISPATCH_LEVEL); else EXIT6(return PASSIVE_LEVEL);}static inline KIRQL raise_irql(KIRQL newirql){ KIRQL ret = in_atomic() ? DISPATCH_LEVEL : PASSIVE_LEVEL; assert(newirql == DISPATCH_LEVEL); assert(current_irql() <= DISPATCH_LEVEL); preempt_disable(); return ret;}static inline void lower_irql(KIRQL oldirql)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -