⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntoskernel.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
wstdcall void WIN_FUNC(KeQueryTickCount,1)	(LARGE_INTEGER *count){	*count = jiffies;}wstdcall LARGE_INTEGER WIN_FUNC(KeQueryPerformanceCounter,1)	(LARGE_INTEGER *counter){	if (counter)		*counter = HZ;	return jiffies;}wstdcall struct task_struct *WIN_FUNC(KeGetCurrentThread,0)	(void){	struct task_struct *task = current;	TRACE2("task: %p, %d", task, task->pid);	return task;}wstdcall KPRIORITY WIN_FUNC(KeQueryPriorityThread,1)	(struct task_struct *task){	KPRIORITY prio;	TRACE2("task: %p, %d", task, task->pid);	if (thread_priority(task) <= 0)		prio = LOW_PRIORITY;	else if (thread_priority(task) <= -5)		prio = LOW_REALTIME_PRIORITY;	else		prio = MAXIMUM_PRIORITY;	TRACE2("%d", prio);	return prio;}wstdcall KPRIORITY WIN_FUNC(KeSetPriorityThread,2)	(struct task_struct *task, KPRIORITY priority){	KPRIORITY old_prio;	TRACE2("task: %p, %d, priority = %u", task, task->pid, priority);	if (thread_priority(task) <= 0)		old_prio = LOW_PRIORITY;	else if (thread_priority(task) <= -5)		old_prio = LOW_REALTIME_PRIORITY;	else		old_prio = MAXIMUM_PRIORITY;	if (priority == LOW_PRIORITY)		set_thread_priority(task, 0);	else if (priority == LOW_REALTIME_PRIORITY)		set_thread_priority(task, -5);	else if (priority == HIGH_PRIORITY)		set_thread_priority(task, -10);	TRACE2("%d, %d", old_prio, thread_priority(task));	return old_prio;}struct nt_thread *get_current_nt_thread(void){	struct task_struct *task = current;	struct nt_thread *thread;	struct common_object_header *header;	KIRQL irql;	TRACE6("task: %p", task);	thread = NULL;	irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);	nt_list_for_each_entry(header, &object_list, list) {		TRACE6("header: %p, type: %d", header, header->type);		if (header->type != OBJECT_TYPE_NT_THREAD)			break;		thread = HEADER_TO_OBJECT(header);		TRACE6("thread: %p, task: %p", thread, thread->task);		if (thread->task == task)			break;		else			thread = NULL;	}	nt_spin_unlock_irql(&ntoskernel_lock, irql);	if (thread == NULL)		TRACE4("couldn't find thread for task %p, %d", task, task->pid);	TRACE6("thread: %p", thread);	return thread;}struct thread_trampoline_info {	void (*func)(void *) wstdcall;	void *ctx;	struct nt_thread *thread;	struct completion started;};static int thread_trampoline(void *data){	struct thread_trampoline_info *thread_info = data;	typeof(thread_info->func) func;	void *ctx;	func = thread_info->func;	ctx = thread_info->ctx;	thread_info->thread->task = current;	thread_info->thread->pid = current->pid;	TRACE2("thread: %p, task: %p (%d)", thread_info->thread,	       current, current->pid);	complete(&thread_info->started);#ifdef PF_NOFREEZE	current->flags |= PF_NOFREEZE;#endif	strncpy(current->comm, "windisdrvr", sizeof(current->comm));	current->comm[sizeof(current->comm)-1] = 0;	LIN2WIN1(func, ctx);	ERROR("task: %p", current);	return 0;}wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7)	(void **phandle, ULONG access, void *obj_attr, void *process,	 void *client_id, void (*func)(void *) wstdcall, void *ctx){	struct nt_thread *thread;	struct thread_trampoline_info thread_info;	no_warn_unused struct task_struct *task;	no_warn_unused int pid;	ENTER2("phandle = %p, access = %u, obj_attr = %p, process = %p, "	       "client_id = %p, func = %p, context = %p", phandle, access,	       obj_attr, process, client_id, func, ctx);	thread = allocate_object(sizeof(*thread), OBJECT_TYPE_NT_THREAD, NULL);	if (!thread) {		ERROR("couldn't allocate thread object");		EXIT2(return STATUS_RESOURCES);	}	thread->task = NULL;	thread->pid = 0;	nt_spin_lock_init(&thread->lock);	InitializeListHead(&thread->irps);	initialize_object(&thread->dh, ThreadObject, 0);	thread->dh.size = sizeof(*thread);	TRACE2("thread: %p", thread);	thread_info.thread = thread;	thread_info.func = func;	thread_info.ctx = ctx;	init_completion(&thread_info.started);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)	pid = kernel_thread(thread_trampoline, &thread_info, CLONE_SIGHAND);	TRACE2("pid = %d", pid);	if (pid < 0) {		free_object(thread_info.thread);		EXIT2(return STATUS_FAILURE);	}	TRACE2("created task: %d", pid);#else	task = kthread_run(thread_trampoline, &thread_info, "windisdrvr");	if (IS_ERR(task)) {		free_object(thread_info.thread);		EXIT2(return STATUS_FAILURE);	}	TRACE2("created task: %p (%d)", task, task->pid);#endif	wait_for_completion(&thread_info.started);	*phandle = OBJECT_TO_HEADER(thread_info.thread);	TRACE2("created thread: %p, %p", thread_info.thread, *phandle);	EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1)	(NTSTATUS status){	struct nt_thread *thread;	TRACE2("%p, %08X", current, status);	thread = get_current_nt_thread();	if (!thread) {		ERROR("couldn't find thread for task: %p", current);		return STATUS_FAILURE;	}	TRACE2("setting event for thread: %p", thread);	KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE);	TRACE2("set event for thread: %p", thread);	while (1) {		struct nt_list *ent;		struct irp *irp;		KIRQL irql;		irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);		ent = RemoveHeadList(&thread->irps);		nt_spin_unlock_irql(&thread->lock, irql);		if (!ent)			break;		irp = container_of(ent, struct irp, thread_list);		IOTRACE("%p", irp);		IoCancelIrp(irp);	}	/* the driver may later query this status with	 * ZwQueryInformationThread */	thread->status = status;	complete_and_exit(NULL, status);	ERROR("oops: %p, %d", thread->task, thread->pid);	return STATUS_FAILURE;}wstdcall BOOLEAN WIN_FUNC(KeRemoveEntryDeviceQueue,2)	(struct kdevice_queue *dev_queue, struct kdevice_queue_entry *entry){	struct kdevice_queue_entry *e;	KIRQL irql;	irql = nt_spin_lock_irql(&dev_queue->lock, DISPATCH_LEVEL);	nt_list_for_each_entry(e, &dev_queue->list, list) {		if (e == entry) {			RemoveEntryList(&e->list);			nt_spin_unlock_irql(&dev_queue->lock, irql);			return TRUE;		}	}	nt_spin_unlock_irql(&dev_queue->lock, irql);	return FALSE;}wstdcall BOOLEAN WIN_FUNC(KeSynchronizeExecution,3)	(struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine,	 void *ctx){	BOOLEAN ret;	unsigned long flags;	nt_spin_lock_irqsave(&interrupt->lock, flags);	ret = LIN2WIN1(synch_routine, ctx);	nt_spin_unlock_irqrestore(&interrupt->lock, flags);	return ret;}wstdcall void *WIN_FUNC(MmAllocateContiguousMemorySpecifyCache,5)	(SIZE_T size, PHYSICAL_ADDRESS lowest, PHYSICAL_ADDRESS highest,	 PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type){	void *addr;	addr = wrap_get_free_pages(gfp_irql(), size);	TRACE4("%p, %lu", addr, size);	return addr;}wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3)	(void *base, SIZE_T size, enum memory_caching_type cache_type){	TRACE4("%p, %lu", base, size);	free_pages((unsigned long)base, get_order(size));}wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1)	(void *base){	TRACE2("%p", base);	return virt_to_phys(base);}/* Atheros card with pciid 168C:0014 calls this function with 0xf0000 * and 0xf6ef0 address, and then check for things that seem to be * related to ACPI: "_SM_" and "_DMI_". This may be the hack they do * to check if this card is installed in IBM thinkpads; we can * probably get this device to work if we create a buffer with the * strings as required by the driver and return virtual address for * that address instead */wstdcall void *WIN_FUNC(MmMapIoSpace,3)	(PHYSICAL_ADDRESS phys_addr, SIZE_T size,	 enum memory_caching_type cache){	void *virt;	ENTER1("cache type: %d", cache);	if (cache == MmCached)		virt = ioremap(phys_addr, size);	else		virt = ioremap_nocache(phys_addr, size);	TRACE1("%Lx, %lu, %p", phys_addr, size, virt);	return virt;}wstdcall void WIN_FUNC(MmUnmapIoSpace,2)	(void *addr, SIZE_T size){	ENTER1("%p, %lu", addr, size);	iounmap(addr);	return;}wstdcall ULONG WIN_FUNC(MmSizeOfMdl,2)	(void *base, ULONG length){	return (sizeof(struct mdl) +		(sizeof(PFN_NUMBER) * SPAN_PAGES(base, length)));}struct mdl *allocate_init_mdl(void *virt, ULONG length){	struct wrap_mdl *wrap_mdl;	struct mdl *mdl;	int mdl_size = MmSizeOfMdl(virt, length);	KIRQL irql;	if (mdl_size <= MDL_CACHE_SIZE) {		wrap_mdl = kmem_cache_alloc(mdl_cache, gfp_irql());		if (!wrap_mdl)			return NULL;		irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);		InsertHeadList(&wrap_mdl_list, &wrap_mdl->list);		nt_spin_unlock_irql(&ntoskernel_lock, irql);		mdl = wrap_mdl->mdl;		TRACE3("allocated mdl from cache: %p(%p), %p(%d)",		       wrap_mdl, mdl, virt, length);		memset(mdl, 0, MDL_CACHE_SIZE);		MmInitializeMdl(mdl, virt, length);		/* mark the MDL as allocated from cache pool so when		 * it is freed, we free it back to the pool */		mdl->flags = MDL_ALLOCATED_FIXED_SIZE | MDL_CACHE_ALLOCATED;	} else {		wrap_mdl =			kmalloc(sizeof(*wrap_mdl) + mdl_size, gfp_irql());		if (!wrap_mdl)			return NULL;		mdl = wrap_mdl->mdl;		TRACE3("allocated mdl from memory: %p(%p), %p(%d)",		       wrap_mdl, mdl, virt, length);		irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);		InsertHeadList(&wrap_mdl_list, &wrap_mdl->list);		nt_spin_unlock_irql(&ntoskernel_lock, irql);		memset(mdl, 0, mdl_size);		MmInitializeMdl(mdl, virt, length);		mdl->flags = MDL_ALLOCATED_FIXED_SIZE;	}	return mdl;}void free_mdl(struct mdl *mdl){	KIRQL irql;	/* A driver may allocate Mdl with NdisAllocateBuffer and free	 * with IoFreeMdl (e.g., 64-bit Broadcom). Since we need to	 * treat buffers allocated with Ndis calls differently, we	 * must call NdisFreeBuffer if it is allocated with Ndis	 * function. We set 'pool' field in Ndis functions. */	if (!mdl)		return;	if (mdl->pool)		NdisFreeBuffer(mdl);	else {		struct wrap_mdl *wrap_mdl = (struct wrap_mdl *)			((char *)mdl - offsetof(struct wrap_mdl, mdl));		irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);		RemoveEntryList(&wrap_mdl->list);		nt_spin_unlock_irql(&ntoskernel_lock, irql);		if (mdl->flags & MDL_CACHE_ALLOCATED) {			TRACE3("freeing mdl cache: %p, %p, %p",			       wrap_mdl, mdl, mdl->mappedsystemva);			kmem_cache_free(mdl_cache, wrap_mdl);		} else {			TRACE3("freeing mdl: %p, %p, %p",			       wrap_mdl, mdl, mdl->mappedsystemva);			kfree(wrap_mdl);		}	}	return;}wstdcall void WIN_FUNC(IoBuildPartialMdl,4)	(struct mdl *source, struct mdl *target, void *virt, ULONG length){	MmInitializeMdl(target, virt, length);	target->flags |= MDL_PARTIAL;}wstdcall void WIN_FUNC(MmBuildMdlForNonPagedPool,1)	(struct mdl *mdl){	PFN_NUMBER *mdl_pages;	int i, n;	ENTER4("%p", mdl);	/* already mapped *///	mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl);	mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL;	TRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva,	       mdl->byteoffset, mdl->bytecount);	n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl));	if (n > MDL_CACHE_PAGES)		WARNING("%p, %d, %d", MmGetSystemAddressForMdl(mdl),			MmGetMdlByteCount(mdl), n);	mdl_pages = MmGetMdlPfnArray(mdl);	for (i = 0; i < n; i++)		mdl_pages[i] = (ULONG_PTR)mdl->startva + (i * PAGE_SIZE);	EXIT4(return);}wstdcall void *WIN_FUNC(MmMapLockedPages,2)	(struct mdl *mdl, KPROCESSOR_MODE access_mode){	/* already mapped *///	mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl);	mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA;	/* what is the need for MDL_PARTIAL_HAS_BEEN_MAPPED? */	if (mdl->flags & MDL_PARTIAL)		mdl->flags |= MDL_PARTIAL_HAS_BEEN_MAPPED;	return mdl->mappedsystemva;}wstdcall void *WIN_FUNC(MmMapLockedPagesSpecifyCache,6)	(struct mdl *mdl, KPROCESSOR_MODE access_mode,	 enum memory_caching_type cache_type, void *base_address,	 ULONG bug_check, enum mm_page_priority priority){	return MmMapLockedPages(mdl, access_mode);}wstdcall void WIN_FUNC(MmUnmapLockedPages,2)	(void *base, struct mdl *mdl){	mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA;	return;}wstdcall void WIN_FUNC(MmProbeAndLockPages,3)	(struct mdl *mdl, KPROCESSOR_MODE access_mode,	 enum lock_operation operation){	/* already locked */	mdl->flags |= MDL_PAGES_LOCKED;	return;}wstdcall void WIN_FUNC(MmUnlockPages,1)	(struct mdl *mdl){	mdl->flags &= ~MDL_PAGES_LOCKED;	return;}wstdcall BOOLEAN WIN_FUNC(MmIsAddressValid,1)	(void *virt_addr){	if (virt_addr_valid(virt_addr))		return TRUE;	else		return FALSE;}wstdcall void *WIN_FUNC(MmLockPagableDataSection,1)	(void *address){	return address;}wstdcall void WIN_FUNC(MmUnlockPagableImageSection,1)	(void *handle){	return;}wstdcall NTSTATUS WIN_FUNC(ObReferenceObjectByHandle,6)	(void *handle, ACCESS_MASK desired_access, void *obj_type,	 KPROCESSOR_MODE access_mode, void **object, void *handle_info){	struct common_object_header *hdr;	TRACE2("%p", handle);	hdr = HANDLE_TO_HEADER(handle);	atomic_inc_var(hdr->ref_count);	*object = HEADER_TO_OBJECT(hdr);	TRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object);	return STATUS_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -