编写一个线程
用来对文件进行枚举
typedef struct _THREAD_EVENT
{
KEVENT most_wait_thread;//这里是主线程唤醒辅线程时 主线程对待的互迟量
KEVENT hyp_wait_thread;//这时主线程唤醒辅线程的互斥量
WCHAR* file_name;//要枚举的文件夹
PVOID in_buffer;//进行枚举后文件结构所在缓存,也是用户传进的缓存
ULONG buffer_length;
}THREAD_EVENT,*PTHREAD_EVENT;
void io_thread(void)
{
PIRP irp = NULL;
PIO_STACK_LOCATION irp_sp;
OBJECT_ATTRIBUTES ob;
KEVENT event;
HANDLE hfile;
IO_STATUS_BLOCK stat;
UNICODE_STRING file_name;
PDEVICE_OBJECT pfile_device;
PFILE_OBJECT pfile_object = NULL;
NTSTATUS ntstatus;
DbgPrint("begin/n");
KeWaitForSingleObject(&thread_event.hyp_wait_thread,Executive,KernelMode,FALSE,NULL);
//创建线成后则线程进入对待状态,等待主线程唤醒
DbgPrint("success/n");
KeInitializeEvent(&event, NotificationEvent, FALSE);
hfile = open_file(thread_event.file_name,
FILE_READ_DATA,
FILE_SHARE_READ);//为传入的文件创建局柄
if(!hfile){
return;
}
ntstatus = ObReferenceObjectByHandle(hfile,GENERIC_READ,*IoFileObjectType,KernelMode,(PVOID*)&pfile_object,0);//得到object对象
ZwClose(hfile);
if (!NT_SUCCESS(ntstatus)) {
return;
}
if (pfile_object->Vpb != NULL && pfile_object->Vpb->DeviceObject != NULL) {
pfile_device = pfile_object->Vpb->DeviceObject;//为了得到最底层的fsd绕过中间的过滤层
}
else
{
DbgPrint(" pFileDevice fails/n");
return;
}
if(!(pfile_device->StackSize)){
DbgPrint("myfsd: DStackSize is zero./n");
return;
}
irp = IoAllocateIrp(pfile_device->StackSize, TRUE);
if(!irp) {
DbgPrint("myfsd: cannot allocate irp./n");
return;
}
// RtlInitUnicodeString (&FileNtfs,devNtfs);
DbgPrint("0x%08x/n",irp->UserBuffer);
irp->UserBuffer=thread_event.in_buffer;
DbgPrint("uerbufffer:0x%08x/n",irp->UserBuffer);
//DbgPrint("%d/n",sizeof(FILE_BOTH_DIR_INFORMATION));
//memset(Irp->UserBuffer,0,100*sizeof(FILE_BOTH_DIR_INFORMATION));
DbgPrint("pfileobject/n");
irp->UserEvent = &event;
irp->UserIosb = &stat;
irp->Tail.Overlay.Thread = KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = pfile_object;
irp->RequestorMode = KernelMode;
irp->PendingReturned = FALSE;
irp->MdlAddress = NULL;
irp->Cancel = FALSE;
irp->CancelRoutine = NULL;
irp->Tail.Overlay.AuxiliaryBuffer = NULL;
irp->Flags = IRP_SYNCHRONOUS_PAGING_IO;
irp_sp = IoGetNextIrpStackLocation(irp);
irp_sp->FileObject=pfile_object;
irp_sp->DeviceObject=pfile_device;
irp_sp->MajorFunction=IRP_MJ_DIRECTORY_CONTROL;
irp_sp->MinorFunction=IRP_MN_QUERY_DIRECTORY;
irp_sp->Flags=0;
irp_sp->Parameters.QueryDirectory.FileInformationClass = FileNamesInformation;
//irpSP->Parameters.QueryDirectory.FileName = &FileNtfs;
irp_sp->Parameters.QueryDirectory.Length = thread_event.buffer_length;
DbgPrint("irpsp/n");
DbgPrint("myfsd:Length %d/n",irp_sp->Parameters.QueryDirectory.Length);
//创建irp直接发送给object对象 以得到文件列表
IoSetCompletionRoutine(
irp,
io_completion,
&event,
TRUE,
TRUE,
TRUE
);
DbgPrint("io/n");
ntstatus = IoCallDriver( pfile_device, irp);
//DbgPrint("IoCallDriver have been completed/n");
if (ntstatus == STATUS_PENDING)
{
//wait for the io to complete
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0);
ntstatus = stat.Status;
}
if (!NT_SUCCESS(ntstatus)) {
DbgPrint("myfsd:Wait Fails/n");
return;
}
irp->UserBuffer = NULL;
IoFreeIrp(irp);
KeClearEvent(&thread_event.hyp_wait_thread);
KeSetEvent(&thread_event.most_wait_thread,0,FALSE);
return;
}
VOID work_thr(IN PVOID pcontext)
{
io_thread();
PsTerminateSystemThread(STATUS_SUCCESS);
}
在device_control中的相关代码 用来唤醒枚举线程
thread_event设置为一个全局变量,用来控制枚举线程
thread_event.in_buffer = poutput_buffer;
DbgPrint("inbuffer:0%08x/n",thread_event.in_buffer);
thread_event.buffer_length = output_buffer_length;
thread_event.file_name = L"//??//D://";
KeSetEvent(&thread_event.hyp_wait_thread,0,FALSE);
KeWaitForSingleObject(&thread_event.most_wait_thread,Executive,KernelMode,FALSE,NULL);
KeClearEvent(&thread_event.most_wait_thread);
// KeSetEvent(&ke_event,0,FALSE);
DbgPrint("Event/n");
io_status->Information = output_buffer_length;
break;
在DriverEntry中创建一个线程 即:
KeInitializeEvent(&thread_event.most_wait_thread,SynchronizationEvent,FALSE);
KeInitializeEvent(&thread_event.hyp_wait_thread,SynchronizationEvent,FALSE);
//KeInitializeEvent(&ke_event,SynchronizationEvent,FALSE);
ntstatus = PsCreateSystemThread(&h_thread,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
work_thr,
NULL
);//创建线程
c代码的重用实在太差了
哎 面向对象来解决驱动环境中变成或许会好些
自动生成一部分代码 看到做java的同学 用Eclipse画画图就把代码的框架出来了
实在是羡慕
c++来自动生成驱动主体框架代码的可行性不知道有没有 。。。
不过怎么说windows操作系统是面向对象设计的 说不定有一部分可行性