📄 ntoskernel.c
字号:
irp->size = sizeof(struct irp) + sizeof(struct io_stack_location); irp->stack_size = 1; irp->stack_pos = 1; irp->user_status = io_status; irp->user_event = event; irp->user_buf = output_buf; stack = (struct io_stack_location *)(irp + 1); IRP_CUR_STACK_LOC(irp) = stack + 1; stack->params.ioctl.code = ioctl; stack->params.ioctl.input_buf_len = input_buf_len; stack->params.ioctl.output_buf_len = output_buf_len; stack->params.ioctl.type3_input_buf = input_buf; stack->dev_obj = dev_obj; stack->major_fn = (internal_ioctl) ? IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL; } USBTRACEEXIT(return irp);}_FASTCALL void WRAP_EXPORT(IofCompleteRequest) (FASTCALL_DECL_2(struct irp *irp, CHAR prio_boost)){ struct io_stack_location *stack = IRP_CUR_STACK_LOC(irp) - 1; USBTRACEENTER("irp = %p", irp); if (irp->user_status) { irp->user_status->status = irp->io_status.status; irp->user_status->status_info = irp->io_status.status_info; } if ((stack->completion_handler) && ((((irp->io_status.status == 0) && (stack->control & CALL_ON_SUCCESS)) || ((irp->io_status.status == STATUS_CANCELLED) && (stack->control & CALL_ON_CANCEL)) || ((irp->io_status.status != 0) && (stack->control & CALL_ON_ERROR))))) { USBTRACE("calling %p", stack->completion_handler); if (stack->completion_handler(stack->dev_obj, irp, stack->handler_arg) == STATUS_MORE_PROCESSING_REQUIRED) USBTRACEEXIT(return); } if (irp->user_event) { USBTRACE("setting event %p", irp->user_event); KeSetEvent(irp->user_event, 0, 0); } /* To-Do: what about IRP_DEALLOCATE_BUFFER...? */ USBTRACE("freeing irp %p", irp); kfree(irp); USBTRACEEXIT(return);}_FASTCALL NTSTATUS WRAP_EXPORT(IofCallDriver) (FASTCALL_DECL_2(struct device_object *dev_obj, struct irp *irp)){ struct io_stack_location *stack = IRP_CUR_STACK_LOC(irp) - 1; NTSTATUS ret = STATUS_NOT_SUPPORTED; unsigned long result; USBTRACEENTER("dev_obj = %p, irp = %p, major_fn = %x, ioctl = %u", dev_obj, irp, stack->major_fn, stack->params.ioctl.code); if (stack->major_fn == IRP_MJ_INTERNAL_DEVICE_CONTROL) { switch (stack->params.ioctl.code) {#ifdef CONFIG_USB case IOCTL_INTERNAL_USB_SUBMIT_URB: ret = usb_submit_nt_urb(dev_obj->device.usb, stack->params.generic.arg1, irp); break; case IOCTL_INTERNAL_USB_RESET_PORT: ret = usb_reset_port(dev_obj->device.usb); break;#endif default: ERROR("ioctl %08X NOT IMPLEMENTED!", stack->params.ioctl.code); } } else if (stack->major_fn == IRP_MJ_CREATE) { UNIMPL(); ret = STATUS_SUCCESS; } else ERROR("major_fn %08X NOT IMPLEMENTED!\n", stack->major_fn); if (ret == STATUS_PENDING) { stack->control |= IS_PENDING; USBTRACEEXIT(return ret); } else { irp->io_status.status = ret; if (irp->user_status) irp->user_status->status = ret; if ((stack->completion_handler) && ((((ret == 0) && (stack->control & CALL_ON_SUCCESS)) || ((ret != 0) && (stack->control & CALL_ON_ERROR))))) { USBTRACE("calling %p", stack->completion_handler); result = stack->completion_handler(stack->dev_obj, irp, stack->handler_arg); if (result == STATUS_MORE_PROCESSING_REQUIRED) USBTRACEEXIT(return ret); } if (irp->user_event) { USBTRACE("setting event %p", irp->user_event); KeSetEvent(irp->user_event, 0, 0); } } /* To-Do: what about IRP_DEALLOCATE_BUFFER...? */ USBTRACE("freeing irp %p", irp); kfree(irp); USBTRACEEXIT(return ret);}STDCALL NTSTATUS WRAP_EXPORT(PoCallDriver) (struct device_object *dev_obj, struct irp *irp){ TRACEENTER5("irp = %p", irp); TRACEEXIT5(return IofCallDriver(FASTCALL_ARGS_2(dev_obj, irp)));}struct trampoline_context { void (*start_routine)(void *) STDCALL; void *context;};int kthread_trampoline(void *data){ struct trampoline_context ctx; memcpy(&ctx, data, sizeof(ctx)); kfree(data); ctx.start_routine(ctx.context); return 0;}STDCALL NTSTATUS WRAP_EXPORT(PsCreateSystemThread) (void **phandle, ULONG access, void *obj_attr, void *process, void *client_id, void (*start_routine)(void *) STDCALL, void *context){ struct trampoline_context *ctx;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) int pid;#endif TRACEENTER2("phandle = %p, access = %u, obj_attr = %p, process = %p, " "client_id = %p, start_routine = %p, context = %p", phandle, access, obj_attr, process, client_id, start_routine, context); ctx = kmalloc(sizeof(struct trampoline_context), GFP_KERNEL); if (!ctx) TRACEEXIT2(return STATUS_RESOURCES); ctx->start_routine = start_routine; ctx->context = context;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) pid = kernel_thread(kthread_trampoline, ctx, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); DBGTRACE2("pid = %d", pid); if (pid < 0) { kfree(ctx); TRACEEXIT2(return STATUS_FAILURE); } *phandle = find_task_by_pid(pid); DBGTRACE2("*phandle = %p", *phandle);#else *phandle = KTHREAD_RUN(kthread_trampoline, ctx, DRIVER_NAME); DBGTRACE2("*phandle = %p", *phandle); if (IS_ERR(*phandle)) { kfree(ctx); TRACEEXIT2(return STATUS_FAILURE); }#endif TRACEEXIT2(return STATUS_SUCCESS);}STDCALL NTSTATUS WRAP_EXPORT(PsTerminateSystemThread) (NTSTATUS status){ TRACEENTER2("status = %u", status); complete_and_exit(NULL, status); return 0;}STDCALL void WRAP_EXPORT(PoStartNextPowerIrp) (struct irp *irp){ TRACEENTER5("irp = %p", irp); TRACEEXIT5(return);}STDCALL BOOLEAN WRAP_EXPORT(IoIs32bitProcess) (struct irp *irp){#ifdef CONFIG_X86_64 return FALSE;#else return TRUE;#endif}STDCALL ULONG WRAP_EXPORT(MmSizeOfMdl) (void *base, ULONG length){ return (sizeof(struct mdl) + SPAN_PAGES((ULONG_PTR)base, length) * sizeof(ULONG));}struct mdl *allocate_init_mdl(void *virt, ULONG length){ struct mdl *mdl; int mdl_size = MmSizeOfMdl(virt, length); if (mdl_size <= CACHE_MDL_SIZE) { mdl = kmem_cache_alloc(mdl_cache, GFP_ATOMIC); if (!mdl) return NULL; 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 { mdl = kmalloc(mdl_size, GFP_ATOMIC); if (!mdl) return NULL; memset(mdl, 0, mdl_size); MmInitializeMdl(mdl, virt, length); } return mdl;}void free_mdl(struct mdl *mdl){ /* 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 'process' field in Ndis functions. */ if (mdl) { if (mdl->process) NdisFreeBuffer(mdl); else if (mdl->flags & MDL_CACHE_ALLOCATED) kmem_cache_free(mdl_cache, mdl); else kfree(mdl); }}STDCALL struct mdl *WRAP_EXPORT(IoAllocateMdl) (void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota, struct irp *irp){ struct mdl *mdl; mdl = allocate_init_mdl(virt, length); if (!mdl) return NULL; if (irp) { if (second_buf == TRUE) { struct mdl *last; last = irp->mdl; while (last->next) last = last->next; last->next = mdl; } else irp->mdl = mdl; } return mdl;}STDCALL void WRAP_EXPORT(IoFreeMdl) (struct mdl *mdl){ free_mdl(mdl); TRACEEXIT3(return);}/* FIXME: We don't update MDL to physical page mapping, since in Linux * the pages are in memory anyway; if a driver treats an MDL as * opaque, we should be safe; otherwise, the driver may break */STDCALL void WRAP_EXPORT(MmBuildMdlForNonPagedPool) (struct mdl *mdl){ mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL; mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); return;}STDCALL void *WRAP_EXPORT(MmMapLockedPages) (struct mdl *mdl, KPROCESSOR_MODE access_mode){ mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA; return MmGetMdlVirtualAddress(mdl);}STDCALL void *WRAP_EXPORT(MmMapLockedPagesSpecifyCache) (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);}STDCALL void WRAP_EXPORT(MmUnmapLockedPages) (void *base, struct mdl *mdl){ mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA; return;}STDCALL void WRAP_EXPORT(MmProbeAndLockPages) (struct mdl *mdl, KPROCESSOR_MODE access_mode, enum lock_operation operation){ mdl->flags |= MDL_PAGES_LOCKED; return;}STDCALL void WRAP_EXPORT(MmUnlockPages) (struct mdl *mdl){ mdl->flags &= ~MDL_PAGES_LOCKED; return;}STDCALL BOOLEAN WRAP_EXPORT(MmIsAddressValid) (void *virt_addr){ if (virt_addr_valid(virt_addr)) return TRUE; else return FALSE;}_FASTCALL void WRAP_EXPORT(ObfDereferenceObject) (FASTCALL_DECL_1(void *object)){ struct object_header *header; LONG ref_count; BOOLEAN permanent; ULONG handle_count; if (!object) TRACEEXIT3(return); header = container_of(&((struct common_body_header *)object)->type, struct object_header, type); permanent = header->permanent; handle_count = header->handle_count; ref_count = InterlockedDecrement(FASTCALL_ARGS_1(&header->ref_count)); if (ref_count < 0 || permanent) TRACEEXIT3(return); /* since we didn't allocate it, we don't free it */ /* if (ref_count == 0 && handle_count == 0) kfree(header); */ TRACEEXIT3(return);}_FASTCALL void WRAP_EXPORT(ObDereferenceObject) (FASTCALL_DECL_1(void *object)){ ObfDereferenceObject(FASTCALL_ARGS_1(object)); TRACEEXIT3(return);}STDCALL NTSTATUS WRAP_EXPORT(ZwClose) (void *object){ ObfDereferenceObject(FASTCALL_ARGS_1(object)); TRACEEXIT3(return STATUS_SUCCESS);}NOREGPARM NTSTATUS WRAP_EXPORT(WmiTraceMessage) (void *tracehandle, ULONG message_flags, void *message_guid, USHORT message_no, ...){ TRACEENTER2("%s", ""); TRACEEXIT2(return STATUS_SUCCESS);}STDCALL NTSTATUS WRAP_EXPORT(WmiQueryTraceInformation) (enum trace_information_class trace_info_class, void *trace_info, ULONG *req_length, void *buf){ TRACEENTER2("%s", ""); TRACEEXIT2(return STATUS_SUCCESS);}STDCALL unsigned int WRAP_EXPORT(IoWMIRegistrationControl) (struct device_object *dev_obj, ULONG action){ TRACEENTER2("%s", ""); TRACEEXIT2(return STATUS_SUCCESS);}STDCALL void WRAP_EXPORT(KeBugCheckEx) (ULONG code, ULONG_PTR param1, ULONG_PTR param2, ULONG_PTR param3, ULONG_PTR param4){ UNIMPL(); return;}/* this function can't be STDCALL as it takes variable number of args */NOREGPARM ULONG WRAP_EXPORT(DbgPrint) (char *format, ...){#ifdef DEBUG va_list args; static char buf[1024]; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); printk("DbgPrint: "); printk(buf); va_end(args);#endif return STATUS_SUCCESS;}STDCALL void WRAP_EXPORT(DbgBreakPoint) (void){ UNIMPL();}STDCALL void WRAP_EXPORT(IoReleaseCancelSpinLock)(void){UNIMPL();}STDCALL void WRAP_EXPORT(IoDeleteDevice)(void){UNIMPL();}STDCALL void WRAP_EXPORT(IoCreateSymbolicLink)(void){UNIMPL();}STDCALL void WRAP_EXPORT(IoCreateUnprotectedSymbolicLink)(void){UNIMPL();}STDCALL void WRAP_EXPORT(IoCreateDevice)(void){UNIMPL();}STDCALL void WRAP_EXPORT(IoDeleteSymbolicLink)(void){UNIMPL();}STDCALL void WRAP_EXPORT(ObfReferenceObject)(void){UNIMPL();}STDCALL void WRAP_EXPORT(ObReferenceObjectByHandle)(void){UNIMPL();}STDCALL void WRAP_EXPORT(_except_handler3)(void){UNIMPL();}STDCALL void WRAP_EXPORT(__C_specific_handler)(void){UNIMPL();}#include "ntoskernel_exports.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -