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

📄 ntoskernel.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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);	TRACE2("%p, %d, %p", hdr, hdr->ref_count, object);	return ret;}int dereference_object(void *object){	struct common_object_header *hdr;	int ref_count;	ENTER2("object: %p", object);	hdr = OBJECT_TO_HEADER(object);	TRACE2("hdr: %p", hdr);	ref_count = post_atomic_add(hdr->ref_count, -1);	TRACE2("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){	TRACE2("%p", 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;			EXIT2(return STATUS_SUCCESS);		}	}	nt_spin_unlock_irql(&ntoskernel_lock, irql);	if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) !=	    STATUS_SUCCESS)		EXIT2(return STATUS_INSUFFICIENT_RESOURCES);	file_basename = strrchr(ansi.buf, '\\');	if (file_basename)		file_basename++;	else		file_basename = ansi.buf;	TRACE2("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;		EXIT2(return STATUS_FAILURE);	}	coh = OBJECT_TO_HEADER(fo);	bin_file = get_bin_file(file_basename);	if (bin_file) {		TRACE2("%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;	RtlFreeAnsiString(&ansi);	if (!bin_file) {		iosb->status = FILE_DOES_NOT_EXIST;		iosb->info = 0;		free_object(fo);		EXIT2(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;	TRACE2("handle: %p", *handle);	status = STATUS_SUCCESS;	EXIT2(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;	TRACE2("%p", handle);	coh = handle;	if (coh->type != OBJECT_TYPE_FILE) {		ERROR("handle %p is invalid: %d", handle, coh->type);		EXIT2(return STATUS_FAILURE);	}	fo = HANDLE_TO_OBJECT(coh);	file = fo->wrap_bin_file;	TRACE2("file: %s (%zu)", 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);	TRACE2("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;	EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,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;	struct wrap_bin_file *file;	unsigned long offset;	KIRQL irql;	TRACE2("%p", handle);	coh = handle;	if (coh->type != OBJECT_TYPE_FILE) {		ERROR("handle %p is invalid: %d", handle, coh->type);		EXIT2(return STATUS_FAILURE);	}	fo = HANDLE_TO_OBJECT(coh);	file = fo->wrap_bin_file;	TRACE2("file: %zu, %u", file->size, length);	irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);	if (byte_offset)		offset = *byte_offset;	else		offset = fo->current_byte_offset;	if (length + offset > file->size) {		WARNING("%lu, %u", length + offset, (unsigned int)file->size);		/* TODO: implement writing past end of current size */		iosb->status = STATUS_FAILURE;		iosb->info = 0;	} else {		memcpy(file->data + offset, buffer, length);		iosb->status = STATUS_SUCCESS;		iosb->info = length;		fo->current_byte_offset = offset + length;	}	nt_spin_unlock_irql(&ntoskernel_lock, irql);	EXIT2(return iosb->status);}wstdcall NTSTATUS WIN_FUNC(ZwClose,1)	(void *handle){	struct common_object_header *coh;	TRACE2("%p", handle);	if (handle == NULL) {		TRACE1("");		EXIT2(return STATUS_SUCCESS);	}	coh = handle;	if (coh->type == OBJECT_TYPE_FILE) {		struct file_object *fo;		struct wrap_bin_file *bin_file;		typeof(fo->flags) flags;		fo = HANDLE_TO_OBJECT(handle);		flags = fo->flags;		bin_file = fo->wrap_bin_file;		if (dereference_object(fo)) {			if (flags == FILE_CREATED) {				vfree(bin_file->data);				kfree(bin_file);			} else				free_bin_file(bin_file);		}	} else if (coh->type == OBJECT_TYPE_NT_THREAD) {		struct nt_thread *thread = HANDLE_TO_OBJECT(handle);		TRACE2("thread: %p (%p)", thread, handle);		ObDereferenceObject(thread);	} else {		/* TODO: can we just dereference object here? */		WARNING("closing handle 0x%x not implemented", coh->type);	}	EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5)	(void *handle, struct io_status_block *iosb, void *info,	 ULONG length, enum file_info_class class){	struct file_object *fo;	struct file_name_info *fni;	struct file_std_info *fsi;	struct wrap_bin_file *file;	struct common_object_header *coh;	ENTER2("%p", handle);	coh = handle;	if (coh->type != OBJECT_TYPE_FILE) {		ERROR("handle %p is invalid: %d", coh, coh->type);		EXIT2(return STATUS_FAILURE);	}	fo = HANDLE_TO_OBJECT(handle);	TRACE2("fo: %p, %d", fo, class);	switch (class) {	case FileNameInformation:		fni = info;		fni->length = min(length, (typeof(length))coh->name.length);		memcpy(fni->name, coh->name.buf, fni->length);		iosb->status = STATUS_SUCCESS;		iosb->info = fni->length;		break;	case FileStandardInformation:		fsi = info;		file = fo->wrap_bin_file;		fsi->alloc_size = file->size;		fsi->eof = file->size;		fsi->num_links = 1;		fsi->delete_pending = FALSE;		fsi->dir = FALSE;		iosb->status = STATUS_SUCCESS;		iosb->info = 0;		break;	default:		WARNING("type %d not implemented yet", class);		iosb->status = STATUS_FAILURE;		iosb->info = 0;		break;	}	EXIT2(return iosb->status);}wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7)	(void **handle, ACCESS_MASK desired_access, struct object_attr *attr,	 ULONG title_index, struct unicode_string *class,	 ULONG create_options, ULONG *disposition){	struct ansi_string ansi;	if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) ==	    STATUS_SUCCESS) {		TRACE1("key: %s", ansi.buf);		RtlFreeAnsiString(&ansi);	}	*handle = NULL;	return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3)	(void **handle, ACCESS_MASK desired_access, struct object_attr *attr){	struct ansi_string ansi;	if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) ==	    STATUS_SUCCESS) {		TRACE1("key: %s", ansi.buf);		RtlFreeAnsiString(&ansi);	}	*handle = NULL;	return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6)	(void *handle, struct unicode_string *name, ULONG title_index,	 ULONG type, void *data, ULONG data_size){	struct ansi_string ansi;	if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) ==	    STATUS_SUCCESS) {		TRACE1("key: %s", ansi.buf);		RtlFreeAnsiString(&ansi);	}	return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6)	(void *handle, struct unicode_string *name,	 enum key_value_information_class class, void *info,	 ULONG length, ULONG *res_length){	struct ansi_string ansi;	if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) {		TRACE1("key: %s", ansi.buf);		RtlFreeAnsiString(&ansi);	}	TODO();	return STATUS_INVALID_PARAMETER;}wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1)	(void *handle){	ENTER2("%p", handle);	return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4)	(struct wmilib_context *info, struct device_object *dev_obj,	 struct irp *irp, void *irp_disposition){	TODO();	return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5)	(struct device_object *dev_obj, struct irp *irp, NTSTATUS status,	 ULONG buffer_used, CCHAR priority_boost){	TODO();	return STATUS_SUCCESS;}noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12)	(void *tracehandle, ULONG message_flags,	 void *message_guid, USHORT message_no, ...){	TODO();	EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4)	(enum trace_information_class trace_info_class, void *trace_info,	 ULONG *req_length, void *buf){	TODO();	EXIT2(return STATUS_SUCCESS);}/* this function can't be wstdcall as it takes variable number of args */noregparm ULONG WIN_FUNC(DbgPrint,12)	(char *format, ...){#ifdef DEBUG	va_list args;	static char buf[100];	va_start(args, format);	vsnprintf(buf, sizeof(buf), format, args);	printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __FUNCTION__, buf);	va_end(args);#endif	return STATUS_SUCCESS;}wstdcall void WIN_FUNC(KeBugCheckEx,5)	(ULONG code, ULONG_PTR param1, ULONG_PTR param2,	 ULONG_PTR param3, ULONG_PTR param4){	TODO();	return;}wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2)	(LARGE_INTEGER *system_time, LARGE_INTEGER *local_time){	*local_time = *system_time;}wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2)	(ULONG time, BOOLEAN set){	/* why a driver should change system wide timer resolution is	 * beyond me */	return time;}wstdcall void WIN_FUNC(DbgBreakPoint,0)	(void){	TODO();}wstdcall void WIN_FUNC(_except_handler3,0)	(void){	TODO();}wstdcall void WIN_FUNC(__C_specific_handler,0)	(void){	TODO();}void WIN_FUNC(_purecall,0)	(void){	TODO();}#include "ntoskernel_exports.h"int ntoskernel_init(void){	struct timeval now;	nt_spin_lock_init(&dispatcher_lock);	nt_spin_lock_init(&ntoskernel_lock);	nt_spin_lock_init(&ntos_work_lock);	nt_spin_lock_init(&kdpc_list_lock);	nt_spin_lock_init(&irp_cancel_lock);	InitializeListHead(&wrap_mdl_list);	InitializeListHead(&kdpc_list);	InitializeListHead(&callback_objects);	InitializeListHead(&bus_driver_list);	InitializeListHead(&object_list);	InitializeListHead(&ntos_work_list);	initialize_work(&kdpc_work, kdpc_worker, NULL);	initialize_work(&ntos_work, ntos_work_worker, NULL);	nt_spin_lock_init(&timer_lock);	InitializeListHead(&wrap_timer_list);	do_gettimeofday(&now);	wrap_ticks_to_boot = TICKS_1601_TO_1970;	wrap_ticks_to_boot += (u64)now.tv_sec * TICKSPERSEC;	wrap_ticks_to_boot += now.tv_usec * 10;	wrap_ticks_to_boot -= jiffies * TICKSPERJIFFY;	TRACE2("%Lu

⌨️ 快捷键说明

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