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

📄 ntoskernel.c

📁 ndiswrapper工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	TRACEEXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1)	(NTSTATUS status){	struct nt_thread *thread;	DBGTRACE2("%p, %08X", current, status);	thread = get_current_nt_thread();	if (thread) {		DBGTRACE2("setting event for thread: %p", thread);		KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE);		DBGTRACE2("set event for thread: %p", thread);		remove_nt_thread(thread);		complete_and_exit(NULL, status);		ERROR("oops: %p, %d", thread->task, thread->pid);	} else		ERROR("couldn't find thread for task: %p", current);	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 *synch_context){	NT_SPIN_LOCK *spinlock;	BOOLEAN ret;	unsigned long flags;	if (interrupt->actual_lock)		spinlock = interrupt->actual_lock;	else		spinlock = &interrupt->lock;	nt_spin_lock_irqsave(spinlock, flags);	ret = synch_routine(synch_context);	nt_spin_unlock_irqrestore(spinlock, 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;	size_t page_length = ((size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;	DBGTRACE2("%lu, %u, %Lu, %Lu, %Lu, %d", size, page_length,		  lowest, highest, boundary, cache_type);	addr = ExAllocatePoolWithTag(NonPagedPool, page_length, 0);	DBGTRACE2("%p", addr);	return addr;}wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3)	(void *base, SIZE_T size, enum memory_caching_type cache_type){	DBGTRACE2("%p", base);	ExFreePool(base);}wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1)	(void *base){	DBGTRACE2("%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;	TRACEENTER1("cache type: %d", cache);	if (cache == MmCached)		virt = ioremap(phys_addr, size);	else		virt = ioremap_nocache(phys_addr, size);	DBGTRACE1("%Lx, %lu, %p", phys_addr, size, virt);	return virt;}wstdcall void WIN_FUNC(MmUnmapIoSpace,2)	(void *addr, SIZE_T size){	TRACEENTER1("%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 <= CACHE_MDL_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;		DBGTRACE3("allocated mdl from cache: %p(%p), %p(%d)",			  wrap_mdl, mdl, virt, length);		memset(mdl, 0, CACHE_MDL_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_CACHE_ALLOCATED;	} else {		wrap_mdl =			kmalloc(sizeof(*wrap_mdl) + mdl_size, gfp_irql());		if (!wrap_mdl)			return NULL;		mdl = wrap_mdl->mdl;		DBGTRACE3("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);	}	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) {			DBGTRACE3("freeing mdl cache: %p, %p, %p",				  wrap_mdl, mdl, mdl->mappedsystemva);			kmem_cache_free(mdl_cache, wrap_mdl);		} else {			DBGTRACE3("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;	TRACEENTER4("%p", mdl);	/* already mapped *///	mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl);	mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL;	DBGTRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva,		  mdl->byteoffset, mdl->bytecount);	n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl));	if (n > CACHE_MDL_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);	TRACEEXIT4(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;	DBGTRACE2("%p", handle);	hdr = HANDLE_TO_HEADER(handle);	atomic_inc_var(hdr->ref_count);	*object = HEADER_TO_OBJECT(hdr);	DBGTRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object);	return STATUS_SUCCESS;}/* DDK doesn't say if return value should be before incrementing or * after incrementing reference count, but according to #reactos * devels, it should be return value after incrementing */wfastcall LONG WIN_FUNC(ObfReferenceObject,1)	(void *object){	struct common_object_header *hdr;	LONG ret;	hdr = OBJECT_TO_HEADER(object);	ret = post_atomic_add(hdr->ref_count, 1);	DBGTRACE2("%p, %d, %p", hdr, hdr->ref_count, object);	return ret;}int dereference_object(void *object){	struct common_object_header *hdr;	int ref_count;	TRACEENTER2("object: %p", object);	hdr = OBJECT_TO_HEADER(object);	DBGTRACE2("hdr: %p", hdr);	ref_count = post_atomic_add(hdr->ref_count, -1);	DBGTRACE2("object: %p, %d", object, ref_count);	if (ref_count < 0)		ERROR("invalid object: %p (%d)", object, ref_count);	if (ref_count <= 0) {		free_object(object);		return 1;	} else		return 0;}wfastcall void WIN_FUNC(ObfDereferenceObject,1)	(void *object){	dereference_object(object);}wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11)	(void **handle, ACCESS_MASK access_mask, struct object_attr *obj_attr,	 struct io_status_block *iosb, LARGE_INTEGER *size,	 ULONG file_attr, ULONG share_access, ULONG create_disposition,	 ULONG create_options, void *ea_buffer, ULONG ea_length){	struct common_object_header *coh;	struct file_object *fo;	struct ansi_string ansi;	struct wrap_bin_file *bin_file;	char *file_basename;	KIRQL irql;	NTSTATUS status;	irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);	nt_list_for_each_entry(coh, &object_list, list) {		if (coh->type != OBJECT_TYPE_FILE)			continue;		/* TODO: check if file is opened in shared mode */		if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) {			fo = HEADER_TO_OBJECT(coh);			bin_file = fo->wrap_bin_file;			*handle = coh;			nt_spin_unlock_irql(&ntoskernel_lock, irql);			ObReferenceObject(fo);			iosb->status = FILE_OPENED;			iosb->info = bin_file->size;			TRACEEXIT2(return STATUS_SUCCESS);		}	}	nt_spin_unlock_irql(&ntoskernel_lock, irql);	if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) !=	    STATUS_SUCCESS)		TRACEEXIT2(return STATUS_INSUFFICIENT_RESOURCES);	file_basename = strrchr(ansi.buf, '\\');	if (file_basename)		file_basename++;	else		file_basename = ansi.buf;	DBGTRACE2("file: '%s', '%s'", ansi.buf, file_basename);	fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE,			     obj_attr->name);	if (!fo) {		RtlFreeAnsiString(&ansi);		iosb->status = STATUS_INSUFFICIENT_RESOURCES;		iosb->info = 0;		TRACEEXIT2(return STATUS_FAILURE);	}	coh = OBJECT_TO_HEADER(fo);	bin_file = get_bin_file(file_basename);	if (bin_file) {		DBGTRACE2("%s, %s", bin_file->name, file_basename);		fo->flags = FILE_OPENED;	} else if (access_mask & FILE_WRITE_DATA) {		bin_file = kmalloc(sizeof(*bin_file), GFP_KERNEL);		if (bin_file) {			memset(bin_file, 0, sizeof(*bin_file));			strncpy(bin_file->name, file_basename,				sizeof(bin_file->name));			bin_file->name[sizeof(bin_file->name)-1] = 0;			bin_file->data = vmalloc(*size);			if (bin_file->data) {				memset(bin_file->data, 0, *size);				bin_file->size = *size;				fo->flags = FILE_CREATED;			} else {				kfree(bin_file);				bin_file = NULL;			}		}	} else		bin_file = NULL;	if (!bin_file) {		iosb->status = FILE_DOES_NOT_EXIST;		iosb->info = 0;		RtlFreeAnsiString(&ansi);		free_object(fo);		TRACEEXIT2(return STATUS_FAILURE);	}	fo->wrap_bin_file = bin_file;	fo->current_byte_offset = 0;	if (access_mask & FILE_READ_DATA)		fo->read_access = TRUE;	if (access_mask & FILE_WRITE_DATA)		fo->write_access = TRUE;	iosb->status = FILE_OPENED;	iosb->info = bin_file->size;	*handle = coh;	DBGTRACE2("handle: %p", *handle);	status = STATUS_SUCCESS;	RtlFreeAnsiString(&ansi);	TRACEEXIT2(return status);}wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9)	(void *handle, struct nt_event *event, void *apc_routine,	 void *apc_context, struct io_status_block *iosb, void *buffer,	 ULONG length, LARGE_INTEGER *byte_offset, ULONG *key){	struct file_object *fo;	struct common_object_header *coh;	ULONG count;	size_t offset;	struct wrap_bin_file *file;	KIRQL irql;	DBGTRACE2("%p", handle);	coh = handle;	if (coh->type != OBJECT_TYPE_FILE) {		ERROR("handle %p is invalid: %d", handle, coh->type);		TRACEEXIT2(return STATUS_FAILURE);	}	fo = HANDLE_TO_OBJECT(coh);	file = fo->wrap_bin_file;	DBGTRACE2("file: %s (%u)", file->name, file->size);	irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);	if (byte_offset)		offset = *byte_offset;	else		offset = fo->current_byte_offset;	count = min((size_t)length, file->size - offset);	DBGTRACE2("count: %u, offset: %zu, length: %u", count, offset, length);	memcpy(buffer, ((void *)file->data) + offset, count);	fo->current_byte_offset = offset + count;	nt_spin_unlock_irql(&ntoskernel_lock, irql);	iosb->status = STATUS_SUCCESS;	iosb->info = count;	TRACEEXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9)	(void *handle, struct nt_event *event, void *apc_routine,

⌨️ 快捷键说明

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