createthread创建的IST用NDIS的workitem替换后对系统会有何影响?

clnemo   2007-3-5 11:30 楼主
各位高手:
    我目前碰到一个问题,原来是用createthread创建的IST,有人想用NDIS的workitem替换,实现在WINDOWS下的可移植性。
    不知在WINCE下用用NDIS的workitem替换CREATETHREAD有何影响,有没有人试过?

回复评论 (6)

上楼我想请问一下,NDIS中直接用CreatThread开启线程好像行不通吧??看我在NDIS IM 的passthru.dll中在protocol.c中的ProtocolReceivePacket添加的代码,如下,模拟器debug版本编译后行不通!说CreatThread警告视为错误。
INT
ProtocolReceivePacket(
   IN NDIS_HANDLE hProtocolBindingContext,
   IN PNDIS_PACKET pPacket
)
/*++

Arguments:
   ProtocolBindingContext - Pointer to our adapter structure.
   Packet - Pointer to the packet

Return Value:
   == 0 -> We are done with the packet
   != 0 -> We will keep the packet and call NdisReturnPackets() this
           many times when done.
--*/
{
   BINDING* pBinding = (BINDING*)hProtocolBindingContext;
   INT iCode = 0;
   NDIS_STATUS status;
   PNDIS_PACKET pIMPacket;
   INT rc;
   NDIS_HANDLE hWriteThread;
   //添加的
           UINT PacketSize;
       PVOID pPacketContent;
       UCHAR* pBuf;
       UINT BufLength;
       NDIS_BUFFER * pNext;
       UINT i;
   //结束
#ifdef NDIS51
   
           BOOLEAN bRemaining;
#endif
   // Drop the packet silently if the upper miniport edge isn't initialized
   DBGPRINT(("+++++++++++++++ get into ProtocolReceivePacket  ----------\n"));
   if (!pBinding->hMPBinding) goto cleanUp;
   DBGPRINT(("+++++++++++++++ pBinding->hMPBinding is not NULL ----------\n"));
#ifdef NDIS51
   //
   // Check if we can reuse the same packet for indicating up.
   // See also: ProtocolReceive().
   //
   (VOID)NdisIMGetCurrentPacketStack(pPacket, &bRemaining);
   if (bRemaining) {
      //
      // We can reuse "Packet". Indicate it up and be done with it.
      //
      //begin
      NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
      if (status == NDIS_STATUS_SUCCESS) {

      PASSTHRU_PR_RECV* pProtocolRecv;
      
      pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
      pProtocolRecv->pOriginalPacket = pPacket;

      pIMPacket->Private.Head = pPacket->Private.Head;
      pIMPacket->Private.Tail = pPacket->Private.Tail;
      NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
      NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
      status = NDIS_GET_PACKET_STATUS(pPacket);
      NDIS_SET_PACKET_STATUS(pIMPacket, status);

      NDIS_SET_PACKET_HEADER_SIZE(
         pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
      );
      //创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
      //然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
      //然后打开内存映射文件,把buffer data写入内存映射文件N次,
      //释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,设置hReadEvent信号,
      //利用事件对象等待App(App线程在调用等待中获得互斥体,得到对文件的读取和写入权限,读取数据,清空文件,
      //释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下:
      
      hWriteThread=CreatThread(NULL,0,WriteThread,pIMPacket,0,&rc);//rc表示线程ID
      if(hWriteThread)
      CloseHandle(hWriteThread);
DBGPRINT(("++==>PASSTHRU::next we willshow the copied packet buffer context++++++++\n"));
//end
      status = NDIS_GET_PACKET_STATUS(pPacket);
      NdisMIndicateReceivePacket(pBinding->hMPBinding, &pPacket, 1);
      iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
      goto cleanUp;
   }
#endif // NDIS51
   // actualy  define NDIS51
   // Get a packet off the pool and indicate that up
   //
   NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);

   if (status == NDIS_STATUS_SUCCESS) {

      PASSTHRU_PR_RECV* pProtocolRecv;
      
      pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
      pProtocolRecv->pOriginalPacket = pPacket;

      pIMPacket->Private.Head = pPacket->Private.Head;
      pIMPacket->Private.Tail = pPacket->Private.Tail;

      //
      // Get the original packet (it could be the same packet as the one
      // received or a different one based on the number of layered miniports
      // below) and set it on the indicated packet so the OOB data is visible
      // correctly to protocols above us.
      //
      NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));

      //
      // Set Packet Flags
      //
      NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));

      status = NDIS_GET_PACKET_STATUS(pPacket);
      NDIS_SET_PACKET_STATUS(pIMPacket, status);

      NDIS_SET_PACKET_HEADER_SIZE(
         pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
      );

      NdisMIndicateReceivePacket(pBinding->hMPBinding, &pIMPacket, 1);
          //++++
