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

📄 wdf.h

📁 Windows文件系统过滤驱动开发教程 . 作者
💻 H
📖 第 1 页 / 共 2 页
字号:
{
    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 + -