misc_funcs.c
来自「改文件可以安装无线网卡在linux下的驱动,大家可以在网站上查找一下用法」· C语言 代码 · 共 934 行 · 第 1/2 页
C
934 行
/* * 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. * */#include <linux/types.h>#include <linux/module.h>#include <linux/delay.h>#include <asm/io.h>#include <linux/ctype.h>#include <linux/net.h>#include <linux/list.h>#include "ndis.h"static struct list_head wrap_allocs;static KSPIN_LOCK wrap_allocs_lock;int misc_funcs_init(void){ INIT_LIST_HEAD(&wrap_allocs); kspin_lock_init(&wrap_allocs_lock); return 0;}/* called when a handle is being removed */void misc_funcs_exit_handle(struct ndis_handle *handle){ char canceled; KIRQL irql; /* cancel any timers left by bugyy windows driver * Also free the memory for timers */ while (1) { struct wrapper_timer *timer; irql = kspin_lock_irql(&handle->timers_lock, DISPATCH_LEVEL); if (list_empty(&handle->timers)) { kspin_unlock_irql(&handle->timers_lock, irql); break; } timer = list_entry(handle->timers.next, struct wrapper_timer, list); list_del(&timer->list); kspin_unlock_irql(&handle->timers_lock, irql); DBGTRACE1("fixing up timer %p, timer->list %p", timer, &timer->list); wrapper_cancel_timer(timer, &canceled); wrap_kfree(timer); }}/* called when module is being removed */void misc_funcs_exit(void){ /* free all pointers on the allocated list */ kspin_lock(&wrap_allocs_lock); while (!list_empty(&wrap_allocs)) { struct wrap_alloc *alloc; alloc = list_entry(wrap_allocs.next, struct wrap_alloc, list); list_del(&alloc->list); kfree(alloc->ptr); kfree(alloc); } kspin_unlock(&wrap_allocs_lock); TRACEEXIT4(return);}/* allocate memory with given flags and add it to list of allocated pointers; * if a driver doesn't free this memory for any reason (buggy driver or we * allocate space behind driver's back since we need more space than * corresponding Windows structure provides etc.), this gets freed * automatically during module unloading */void *wrap_kmalloc(size_t size, int flags){ struct wrap_alloc *alloc; TRACEENTER4("size = %lu, flags = %d", (unsigned long)size, flags); if ((flags & GFP_ATOMIC) || irqs_disabled()) alloc = kmalloc(sizeof(*alloc), GFP_ATOMIC); else alloc = kmalloc(sizeof(*alloc), GFP_KERNEL); if (!alloc) return NULL; alloc->ptr = kmalloc(size, flags); if (!alloc->ptr) { kfree(alloc); return NULL; } kspin_lock(&wrap_allocs_lock); list_add(&alloc->list, &wrap_allocs); kspin_unlock(&wrap_allocs_lock); DBGTRACE4("%p, %p", alloc, alloc->ptr); TRACEEXIT4(return alloc->ptr);}/* free pointer and remove from list of allocated pointers */void wrap_kfree(void *ptr){ struct list_head *cur, *tmp; TRACEENTER4("%p", ptr); kspin_lock(&wrap_allocs_lock); list_for_each_safe(cur, tmp, &wrap_allocs) { struct wrap_alloc *alloc; alloc = list_entry(cur, struct wrap_alloc, list); if (alloc->ptr == ptr) { list_del(&alloc->list); kfree(alloc->ptr); kfree(alloc); break; } } kspin_unlock(&wrap_allocs_lock); TRACEEXIT4(return);}void wrapper_timer_handler(unsigned long data){ struct wrapper_timer *timer = (struct wrapper_timer *)data; struct kdpc *kdpc; STDCALL void (*miniport_timer)(void *specific1, void *ctx, void *specific2, void *specific3); KIRQL irql; TRACEENTER5("%p", timer);#ifdef DEBUG_TIMER BUG_ON(timer == NULL); BUG_ON(timer->wrapper_timer_magic != WRAPPER_TIMER_MAGIC); BUG_ON(timer->kdpc == NULL);#endif /* don't add the timer if aperiodic; see wrapper_cancel_timer * protect access to kdpc, repeat, and active via spinlock */ irql = kspin_lock_irql(&timer->lock, DISPATCH_LEVEL); kdpc = timer->kdpc; if (timer->repeat) { timer->timer.expires = jiffies + timer->repeat; add_timer(&timer->timer); } else timer->active = 0; kspin_unlock_irql(&timer->lock, irql); miniport_timer = kdpc->func; /* call the handler after restarting in case it cancels itself */ if (miniport_timer) { KIRQL irql; irql = raise_irql(DISPATCH_LEVEL); LIN2WIN4(miniport_timer, kdpc, kdpc->ctx, kdpc->arg1, kdpc->arg2); lower_irql(irql); } TRACEEXIT5(return);}void wrapper_init_timer(struct ktimer *ktimer, void *handle){ struct wrapper_timer *wrapper_timer; struct ndis_handle *ndis_handle = (struct ndis_handle *)handle; TRACEENTER5("%s", ""); wrapper_timer = wrap_kmalloc(sizeof(struct wrapper_timer), GFP_ATOMIC); if (!wrapper_timer) { ERROR("couldn't allocate memory for timer"); return; } memset(wrapper_timer, 27, sizeof(*wrapper_timer)); init_timer(&wrapper_timer->timer); wrapper_timer->timer.data = (unsigned long)wrapper_timer; wrapper_timer->timer.function = &wrapper_timer_handler; wrapper_timer->active = 0; wrapper_timer->repeat = 0; wrapper_timer->kdpc = NULL;#ifdef DEBUG_TIMER wrapper_timer->wrapper_timer_magic = WRAPPER_TIMER_MAGIC;#endif ktimer->wrapper_timer = wrapper_timer; kspin_lock_init(&wrapper_timer->lock); if (handle) { kspin_lock(&ndis_handle->timers_lock); list_add(&wrapper_timer->list, &ndis_handle->timers); kspin_unlock(&ndis_handle->timers_lock); } DBGTRACE4("added timer %p, wrapper_timer->list %p\n", wrapper_timer, &wrapper_timer->list); TRACEEXIT5(return);}int wrapper_set_timer(struct wrapper_timer *timer, unsigned long expires, unsigned long repeat, struct kdpc *kdpc){ KIRQL irql; TRACEENTER5("%p", timer); if (!timer) { ERROR("invalid timer"); return FALSE; }#ifdef DEBUG_TIMER if (timer->wrapper_timer_magic != WRAPPER_TIMER_MAGIC) { WARNING("timer %p is not initialized (%lu)", timer, timer->wrapper_timer_magic); timer->wrapper_timer_magic = WRAPPER_TIMER_MAGIC; }#endif /* timer handler also uses timer->repeat, active, and kdpc, so * protect in case of SMP */ irql = kspin_lock_irql(&timer->lock, DISPATCH_LEVEL); if (kdpc) timer->kdpc = kdpc; timer->repeat = repeat; if (timer->active) { DBGTRACE4("modifying timer %p to %lu, %lu", timer, expires, repeat); mod_timer(&timer->timer, expires); kspin_unlock_irql(&timer->lock, irql); TRACEEXIT5(return TRUE); } else { DBGTRACE4("setting timer %p to %lu, %lu", timer, expires, repeat); timer->timer.expires = expires; timer->active = 1; add_timer(&timer->timer); kspin_unlock_irql(&timer->lock, irql); TRACEEXIT5(return FALSE); }}void wrapper_cancel_timer(struct wrapper_timer *timer, char *canceled){ KIRQL irql; TRACEENTER4("timer = %p, canceled = %p", timer, canceled); if (!timer) { ERROR("%s", "invalid timer"); return; }#ifdef DEBUG_TIMER DBGTRACE4("canceling timer %p", timer); BUG_ON(timer->wrapper_timer_magic != WRAPPER_TIMER_MAGIC);#endif /* timer handler also uses timer->repeat, so protect it in * case of SMP */ /* Oh, and del_timer_sync is not required ('canceled' argument * tells the driver if the timer was deleted or not) here; nor * is del_timer_sync correct, as this function may be called * at DISPATCH_LEVEL */ irql = kspin_lock_irql(&timer->lock, DISPATCH_LEVEL); if (timer->repeat) { /* first mark as aperiodic, so timer function doesn't call * add_timer after del_timer returned */ timer->repeat = 0; del_timer(&timer->timer); /* periodic timers always return TRUE */ *canceled = TRUE; } else *canceled = del_timer(&timer->timer); kspin_unlock_irql(&timer->lock, irql); TRACEEXIT5(return);}NOREGPARM INT WRAP_EXPORT(_win_sprintf) (char *buf, const char *format, ...){ va_list args; int res; va_start(args, format); res = vsprintf(buf, format, args); va_end(args); return res;}NOREGPARM INT WRAP_EXPORT(_win_vsprintf) (char *str, const char *format, va_list ap){ return vsprintf(str, format, ap);}NOREGPARM INT WRAP_EXPORT(_win_snprintf) (char *buf, SIZE_T count, const char *format, ...){ va_list args; int res; va_start(args, format); res = vsnprintf(buf, count, format, args); va_end(args); return res;}NOREGPARM INT WRAP_EXPORT(_win__snprintf) (char *buf, SIZE_T count, const char *format, ...){ va_list args; int res; va_start(args, format); res = vsnprintf(buf, count, format, args); va_end(args); return res;}NOREGPARM INT WRAP_EXPORT(_win_vsnprintf) (char *str, SIZE_T size, const char *format, va_list ap){ return vsnprintf(str, size, format, ap);}NOREGPARM INT WRAP_EXPORT(_win__vsnprintf) (char *str, SIZE_T size, const char *format, va_list ap){ return vsnprintf(str, size, format, ap);}NOREGPARM char *WRAP_EXPORT(_win_strncpy) (char *dst, char *src, SIZE_T n){ return strncpy(dst, src, n);}NOREGPARM SIZE_T WRAP_EXPORT(_win_strlen) (const char *s){ return strlen(s);}NOREGPARM INT WRAP_EXPORT(_win_strncmp) (const char *s1, const char *s2, SIZE_T n){ return strncmp(s1, s2, n);}NOREGPARM INT WRAP_EXPORT(_win_strcmp) (const char *s1, const char *s2){ return strcmp(s1, s2);}int stricmp(const char *s1, const char *s2){ while (*s1 && *s2 && tolower(*s1) == tolower(*s2)) { s1++; s2++; } return (int)*s1 - (int)*s2;}NOREGPARM INT WRAP_EXPORT(_win_tolower) (INT c){ return tolower(c);}NOREGPARM INT WRAP_EXPORT(_win_toupper) (INT c){ return toupper(c);}NOREGPARM void *WRAP_EXPORT(_win_memcpy) (void *to, const void *from, SIZE_T n){ return memcpy(to, from, n);}NOREGPARM void *WRAP_EXPORT(_win_strcpy) (void *to, const void *from){ return strcpy(to, from);}NOREGPARM char *WRAP_EXPORT(_win_strstr) (const char *s1, const char *s2){ return strstr(s1, s2);}NOREGPARM char *WRAP_EXPORT(_win_strchr) (const char *s, int c){ return strchr(s, c);}NOREGPARM void *WRAP_EXPORT(_win_memset) (void *s, char c, SIZE_T count){ return memset(s, c, count);}NOREGPARM void *WRAP_EXPORT(_win_memmove) (void *to, void *from, SIZE_T count){ return memmove(to, from, count);}NOREGPARM void *WRAP_EXPORT(_win_memchr) (const void *s, INT c, SIZE_T n){ return memchr(s, c, n);}NOREGPARM void WRAP_EXPORT(_win_srand) (UINT seed){ net_srandom(seed);}NOREGPARM int WRAP_EXPORT(_win_atoi) (const char *ptr){ int i = simple_strtol(ptr, NULL, 10); return i;}STDCALL s64 WRAP_EXPORT(_alldiv) (s64 a, s64 b){ return (a / b);}STDCALL u64 WRAP_EXPORT(_aulldiv) (u64 a, u64 b){ return (a / b);}STDCALL s64 WRAP_EXPORT(_allmul) (s64 a, s64 b){ return (a * b);}STDCALL u64 WRAP_EXPORT(_aullmul) (u64 a, u64 b){ return (a * b);}STDCALL s64 WRAP_EXPORT(_allrem) (s64 a, s64 b){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?