DBGPRINT(("++==>PASSTHRU::show the copied packet buffer context++++++++\n"));

         //把数据包内容从Packet拷贝到pPacketContent
         NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
        NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
        if (pPacketContent!=NULL)
         {
         NdisZeroMemory (pPacketContent, 2000);
         NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
         NdisMoveMemory(pPacketContent, pBuf, BufLength);
         i = BufLength;
         pNext = pIMPacket->Private.Head;
         for(;;)
        {
          if(pNext == pIMPacket->Private.Tail)
            break;
          pNext = pNext->Next; //指针后移
          if(pNext == NULL)
            break;
        NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);

        NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
        i+=BufLength;
         }
         DBGPRINT(("+++++++++++++++now we should creat a thread to copy data and display  ----------\n"));
        }
        //++然后创建线程对内存映射文件建立并且写入数据,
                //当写完一个包后关闭文件。
        //CreatThread(NULL,0,WriteMMFile,        pPacketContent
                //使用共享内存方式,因为减少了系统调用的开销,可以避免速度下降。
        ////添加的代码结束!
      //
      // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
      // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
      // it might have changed! Use the value saved in the local variable.
      //
      if (status == NDIS_STATUS_RESOURCES) {
         //
         // Our ReturnPackets handler will not be called for this packet.
         // We should reclaim it right here.
         //
         NdisFreePacket(pIMPacket);
      }

      iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;

   }

cleanUp:
DBGPRINT(("++++++++++++++ProtocolReceivePacket Over!!!!!!!!!! ----------\n"));
   return iCode;
}

往下看,希望得到交流!
点赞  2007-11-29 19:51
上楼我想请问一下,NDIS中直接用CreatThread开启线程好像行不通吧??看我在NDIS IM 的passthru.dll中在protocol.c中的ProtocolReceivePacket添加的代码,如下,模拟器debug版本编译后行不通!说CreatThread警告视为错误。
INT
ProtocolReceivePacket(
   IN NDIS_HANDLE hProtocolBindingContext,
   IN PNDIS_PACKET pPacket
)
/*++

Arguments:
   ProtocolBindingContext - Pointer to our adapter structure.
   Packet - Pointer to the packet

Return Value:
   == 0 -> We are done with the packet
   != 0 -> We will keep the packet and call NdisReturnPackets() this
           many times when done.
--*/
{
   BINDING* pBinding = (BINDING*)hProtocolBindingContext;
   INT iCode = 0;
   NDIS_STATUS status;
   PNDIS_PACKET pIMPacket;
   INT rc;
   NDIS_HANDLE hWriteThread;
   //添加的
           UINT PacketSize;
       PVOID pPacketContent;
       UCHAR* pBuf;
       UINT BufLength;
       NDIS_BUFFER * pNext;
       UINT i;
   //结束
#ifdef NDIS51
   
           BOOLEAN bRemaining;
#endif
   // Drop the packet silently if the upper miniport edge isn't initialized
   DBGPRINT(("+++++++++++++++ get into ProtocolReceivePacket  ----------\n"));
   if (!pBinding->hMPBinding) goto cleanUp;
   DBGPRINT(("+++++++++++++++ pBinding->hMPBinding is not NULL ----------\n"));
#ifdef NDIS51
   //
   // Check if we can reuse the same packet for indicating up.
   // See also: ProtocolReceive().
   //
   (VOID)NdisIMGetCurrentPacketStack(pPacket, &bRemaining);
   if (bRemaining) {
      //
      // We can reuse "Packet". Indicate it up and be done with it.
      //
      //begin
      NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
      if (status == NDIS_STATUS_SUCCESS) {

      PASSTHRU_PR_RECV* pProtocolRecv;
      
      pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
      pProtocolRecv->pOriginalPacket = pPacket;

      pIMPacket->Private.Head = pPacket->Private.Head;
      pIMPacket->Private.Tail = pPacket->Private.Tail;
      NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
      NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
      status = NDIS_GET_PACKET_STATUS(pPacket);
      NDIS_SET_PACKET_STATUS(pIMPacket, status);

      NDIS_SET_PACKET_HEADER_SIZE(
         pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
      );
      //创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
      //然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
      //然后打开内存映射文件,把buffer data写入内存映射文件N次,
      //释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,设置hReadEvent信号,
      //利用事件对象等待App(App线程在调用等待中获得互斥体,得到对文件的读取和写入权限,读取数据,清空文件,
      //释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下:
      
      hWriteThread=CreatThread(NULL,0,WriteThread,pIMPacket,0,&rc);//rc表示线程ID
      if(hWriteThread)
      CloseHandle(hWriteThread);
DBGPRINT(("++==>PASSTHRU::next we willshow the copied packet buffer context++++++++\n"));
//end
      status = NDIS_GET_PACKET_STATUS(pPacket);
      NdisMIndicateReceivePacket(pBinding->hMPBinding, &pPacket, 1);
      iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
      goto cleanUp;
   }
#endif // NDIS51
   // actualy  define NDIS51
   // Get a packet off the pool and indicate that up
   //
   NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);

   if (status == NDIS_STATUS_SUCCESS) {

      PASSTHRU_PR_RECV* pProtocolRecv;
      
      pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
      pProtocolRecv->pOriginalPacket = pPacket;

      pIMPacket->Private.Head = pPacket->Private.Head;
      pIMPacket->Private.Tail = pPacket->Private.Tail;

      //
      // Get the original packet (it could be the same packet as the one
      // received or a different one based on the number of layered miniports
      // below) and set it on the indicated packet so the OOB data is visible
      // correctly to protocols above us.
      //
      NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));

      //
      // Set Packet Flags
      //
      NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));

      status = NDIS_GET_PACKET_STATUS(pPacket);
      NDIS_SET_PACKET_STATUS(pIMPacket, status);

      NDIS_SET_PACKET_HEADER_SIZE(
         pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
      );

      NdisMIndicateReceivePacket(pBinding->hMPBinding, &pIMPacket, 1);
          //++++
DBGPRINT(("++==>PASSTHRU::show the copied packet buffer context++++++++\n"));

         //把数据包内容从Packet拷贝到pPacketContent
         NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
        NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
        if (pPacketContent!=NULL)
         {
         NdisZeroMemory (pPacketContent, 2000);
         NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
         NdisMoveMemory(pPacketContent, pBuf, BufLength);
         i = BufLength;
         pNext = pIMPacket->Private.Head;
         for(;;)
        {
          if(pNext == pIMPacket->Private.Tail)
            break;
          pNext = pNext->Next; //指针后移
          if(pNext == NULL)
            break;
        NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);

        NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
        i+=BufLength;
         }
         DBGPRINT(("+++++++++++++++now we should creat a thread to copy data and display  ----------\n"));
        }
        //++然后创建线程对内存映射文件建立并且写入数据,
                //当写完一个包后关闭文件。
        //CreatThread(NULL,0,WriteMMFile,        pPacketContent
                //使用共享内存方式,因为减少了系统调用的开销,可以避免速度下降。
        ////添加的代码结束!
      //
      // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
      // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
      // it might have changed! Use the value saved in the local variable.
      //
      if (status == NDIS_STATUS_RESOURCES) {
         //
         // Our ReturnPackets handler will not be called for this packet.
         // We should reclaim it right here.
         //
         NdisFreePacket(pIMPacket);
      }

      iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;

   }

cleanUp:
DBGPRINT(("++++++++++++++ProtocolReceivePacket Over!!!!!!!!!! ----------\n"));
   return iCode;
}

往下看,希望得到交流!
点赞  2007-11-29 19:51
//the created thread
INT  WINAPI WriteThread(PVIOD pArg)
{  
//创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
      //然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
      //然后打开内存映射文件,把buffer data写入内存映射文件N次,
      //释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,set hReadEvent,reset hWriteEvent,线程返回)
      //利用事件对象hReadEvent促发App等待线程,(App线程在调用等待中获得互斥体,得到对文件的读取权限,读取数据,
      //释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下
//------------------------------------------------------------------------------
                 //把数据包内容从Packet拷贝到pPacketContent
       static UINT  N=0;
       static DWORD  dwOffset=0;
       PNDIS_PACKET pIMPacket;
       UINT PacketSize;
       PVOID pPacketContent;
       LPBYTE pBuf;
       UINT BufLength;
       NDIS_BUFFER * pNext;
       UINT i;
       INT rc;
       *PNDIS_HANDLE hMyMutex;
       *PNDIS_HANDLE hMyFile,hMyFileMap;
       PBYTE pMyFileMem;
       LPTSTR szMyFileName="MyFile";      
       LPTSTR lpWriteEventName="MyWriteEvent";
       LPTSTR lpReadEventName="MyReadEvent";
       LPTSTR lpMutextName="MyMutex";
       //INT rs;
       pIMPacket=(PNDIS_PACKET)pArg;
        NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
        NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
        if (pPacketContent!=NULL)
         {
         NdisZeroMemory (pPacketContent, 2000);
         NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
         NdisMoveMemory(pPacketContent, pBuf, BufLength);
         i = BufLength;
         pNext = pIMPacket->Private.Head;
         for(;;)
        {
          if(pNext == pIMPacket->Private.Tail)
            break;
          pNext = pNext->Next; //指针后移
          if(pNext == NULL)
            break;
        NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
        NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
        i+=BufLength;
         }
}
//然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体(设置超时则线程返回)得到权限
       hWriteEvent=CreatEvent(NULL,TRUE,TURE,lpWriteEventName);
       hReadEvent=CreatEvent(NULL,TRUE,TRUE,lpReadEnentName);
       if(!hWriteEvent||!hReadEvent)
        return  -1;
       rc=WaitForSingleObject(hWriteEvent,2000);
       if(rc==WAit_OBJECT_0){
       hMyMutex=CreatMutex(NULL,TURE, lpMutextName);
      // rs=GetLastError();
      //if(rs==ERROR_ALREADY_EXISTS)
        rc=WaitForSingleObject(hMyMutex,2000);
       if(rc!=WAit_OBJECT_0)
       return 0;
  //然后打开内存映射文件,把buffer data写入内存映射文件N次,   
        hMyFile = CreateFileForMapping (szMyFileName, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL, NULL);

    if (hMyFile== INVALID_HANDLE_VALUE) {
        hMyFile = 0;
        return GetLastError();
    }
   hMyFileMap=CreatFileMapping(hMyFile,NULL,PAGE_MAP_WRITE,0,0,0);
if(hMyFileMap==INVALID_HANDLE_VALUE)
{
CloseHandle(hMyFile);
return 0;
}
  pMyFileMem=(LPBYTE) MapViewOfFile ( hMyFileMap, FILE_MAP_ALL_ACCESS , 0, dwOffset, 0 );
  if(pMyFileMem){
//use the data in my file
      NdisMoveMemory(pMyFileMem,pPacketContent,i);
      N++;
      UnmapViewOfFile(pMyFileMem);
      }
CloseHandle(hMyFileMap);
CloseHandle(hMyFile);
//释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,set hReadEvent,reset hWriteEvent,线程返回)
ReleaseMutex(hMyMutex);
ReleaseMutex(hMyMutex);
if(N>5)
{
SetEvent(hReadEvent);
ResetEvent(hWriteEvent);
}
return 1;

}
else
return -1;
}
//添加线程结束
点赞  2007-11-29 19:52
好象和驱动程序的开发环境有关.

如果你用WIN2000/XP的DDK做开发环境,对某些只在用户态下才适用的API是不能在驱动程序代码里调用的,这里的CreateThread可能就是一个.
点赞  2008-3-29 22:47
好像没那么简单,呵呵.
点赞  2008-4-30 18:13
不会,帮顶
点赞  2008-5-1 06:33
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复