📄 ntoskernel.h
字号:
{ assert(current_irql() == DISPATCH_LEVEL); preempt_enable();}#endif#define irql_gfp() (in_atomic() ? GFP_ATOMIC : GFP_KERNEL)/* Windows spinlocks are of type ULONG_PTR which is not big enough to * store Linux spinlocks; so we implement Windows spinlocks using * ULONG_PTR space with our own functions/macros *//* Windows seems to use 0 for unlocked state of spinlock - if Linux * convention of 1 for unlocked state is used, at least prism54 driver * crashes */#define NT_SPIN_LOCK_UNLOCKED 0#define NT_SPIN_LOCK_LOCKED 1static inline void nt_spin_lock_init(NT_SPIN_LOCK *lock){ *lock = NT_SPIN_LOCK_UNLOCKED;}#ifdef CONFIG_SMPstatic inline void nt_spin_lock(NT_SPIN_LOCK *lock){ __asm__ __volatile__( "1:\t" " xchgl %1, %0\n\t" " testl %1, %1\n\t" " je 3f\n" "2:\t" " rep; nop\n\t" " cmpl %2, %0\n\t" " jne 2b\n\t" " jmp 1b\n" "3:\n\t" : "+m" (*lock) : "r" (NT_SPIN_LOCK_LOCKED), "i" (NT_SPIN_LOCK_UNLOCKED));}static inline void nt_spin_unlock(NT_SPIN_LOCK *lock){ *lock = NT_SPIN_LOCK_UNLOCKED;}#else // CONFIG_SMP#define nt_spin_lock(lock) do { } while (0)#define nt_spin_unlock(lock) do { } while (0)#endif // CONFIG_SMP/* When kernel would've disabled preempt (e.g., in interrupt * handlers), we need to fake preempt so driver thinks it is running * at right IRQL *//* raise IRQL to given (higher) IRQL if necessary before locking */static inline KIRQL nt_spin_lock_irql(NT_SPIN_LOCK *lock, KIRQL newirql){ KIRQL oldirql = raise_irql(newirql); nt_spin_lock(lock); return oldirql;}/* lower IRQL to given (lower) IRQL if necessary after unlocking */static inline void nt_spin_unlock_irql(NT_SPIN_LOCK *lock, KIRQL oldirql){ nt_spin_unlock(lock); lower_irql(oldirql);}#define nt_spin_lock_irqsave(lock, flags) \do { \ preempt_disable(); \ local_irq_save(flags); \ nt_spin_lock(lock); \} while (0)#define nt_spin_unlock_irqrestore(lock, flags) \do { \ nt_spin_unlock(lock); \ local_irq_restore(flags); \ preempt_enable(); \} while (0)static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length){ return PAGE_ALIGN(((unsigned long)ptr & (PAGE_SIZE - 1)) + length) >> PAGE_SHIFT;}#ifdef CONFIG_X86_64/* TODO: can these be implemented without using spinlock? */static inline struct nt_slist *PushEntrySList(nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock){ KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); entry->next = head->next; head->next = entry; head->depth++; nt_spin_unlock_irql(lock, irql); TRACE4("%p, %p, %p", head, entry, entry->next); return entry->next;}static inline struct nt_slist *PopEntrySList(nt_slist_header *head, NT_SPIN_LOCK *lock){ struct nt_slist *entry; KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); entry = head->next; if (entry) { head->next = entry->next; head->depth--; } nt_spin_unlock_irql(lock, irql); TRACE4("%p, %p", head, entry); return entry;}#else#define u64_low_32(x) ((u32)x)#define u64_high_32(x) ((u32)(x >> 32))static inline u64 cmpxchg8b(volatile u64 *ptr, u64 old, u64 new){ u64 prev; __asm__ __volatile__( "\n" LOCK_PREFIX "cmpxchg8b %0\n" : "+m" (*ptr), "=A" (prev) : "A" (old), "b" (u64_low_32(new)), "c" (u64_high_32(new))); return prev;}/* slist routines below update slist atomically - no need for * spinlocks */static inline struct nt_slist *PushEntrySList(nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock){ nt_slist_header old, new; do { old.align = head->align; entry->next = old.next; new.next = entry; new.depth = old.depth + 1; } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); TRACE4("%p, %p, %p", head, entry, old.next); return old.next;}static inline struct nt_slist *PopEntrySList(nt_slist_header *head, NT_SPIN_LOCK *lock){ struct nt_slist *entry; nt_slist_header old, new; do { old.align = head->align; entry = old.next; if (!entry) break; new.next = entry->next; new.depth = old.depth - 1; } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); TRACE4("%p, %p", head, entry); return entry;}#endif#define sleep_hz(n) \do { \ set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(n); \} while (0)int ntoskernel_init(void);void ntoskernel_exit(void);int ntoskernel_init_device(struct wrap_device *wd);void ntoskernel_exit_device(struct wrap_device *wd);void *allocate_object(ULONG size, enum common_object_type type, struct unicode_string *name);void free_object(void *object);int usb_init(void);void usb_exit(void);int usb_init_device(struct wrap_device *wd);void usb_exit_device(struct wrap_device *wd);void usb_cancel_pending_urbs(void);int crt_init(void);void crt_exit(void);int rtl_init(void);void rtl_exit(void);int wrap_procfs_init(void);void wrap_procfs_remove(void);int link_pe_images(struct pe_image *pe_image, unsigned short n);int stricmp(const char *s1, const char *s2);void dump_bytes(const char *name, const u8 *from, int len);struct mdl *allocate_init_mdl(void *virt, ULONG length);void free_mdl(struct mdl *mdl);struct driver_object *find_bus_driver(const char *name);void free_custom_extensions(struct driver_extension *drv_obj_ext);struct nt_thread *get_current_nt_thread(void);u64 ticks_1601(void);int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2);void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, struct ndis_mp_block *nmb);BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, unsigned long repeat_hz, struct kdpc *kdpc);LONG InterlockedDecrement(LONG volatile *val) wfastcall;LONG InterlockedIncrement(LONG volatile *val) wfastcall;struct nt_list *ExInterlockedInsertHeadList (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) wfastcall;struct nt_list *ExInterlockedInsertTailList (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) wfastcall;struct nt_list *ExInterlockedRemoveHeadList (struct nt_list *head, NT_SPIN_LOCK *lock) wfastcall;NTSTATUS IofCallDriver(struct device_object *dev_obj, struct irp *irp) wfastcall;KIRQL KfRaiseIrql(KIRQL newirql) wfastcall;void KfLowerIrql(KIRQL oldirql) wfastcall;KIRQL KfAcquireSpinLock(NT_SPIN_LOCK *lock) wfastcall;void KfReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wfastcall;void IofCompleteRequest(struct irp *irp, CHAR prio_boost) wfastcall;void KefReleaseSpinLockFromDpcLevel(NT_SPIN_LOCK *lock) wfastcall;LONG ObfReferenceObject(void *object) wfastcall;void ObfDereferenceObject(void *object) wfastcall;#define ObReferenceObject(object) ObfReferenceObject(object)#define ObDereferenceObject(object) ObfDereferenceObject(object)void WRITE_PORT_UCHAR(ULONG_PTR port, UCHAR value) wstdcall;UCHAR READ_PORT_UCHAR(ULONG_PTR port) wstdcall;#undef ExAllocatePoolWithTagvoid *ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, ULONG tag) wstdcall;#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1#define ExAllocatePoolWithTag(pool_type, size, tag) \ wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__)#endifvoid ExFreePool(void *p) wstdcall;ULONG MmSizeOfMdl(void *base, ULONG length) wstdcall;void *MmMapIoSpace(PHYSICAL_ADDRESS phys_addr, SIZE_T size, enum memory_caching_type cache) wstdcall;void MmUnmapIoSpace(void *addr, SIZE_T size) wstdcall;void MmProbeAndLockPages(struct mdl *mdl, KPROCESSOR_MODE access_mode, enum lock_operation operation) wstdcall;void MmUnlockPages(struct mdl *mdl) wstdcall;void KeInitializeEvent(struct nt_event *nt_event, enum event_type type, BOOLEAN state) wstdcall;LONG KeSetEvent(struct nt_event *nt_event, KPRIORITY incr, BOOLEAN wait) wstdcall;LONG KeResetEvent(struct nt_event *nt_event) wstdcall;void KeClearEvent(struct nt_event *nt_event) wstdcall;void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall;BOOLEAN queue_kdpc(struct kdpc *kdpc);BOOLEAN dequeue_kdpc(struct kdpc *kdpc);void KeFlushQueuedDpcs(void) wstdcall;NTSTATUS IoConnectInterrupt(struct kinterrupt **kinterrupt, PKSERVICE_ROUTINE service_routine, void *service_context, NT_SPIN_LOCK *lock, ULONG vector, KIRQL irql, KIRQL synch_irql, enum kinterrupt_mode interrupt_mode, BOOLEAN shareable, KAFFINITY processor_enable_mask, BOOLEAN floating_save) wstdcall;void IoDisconnectInterrupt(struct kinterrupt *interrupt) wstdcall;BOOLEAN KeSynchronizeExecution(struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine, void *ctx) wstdcall;NTSTATUS KeWaitForSingleObject(void *object, KWAIT_REASON reason, KPROCESSOR_MODE waitmode, BOOLEAN alertable, LARGE_INTEGER *timeout) wstdcall;struct mdl *IoAllocateMdl(void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota, struct irp *irp) wstdcall;void MmBuildMdlForNonPagedPool(struct mdl *mdl) wstdcall;void IoFreeMdl(struct mdl *mdl) wstdcall;NTSTATUS IoCreateDevice(struct driver_object *driver, ULONG dev_ext_length, struct unicode_string *dev_name, DEVICE_TYPE dev_type, ULONG dev_chars, BOOLEAN exclusive, struct device_object **dev_obj) wstdcall;NTSTATUS IoCreateSymbolicLink(struct unicode_string *link, struct unicode_string *dev_name) wstdcall;void IoDeleteDevice(struct device_object *dev) wstdcall;void IoDetachDevice(struct device_object *topdev) wstdcall;struct device_object *IoGetAttachedDevice(struct device_object *dev) wstdcall;struct device_object *IoGetAttachedDeviceReference (struct device_object *dev) wstdcall;NTSTATUS IoAllocateDriverObjectExtension (struct driver_object *drv_obj, void *client_id, ULONG extlen, void **ext) wstdcall;void *IoGetDriverObjectExtension(struct driver_object *drv, void *client_id) wstdcall;struct device_object *IoAttachDeviceToDeviceStack (struct device_object *src, struct device_object *dst) wstdcall;void KeInitializeEvent(struct nt_event *nt_event, enum event_type type, BOOLEAN state) wstdcall;struct irp *IoAllocateIrp(char stack_count, BOOLEAN charge_quota) wstdcall;void IoFreeIrp(struct irp *irp) wstdcall;BOOLEAN IoCancelIrp(struct irp *irp) wstdcall;struct irp *IoBuildSynchronousFsdRequest (ULONG major_func, struct device_object *dev_obj, void *buf, ULONG length, LARGE_INTEGER *offset, struct nt_event *event, struct io_status_block *status) wstdcall;struct irp *IoBuildAsynchronousFsdRequest (ULONG major_func, struct device_object *dev_obj, void *buf, ULONG length, LARGE_INTEGER *offset, struct io_status_block *status) wstdcall;NTSTATUS PoCallDriver(struct device_object *dev_obj, struct irp *irp) wstdcall;NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) wstdcall;WIN_FUNC_DECL(IoPassIrpDown,2);NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, struct irp *irp) wstdcall;NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, struct irp *irp) wstdcall;NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, struct irp *irp) wstdcall;KIRQL KeGetCurrentIrql(void) wstdcall;void KeInitializeSpinLock(NT_SPIN_LOCK *lock) wstdcall;void KeAcquireSpinLock(NT_SPIN_LOCK *lock, KIRQL *irql) wstdcall;void KeReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wstdcall;KIRQL KeAcquireSpinLockRaiseToDpc(NT_SPIN_LOCK *lock) wstdcall;void IoAcquireCancelSpinLock(KIRQL *irql) wstdcall;void IoReleaseCancelSpinLock(KIRQL irql) wstdcall;void RtlCopyMemory(void *dst, const void *src, SIZE_T length) wstdcall;NTSTATUS RtlUnicodeStringToAnsiString (struct ansi_string *dst, const struct unicode_string *src, BOOLEAN dup) wstdcall;NTSTATUS RtlAnsiStringToUnicodeString (struct unicode_string *dst, const struct ansi_string *src, BOOLEAN dup) wstdcall;void RtlInitAnsiString(struct ansi_string *dst, const char *src) wstdcall;void RtlInitString(struct ansi_string *dst, const char *src) wstdcall;void RtlInitUnicodeString(struct unicode_string *dest, const wchar_t *src) wstdcall;void RtlFreeUnicodeString(struct unicode_string *string) wstdcall;void RtlFreeAnsiString(struct ansi_string *string) wstdcall;LONG RtlCompareUnicodeString(const struct unicode_string *s1, const struct unicode_string *s2, BOOLEAN case_insensitive) wstdcall;void RtlCopyUnicodeString(struct unicode_string *dst, struct unicode_string *src) wstdcall;NTSTATUS RtlUpcaseUnicodeString(struct unicode_string *dst, struct unicode_string *src, BOOLEAN alloc) wstdcall;void KeInitializeTimer(struct nt_timer *nt_timer) wstdcall;void KeInitializeTimerEx(struct nt_timer *nt_timer, enum timer_type type) wstdcall;BOOLEAN KeSetTimerEx(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, LONG period_ms, struct kdpc *kdpc) wstdcall;BOOLEAN KeSetTimer(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, struct kdpc *kdpc) wstdcall;BOOLEAN KeCancelTimer(struct nt_timer *nt_timer) wstdcall;void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall;struct nt_thread *KeGetCurrentThread(void) wstdcall;NTSTATUS ObReferenceObjectByHandle(void *handle, ACCESS_MASK desired_access, void *obj_type, KPROCESSOR_MODE access_mode, void **object, void *handle_info) wstdcall;void adjust_user_shared_data_addr(char *driver, unsigned long length);#define IoCompleteRequest(irp, prio) IofCompleteRequest(irp, prio)#define IoCallDriver(dev, irp) IofCallDriver(dev, irp)#if defined(IO_DEBUG)#define DUMP_IRP(irp) \do { \ struct io_stack_location *irp_sl; \ irp_sl = IoGetCurrentIrpStackLocation(irp); \ IOTRACE("irp: %p, stack size: %d, cl: %d, sl: %p, dev_obj: %p, " \ "mj_fn: %d, minor_fn: %d, nt_urb: %p, event: %p", \ irp, irp->stack_count, (irp)->current_location, \ irp_sl, irp_sl->dev_obj, irp_sl->major_fn, \ irp_sl->minor_fn, IRP_URB(irp), \ (irp)->user_event); \} while (0)#else#define DUMP_IRP(irp) do { } while (0)#endif#endif // _NTOSKERNEL_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -