📄 wdf.h
字号:
{
if(old_dev->Flags & DO_BUFFERED_IO)
new_dev->Flags &= DO_BUFFERED_IO;
if(old_dev->Flags & DO_DIRECT_IO)
new_dev->Flags &= DO_DIRECT_IO;
if (old_dev->Characteristics & FILE_DEVICE_SECURE_OPEN)
new_dev->Characteristics &= FILE_DEVICE_SECURE_OPEN;
}
// 这个例程把源设备绑定到目标设备的设备栈中去,并返回源设备所直
// 接绑定的设备。注意源设备未必直接绑定在目标设备上。它应绑定在
// 目标设备的设备栈的顶端。
_inline wd_stat wd_dev_attach(in wd_dev *src,
in wd_dev *dst,
in out wd_dev **attached)
{
*attached = dst;
*attached = IoAttachDeviceToDeviceStack(src,dst);
if(*attached == NULL)
return wd_stat_no_such_dev;
return wd_stat_suc;
}
_inline wd_void wd_dev_dettach(in wd_dev *dst)
{
IoDetachDevice(dst);
}
// 得到设备扩展
_inline wd_void * wd_dev_ext(wd_dev *dev)
{
return (dev->DeviceExtension);
}
/////////////////////////////// 事件 //////////////////////////////////
typedef KEVENT wd_event;
_inline wd_void wd_event_init(wd_event *event)
{
KeInitializeEvent(event,NotificationEvent,FALSE);
}
_inline wd_void wd_event_set(wd_event *event)
{
KeSetEvent(event,IO_NO_INCREMENT,FALSE);
}
_inline wd_stat wd_event_wait(wd_event *event)
{
return KeWaitForSingleObject(event,Executive,KernelMode,FALSE,NULL);
}
/////////////////////////////// 互斥量 /////////////////////////////////
typedef KMUTEX wd_mutex;
_inline wd_mutex_init(wd_mutex *mutex)
{
KeInitializeMutex(mutex,0);
}
_inline wd_mutex_hold(wd_mutex *mutex)
{
while(KeWaitForSingleObject(mutex,
Executive,
KernelMode,
FALSE,
0)!=wd_stat_suc){};
}
_inline wd_mutex_loose(wd_mutex *mutex)
{
KeReleaseMutex(mutex,FALSE);
}
typedef KSPIN_LOCK wd_splock;
typedef KIRQL wd_irql;
typedef struct _wd_spin{
wd_splock splock;
wd_irql irql;
} wd_spin;
_inline wd_void wd_spin_init(wd_spin *spin)
{
KeInitializeSpinLock(&spin->splock);
}
_inline wd_void wd_spin_hold(wd_spin *spin)
{
KeAcquireSpinLock(&spin->splock,&spin->irql);
}
_inline wd_void wd_spin_loose(wd_spin *spin)
{
KeReleaseSpinLock(&spin->splock,spin->irql);
}
/////////////////////////////// 任务 ///////////////////////////////////
typedef WORK_QUEUE_ITEM wd_work_item;
typedef PWORKER_THREAD_ROUTINE wd_work_func;
// 任务的初始化
_inline wd_void wd_work_init(wd_work_item *item,
wd_work_func worker,
wd_void *context)
{
ExInitializeWorkItem(item,worker,context);
}
// 三种任务队列
typedef enum _wd_work_quque_type{
wd_work_crit = CriticalWorkQueue,
wd_work_delay = DelayedWorkQueue,
wd_work_hyper = HyperCriticalWorkQueue
} wd_work_queue_type;
_inline wd_void wd_work_queue(in wd_work_item *item,
in wd_work_queue_type type)
{
ExQueueWorkItem(item,(WORK_QUEUE_TYPE)type);
}
_inline wd_void wd_work_run(in wd_work_item *item)
{
(item->WorkerRoutine)(item->Parameter);
}
enum {
wd_irql_passive = PASSIVE_LEVEL
};
_inline wd_irql wd_get_cur_irql()
{
return KeGetCurrentIrql();
}
typedef PDRIVER_FS_NOTIFICATION wdff_notify_func;
_inline wd_void wd_delay_milli_se(wd_ulong milli_sec)
{
wd_llong delay = milli_sec*(-10)*1000;
wd_lgint interval;
interval.QuadPart = delay;
KeDelayExecutionThread(KernelMode,FALSE,&interval);
}
wd_stat wdff_reg_notify(
in wd_drv *driver,
in wdff_notify_func func
);
// 用于分发例程设置的函数
wd_void wd_drv_set_unload(
in wd_drv* driver,
wd_void (*unload)(in wd_drv *driver));
wd_void wd_drv_set_dispatch(
in wd_drv* driver,
in wd_disp_fuc disp);
wd_void wd_drv_set_create(
in wd_drv* driver,
in wd_disp_fuc create);
wd_void wd_drv_set_clean_up(
in wd_drv* driver,
in wd_disp_fuc clean_up);
wd_void wd_drv_set_file_sys_control(
in wd_drv* driver,
in wd_disp_fuc control);
wd_void wd_drv_set_close(
in wd_drv* driver,
in wd_disp_fuc read);
_inline wd_void wd_drv_set_read(
in wd_drv* driver,
in wd_disp_fuc read)
{
driver->MajorFunction[IRP_MJ_READ] = read;
}
_inline wd_void wd_drv_set_write(
in wd_drv* driver,
in wd_disp_fuc write)
{
driver->MajorFunction[IRP_MJ_WRITE] = write;
}
_inline wd_void wd_irp_set_comp(wd_irp *irp,
wd_irp_comp_func comp,
wd_void *context)
{
IoSetCompletionRoutine(irp,comp,context,
wd_true,wd_true,
wd_true);
}
_inline wd_file *wd_irp_file(wd_irpsp *irpsp)
{
return irpsp->FileObject;
}
_inline wd_lgint wd_irp_write_offset(wd_irpsp *irpsp)
{
return irpsp->Parameters.Write.ByteOffset;
}
_inline wd_size wd_irp_write_length(wd_irpsp *irpsp)
{
return irpsp->Parameters.Write.Length;
}
_inline wd_void wd_irp_read_offset_set(wd_irpsp *irpsp,wd_lgint offset)
{
irpsp->Parameters.Read.ByteOffset = offset;
}
_inline wd_lgint wd_irp_read_offset(wd_irpsp *irpsp)
{
return irpsp->Parameters.Read.ByteOffset;
}
_inline wd_void wd_file_offset_add(wd_file *file,wd_ulong len)
{
file->CurrentByteOffset.QuadPart += len;
}
_inline wd_void wd_file_offset_set(wd_file *file,wd_lgint offset)
{
file->CurrentByteOffset = offset;
}
_inline wd_lgint wd_file_offset(wd_file *file)
{
return file->CurrentByteOffset;
}
_inline wd_void wd_irp_read_length_set(wd_irpsp *irpsp,
wd_ulong length)
{
irpsp->Parameters.Read.Length = length;
}
_inline wd_mdl *wd_irp_mdl_address(wd_irp *irp)
{
return irp->MdlAddress;
}
_inline wd_mdl *wd_irp_mdl(wd_irp *irp)
{
return irp->MdlAddress;
}
_inline wd_void wd_irp_mdl_address_set(wd_irp *irp,
wd_mdl *mdl)
{
irp->MdlAddress = mdl;
}
_inline wd_void wd_irp_mdl_set(wd_irp *irp,
wd_mdl *mdl)
{
irp->MdlAddress = mdl;
}
_inline wd_void wd_irp_user_buf_set(wd_irp *irp,
wd_void *user_buf)
{
irp->UserBuffer = user_buf;
}
_inline wd_void * wd_irp_user_buf(wd_irp *irp)
{
return irp->UserBuffer;
}
_inline wd_size wd_irp_read_length(wd_irpsp *irpsp)
{
return irpsp->Parameters.Read.Length;
}
_inline wd_void *wd_mdl_vaddr(wd_mdl *mdl)
{
return MmGetSystemAddressForMdlSafe(mdl,NormalPagePriority);
}
typedef struct _wd_set {
wd_void *elems[255];
wd_spin lock;
} wd_set;
_inline wd_void wd_set_init(wd_set *myset)
{
wd_memzero(myset->elems,sizeof(wd_void *)*255);
wd_spin_init(&myset->lock);
}
_inline wd_bool wd_set_insert(wd_set * myset,
wd_void *elem)
{
wd_ulong i;
wd_spin_hold(&myset->lock);
for(i=0;i<255;i++)
{
if(myset->elems[i] == 0)
{
myset->elems[i] = elem;
wd_spin_loose(&myset->lock);
return wd_true;
}
}
wd_spin_loose(&myset->lock);
return wd_false;
}
_inline wd_bool wd_set_in(wd_set *myset,
wd_void *elem)
{
wd_ulong i;
for(i=0;i<255;i++)
{
if(myset->elems[i] == elem)
return wd_true;
}
return wd_false;
}
_inline wd_void wd_set_delete(wd_set * myset,
wd_void *elem)
{
wd_ulong i;
wd_spin_hold(&myset->lock);
for(i=0;i<255;i++)
{
if(myset->elems[i] == elem)
myset->elems[i] = 0;
}
wd_spin_loose(&myset->lock);
}
_inline wd_void wd_mdl_free(wd_mdl *mdl)
{
IoFreeMdl(mdl);
}
// 这个这个东西分配mdl,缓冲必须是非分页的。这玩意可以在dispatch level跑。
_inline wd_mdl *wd_mdl_alloc(wd_void* buf,
wd_ulong length)
{
wd_mdl * pmdl = IoAllocateMdl(buf,length,wd_false,wd_false,NULL);
if(pmdl == NULL)
return NULL;
MmBuildMdlForNonPagedPool(pmdl);
return pmdl;
}
// 这两个函数相当重要,其意义请看"关于C00000E8错误"一文
_inline wd_void *wd_map_user_buffer (
in wd_void *KernelAddress,
in wd_ulong Length,
out wd_mdl **Mdl
)
{
*Mdl = IoAllocateMdl(KernelAddress, Length, FALSE, FALSE, NULL);
if (*Mdl == NULL)
{
return NULL; //or you can raise STATUS_INSUFFICIENT_RESOURCES here
}
MmProbeAndLockPages(*Mdl, KernelMode, IoModifyAccess);
return MmMapLockedPages(*Mdl, UserMode);
}
_inline wd_void wd_unmap_user_buffer(
in wd_void *UserAddress,
in wd_mdl *Mdl)
{
MmUnmapLockedPages(UserAddress, Mdl);
MmUnlockPages(Mdl);
IoFreeMdl(Mdl);
}
// 经常要用的一个函数,做时间限制.这个函数比较大,但是依然内联,
// 是为了防止方便破解
_inline wd_bool wd_time_check(wd_long year,
wd_long month,
wd_long day)
{
LARGE_INTEGER now,limit;
TIME_FIELDS now_fields;
// 得到系统时间,并设置到
KeQuerySystemTime(&now);
RtlTimeToTimeFields(&now,&now_fields);
if( year > now_fields.Year)
return TRUE;
else if(year < now_fields.Year)
return FALSE;
if( month > now_fields.Month)
return TRUE;
else if(month < now_fields.Month)
return FALSE;
if( day > now_fields.Day)
return TRUE;
else if(day < now_fields.Day)
return FALSE;
return TRUE;
}
#endif //_WIN_DRV_FILE_SYS_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -