Windows驱动_WSK驱动之四WSK例程

                最近看了好多文章,也写了好多博客,但是,最近少了很多实践的关系,这一部分是项目的问题,其实大部分还是自己的问题,今天,竟然,知道,随便修改一点微软的例子还可以赚钱,之前自己还真是没有想到的。后续,自己要好好的理解下例子,好好的实践一下。今天,让我知道,我做这么多,看这么多,都是有用的,有帮助的。所以,自己还是要立足这一块,好好的往里面深挖下去。

    

              今天趁热打铁,来看一下微软的WDK中的有关WSK的例子,后续,主要的精力还是要放在这些例子的实现和理解上。闲话不说,首先来看驱动的入口函数。

  
  NTSTATUS
  DriverEntry(
   _In_ PDRIVER_OBJECT DriverObject,
   _In_ PUNICODE_STRING RegistryPath
  )
  {
   NTSTATUS status;

   WSK_CLIENT_NPI wskClientNpi;


            //这里首先定义了一个结构体,WSK_CLIENT_NPI,我们先看一下这个结构体。
   
   typedef struct _WSK_CLIENT_NPI {
    PVOID                     ClientContext;
    const WSK_CLIENT_DISPATCH *Dispatch;
   } WSK_CLIENT_NPI, *PWSK_CLIENT_NPI;
   
            MSDN中的解释是,这个结构是是标识Network Programming Interface(NPI),执行是通过WSK客户端来实现的。

   UNREFERENCED_PARAMETER(RegistryPath);

   PAGED_CODE();
    
   // Allocate a socket context that will be used for queueing an operation
   // to setup a listening socket that will accept incoming connections
   WskSampleListeningSocketContext = WskSampleAllocateSocketContext(
                                            &WskSampleWorkQueue, 0);
           
   这里为套接字的操作定义了全局的上下文,用来保存数据。


   if(WskSampleListeningSocketContext == NULL) {
    return STATUS_INSUFFICIENT_RESOURCES;
   }

   // Register with WSK.
   //填充WSK_CLIENT_NPI结构体成员。
   wskClientNpi.ClientContext = NULL;
   wskClientNpi.Dispatch = &WskSampleClientDispatch;
   status = WskRegister(&wskClientNpi, &WskSampleRegistration);
   //看下这个WskRegister函数
   NTSTATUS WskRegister(
    _In_   PWSK_CLIENT_NPI WskClientNpi,
    _Out_  PWSK_REGISTRATION WskRegistration
   );
   
   这里这个输出的参数标识了WSK应用注册实例的内存地址的指针。后面我们需要使用这个地址的。这个是放在全局变量中。

   if(!NT_SUCCESS(status)) {
    WskSampleFreeSocketContext(WskSampleListeningSocketContext);
    return status;
   }
             下面初始化了一个全局工作队列。
   // Initialize and start the global work queue
   status = WskSampleStartWorkQueue(&WskSampleWorkQueue);
   这里主要是做初始化的动作,创建了一个线程,并设置了一个例程,WskSampleWorkerThread。
   
   NTSTATUS
   WskSampleStartWorkQueue(
    _Out_ PWSKSAMPLE_WORK_QUEUE WorkQueue
   )
   {
    NTSTATUS status;
    HANDLE threadHandle;


    PAGED_CODE();
    
    InitializeSListHead(&WorkQueue->Head);
    KeInitializeEvent(&WorkQueue->Event, SynchronizationEvent, FALSE);
    WorkQueue->Stop = FALSE;


    status = PsCreateSystemThread(
      &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL,
      WskSampleWorkerThread, WorkQueue);


    if(!NT_SUCCESS(status)) {
     return status;
    }


    status = ObReferenceObjectByHandle(
      threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode,
      &WorkQueue->Thread, NULL);
    
    ZwClose(threadHandle);


    if(!NT_SUCCESS(status)) {
     WorkQueue->Stop = TRUE;
     KeSetEvent(&WorkQueue->Event, 0, FALSE);
    }


     return status;
   }
   
   再看一下这个线程:我们创建这个线程的时候,将WorkQueue当成参数传送给例程。
   
   VOID
   WskSampleWorkerThread (
    _In_ PVOID Context
   )
   {
    PWSKSAMPLE_WORK_QUEUE workQueue;
    PSLIST_ENTRY listEntryRev, listEntry, next;
    
    PAGED_CODE();


    workQueue = (PWSKSAMPLE_WORK_QUEUE)Context;


    for(;;) {
        
     // Flush all the queued operations into a local list
     listEntryRev = InterlockedFlushSList(&workQueue->Head);


     if(listEntryRev == NULL) {


      // There's no work to do. If we are allowed to stop, then stop.
      if(workQueue->Stop) {
       DoTraceMessage(TRCINFO, "WorkerThread: WQ %p exit", workQueue);
       break;
      }


      DoTraceMessage(TRCINFO, "WorkerThread: WQ %p wait", workQueue);


      // Otherwise, wait for more operations to be enqueued.
      KeWaitForSingleObject(&workQueue->Event, 
       Executive, KernelMode, FALSE, 0);
       continue;
     }


     DoTraceMessage(TRCINFO, "WorkerThread: WQ %p process", workQueue);


     // Need to reverse the flushed list in order to preserve the FIFO order
     listEntry = NULL;
     while (listEntryRev != NULL) {
      next = listEntryRev->Next;
      listEntryRev->Next = listEntry;
      listEntry = listEntryRev;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值