📄 ntoskernel.c
字号:
kevent->header.signal_state = state; kspin_unlock(&dispatch_event_lock);}STDCALL LONG WRAP_EXPORT(KeSetEvent) (struct kevent *kevent, KPRIORITY incr, BOOLEAN wait){ LONG old_state = kevent->header.signal_state; TRACEENTER3("event = %p, type = %d, wait = %d", kevent, kevent->header.type, wait); if (wait == TRUE) WARNING("wait = %d, not yet implemented", wait); kspin_lock(&dispatch_event_lock); kevent->header.signal_state = TRUE; if (kevent->header.type == SynchronizationEvent) wake_up_nr(&dispatch_event_wq, 1); else wake_up_all(&dispatch_event_wq); DBGTRACE3("woken up %p", kevent); kspin_unlock(&dispatch_event_lock); TRACEEXIT3(return old_state);}STDCALL void WRAP_EXPORT(KeClearEvent) (struct kevent *kevent){ TRACEENTER3("event = %p", kevent); kevent->header.signal_state = FALSE;}STDCALL LONG WRAP_EXPORT(KeResetEvent) (struct kevent *kevent){ LONG old_state; TRACEENTER3("event = %p", kevent); old_state = kevent->header.signal_state; kevent->header.signal_state = FALSE; TRACEEXIT3(return old_state);}STDCALL NTSTATUS WRAP_EXPORT(KeWaitForSingleObject) (void *object, KWAIT_REASON reason, KPROCESSOR_MODE waitmode, BOOLEAN alertable, LARGE_INTEGER *timeout){ struct kevent *kevent = (struct kevent *)object; struct dispatch_header *header = &kevent->header; int res; long wait_jiffies; /* Note: for now, object can only point to an event */ TRACEENTER2("event = %p, reason = %u, waitmode = %u, alertable = %u," " timeout = %p", kevent, reason, waitmode, alertable, timeout); DBGTRACE2("object type = %d, size = %d", header->type, header->size); kspin_lock(&dispatch_event_lock); if (header->signal_state == TRUE) { if (header->type == SynchronizationEvent) header->signal_state = FALSE; kspin_unlock(&dispatch_event_lock); TRACEEXIT3(return STATUS_SUCCESS); } kspin_unlock(&dispatch_event_lock); if (timeout) { DBGTRACE2("timeout = %Ld", *timeout); if (*timeout == 0) TRACEEXIT2(return STATUS_TIMEOUT); else if (*timeout > 0) { long d = (*timeout) - ticks_1601(); /* many drivers call this function with much * smaller numbers that suggest either drivers * are broken or explanation for this is * wrong */ if (d > 0) wait_jiffies = HZ * d / TICKSPERSEC; else wait_jiffies = 0; } else wait_jiffies = HZ * (-(*timeout)) / TICKSPERSEC; } else wait_jiffies = 0; if (wait_jiffies == 0) { if (alertable) res = wait_event_interruptible( dispatch_event_wq, (header->signal_state == TRUE)); else { wait_event(dispatch_event_wq, (header->signal_state == TRUE)); res = 1; } } else { if (alertable) res = wait_event_interruptible_timeout( dispatch_event_wq, (header->signal_state == TRUE), wait_jiffies); else res = wait_event_timeout( dispatch_event_wq, (header->signal_state == TRUE), wait_jiffies); } DBGTRACE3("%p, type = %d woke up (%d), res = %d", kevent, header->type, header->signal_state, res); if (res < 0) TRACEEXIT2(return STATUS_ALERTED); if (res == 0) TRACEEXIT2(return STATUS_TIMEOUT); /* res > 0 */ if (header->type == SynchronizationEvent) header->signal_state = FALSE; TRACEEXIT2(return STATUS_SUCCESS);}STDCALL NTSTATUS WRAP_EXPORT(KeWaitForMultipleObjects) (ULONG count, void *object[], enum wait_type wait_type, KWAIT_REASON wait_reason, KPROCESSOR_MODE waitmode, BOOLEAN alertable, LARGE_INTEGER *timeout, struct wait_block *wait_block){ UNIMPL(); return STATUS_SUCCESS;}STDCALL NTSTATUS WRAP_EXPORT(KeDelayExecutionThread) (KPROCESSOR_MODE wait_mode, BOOLEAN alertable, LARGE_INTEGER *interval){ int res; long timeout; long t = *interval; TRACEENTER3("thread: %p", get_current()); if (wait_mode != 0) ERROR("illegal wait_mode %d", wait_mode); if (t < 0) timeout = HZ * (-t) / TICKSPERSEC; else timeout = HZ * t / TICKSPERSEC - jiffies; if (timeout <= 0) TRACEEXIT3(return STATUS_SUCCESS); if (alertable) set_current_state(TASK_INTERRUPTIBLE); else set_current_state(TASK_UNINTERRUPTIBLE); res = schedule_timeout(timeout); if (res > 0) TRACEEXIT3(return STATUS_ALERTED); else TRACEEXIT3(return STATUS_SUCCESS);}STDCALL KPRIORITY WRAP_EXPORT(KeQueryPriorityThread) (void *thread){ KPRIORITY prio; TRACEENTER5("thread = %p", thread);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) prio = 1;#else if (rt_task((task_t *)thread)) prio = LOW_REALTIME_PRIORITY; else prio = MAXIMUM_PRIORITY;#endif TRACEEXIT5(return prio);}STDCALL ULONGLONG WRAP_EXPORT(KeQueryInterruptTime) (void){ TRACEEXIT4(return jiffies);}STDCALL ULONG WRAP_EXPORT(KeQueryTimeIncrement) (void){ TRACEEXIT5(return TICKSPERSEC/HZ);}STDCALL LARGE_INTEGER WRAP_EXPORT(KeQueryPerformanceCounter) (LARGE_INTEGER *counter){ unsigned long res; res = jiffies; if (counter) *counter = res; return res;}STDCALL void WRAP_EXPORT(KeInitializeMutex) (struct kmutex *mutex, BOOLEAN wait){ INIT_LIST_HEAD(&mutex->dispatch_header.wait_list_head); mutex->abandoned = FALSE; mutex->apc_disable = 1; mutex->dispatch_header.signal_state = TRUE; mutex->dispatch_header.type = SynchronizationEvent; mutex->dispatch_header.size = NT_OBJ_MUTEX; mutex->u.count = 0; mutex->owner_thread = NULL; return;}STDCALL LONG WRAP_EXPORT(KeReleaseMutex) (struct kmutex *mutex, BOOLEAN wait){ kspin_lock(&dispatch_event_lock); mutex->u.count--; if (mutex->u.count == 0) { mutex->owner_thread = NULL; kspin_unlock(&dispatch_event_lock); KeSetEvent((struct kevent *)&mutex->dispatch_header, 0, 0); } else kspin_unlock(&dispatch_event_lock); return mutex->u.count;}STDCALL void * WRAP_EXPORT(KeGetCurrentThread) (void){ void *thread = get_current(); TRACEENTER2("current thread = %p", thread); return thread;}STDCALL KPRIORITY WRAP_EXPORT(KeSetPriorityThread) (void *thread, KPRIORITY priority){ KPRIORITY old_prio; TRACEENTER2("thread = %p, priority = %u", thread, priority);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) /* FIXME: is there a way to set kernel thread prio on 2.4? */ old_prio = LOW_PRIORITY;#else if (rt_task((task_t *)thread)) old_prio = LOW_REALTIME_PRIORITY; else old_prio = MAXIMUM_PRIORITY; if (priority == LOW_REALTIME_PRIORITY) set_user_nice((task_t *)thread, -20); else set_user_nice((task_t *)thread, 10);#endif return old_prio;}STDCALL NTSTATUS WRAP_EXPORT(IoGetDeviceProperty) (struct device_object *dev_obj, enum device_registry_property dev_property, ULONG buffer_len, void *buffer, ULONG *result_len){ struct ansi_string ansi; struct unicode_string unicode; struct ndis_handle *handle; char buf[32]; handle = (struct ndis_handle *)dev_obj->handle; TRACEENTER1("dev_obj = %p, dev_property = %d, buffer_len = %u, " "buffer = %p, result_len = %p", dev_obj, dev_property, buffer_len, buffer, result_len); switch (dev_property) { case DevicePropertyDeviceDescription: if (buffer_len > 0 && buffer) { *result_len = 4; memset(buffer, 0xFF, *result_len); TRACEEXIT1(return STATUS_SUCCESS); } else { *result_len = 4; TRACEEXIT1(return STATUS_SUCCESS); } break; case DevicePropertyFriendlyName: if (buffer_len > 0 && buffer) { ansi.len = snprintf(buf, sizeof(buf), "%d", handle->dev.usb->devnum); ansi.buf = buf; ansi.len = strlen(ansi.buf); if (ansi.len <= 0) { *result_len = 0; TRACEEXIT1(return STATUS_BUFFER_TOO_SMALL); } ansi.buflen = ansi.len; unicode.buf = buffer; unicode.buflen = buffer_len; DBGTRACE1("unicode.buflen = %d, ansi.len = %d", unicode.buflen, ansi.len); if (RtlAnsiStringToUnicodeString(&unicode, &ansi, 0)) { *result_len = 0; TRACEEXIT1(return STATUS_BUFFER_TOO_SMALL); } else { *result_len = unicode.len; TRACEEXIT1(return STATUS_SUCCESS); } } else { ansi.len = snprintf(buf, sizeof(buf), "%d", handle->dev.usb->devnum); *result_len = 2 * (ansi.len + 1); TRACEEXIT1(return STATUS_BUFFER_TOO_SMALL); } break; case DevicePropertyDriverKeyName:// ansi.buf = handle->driver->name; ansi.buf = buf; ansi.len = strlen(ansi.buf); ansi.buflen = ansi.len; if (buffer_len > 0 && buffer) { unicode.buf = buffer; unicode.buflen = buffer_len; if (RtlAnsiStringToUnicodeString(&unicode, &ansi, 0)) { *result_len = 0; TRACEEXIT1(return STATUS_BUFFER_TOO_SMALL); } else { *result_len = unicode.len; TRACEEXIT1(return STATUS_SUCCESS); } } else { *result_len = 2 * (strlen(buf) + 1); TRACEEXIT1(return STATUS_SUCCESS); } break; default: TRACEEXIT1(return STATUS_INVALID_PARAMETER_2); }}STDCALL void WRAP_EXPORT(IoBuildSynchronousFsdRequest) (void){ UNIMPL();}STDCALL struct irp *WRAP_EXPORT(IoAllocateIrp) (char stack_size, BOOLEAN charge_quota){ struct irp *irp; int size; USBTRACEENTER("stack_size = %d, charge_quota = %d", stack_size, charge_quota); size = sizeof(struct irp) + stack_size * sizeof(struct io_stack_location); /* FIXME: we should better check what GFP_ is required */ irp = kmalloc(size, GFP_ATOMIC); if (irp) { USBTRACE("allocated irp %p", irp); memset(irp, 0, size); irp->size = size; irp->stack_size = stack_size; irp->stack_pos = stack_size; IRP_CUR_STACK_LOC(irp) = ((struct io_stack_location *)(irp + 1)) + stack_size; } USBTRACEEXIT(return irp);}STDCALL void WRAP_EXPORT(IoInitializeIrp) (struct irp *irp, USHORT size, CHAR stack_size){ USBTRACEENTER("irp = %p, size = %d, stack_size = %d", irp, size, stack_size); if (irp) { USBTRACE("initializing irp %p", irp); memset(irp, 0, size); irp->size = size; irp->stack_size = stack_size; irp->stack_pos = stack_size; IRP_CUR_STACK_LOC(irp) = ((struct io_stack_location *)(irp+1)) + stack_size; } USBTRACEEXIT(return);}STDCALL void WRAP_EXPORT(IoReuseIrp) (struct irp *irp, NTSTATUS status){ USBTRACEENTER("irp = %p, status = %d", irp, status); if (irp) irp->io_status.status = status; USBTRACEEXIT(return);}STDCALL BOOLEAN WRAP_EXPORT(IoCancelIrp) (struct irp *irp){ struct io_stack_location *stack = IRP_CUR_STACK_LOC(irp) - 1; void (*cancel_routine)(struct device_object *, struct irp *) STDCALL; USBTRACEENTER("irp = %p", irp); kspin_lock(&irp_cancel_lock); cancel_routine = xchg(&irp->cancel_routine, NULL); if (cancel_routine) { irp->cancel_irql = current_irql(); irp->pending_returned = 1; irp->cancel = 1; cancel_routine(stack->dev_obj, irp); kspin_unlock(&irp_cancel_lock); USBTRACEEXIT(return 1); } else { kspin_unlock(&irp_cancel_lock); USBTRACEEXIT(return 0); }}STDCALL void WRAP_EXPORT(IoFreeIrp) (struct irp *irp){ USBTRACEENTER("irp = %p", irp); kfree(irp); USBTRACEEXIT(return);}STDCALL struct irp *WRAP_EXPORT(IoBuildDeviceIoControlRequest) (ULONG ioctl, struct device_object *dev_obj, void *input_buf, ULONG input_buf_len, void *output_buf, ULONG output_buf_len, BOOLEAN internal_ioctl, struct kevent *event, struct io_status_block *io_status){ struct irp *irp; struct io_stack_location *stack; USBTRACEENTER(""); irp = kmalloc(sizeof(struct irp) + sizeof(struct io_stack_location), GFP_KERNEL); /* we are running at IRQL = PASSIVE_LEVEL */ if (irp) { USBTRACE("allocated irp %p", irp); memset(irp, 0, sizeof(struct irp) + sizeof(struct io_stack_location));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -