anylin
驱动牛犊
驱动牛犊
  • 注册日期2005-06-07
  • 最后登录2008-11-04
  • 粉丝0
  • 关注0
  • 积分365分
  • 威望45点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
阅读:1898回复:1

我这个驱动到底怎么了--高手指点啊

楼主#
更多 发布于:2005-07-23 21:59
  一个虚拟网卡的驱动
请高手看看我的发包和收包部分是否有问题

发包:
通知跟驱动通信的应用程序来取数据

收包:
应用程序把数据写到驱动中,触发一个收包信号

下面是源代码:

//////////////////////////////////////////////////////////////////////
// VNICAdap.cpp: implementation of the VNICAdapter class.
//
// Generated by Network Driver Wizard on 星期一, 五月 09, 2005
//

#include <stdlib.h>
#include "VNICAdap.h"
#include "Global.h"
#include <kexception.h>


////////////////////////////////////////////////////////////////////
// CmpMac
//              比较两个MAC地址是否相等
// Parameters:
//              lmac       -              MAC地址1
//              rmac    -              MAC地址2
// Return:
//              true       -              如果两个MAC地址相等
//              false       -              如果不相等
// Note:
//              静态全局方法
static bool CmpMac(UCHAR * lmac, UCHAR *rmac, int len = 6)
{
       for (int i = 0; i < len ; i++)
       {
              if (lmac != rmac)
              {
                     return false;
              }
       }
       return true;
}


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

VNICAdapter::VNICAdapter() :
       KNdisMiniAdapter(), m_DeviceHandle(NULL),m_pDeviceObject(NULL)              
{
       // TODO: initialize your private sndData members
       //       Do NOT call any NDIS functions in here. Defer to Initialize()
       pFile = NULL;
       pEvent = NULL;

}

VNICAdapter::~VNICAdapter()
{
       // TODO: deallocate all the resources allocated in constructor/Initialize()
       pAdapter = NULL;
      
}

////////////////////////////////////////////////////////////////////
// NDIS callback handlers
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// VNICAdapter::Initialize
//
// MiniportInitialize is a required function that sets up a NIC (or
// virtual NIC) for network I/O operations, claims all hardware resources
// necessary to the NIC in the registry, and allocates resources the driver
// needs to carry out network I/O operations
//
// Parameters:
//              Medium      
//                     Reference to KNdisMedium object that we have to set the medium
//                     type our NIC supports
//              Config
//                     Reference to KNdisConfig object that we use to query various
//                     configuration parameters
// IRQL:
//              PASSIVE_LEVEL
// Return Mode:
//              Synchronous
//
// TODO:
// 1) Select supported medium in Medium object
// 2) Read config parameters if any using Config object
// 3) Allocate h/w resources, pools, etc.
// 4) Register with NDIS using SetAttributes()
// 5) Register Shutdown Handler
// 6) Initialize and enable the NIC.
// NOTE: Be ready to process INTs even before the function exits
//
NDIS_STATUS VNICAdapter::Initialize
                            (IN OUT KNdisMedium& Medium, IN KNdisConfig& Config)
{
       TRACE("VNICAdapter::Initialize() Entered\n");
      
       //保存执针
       pAdapter = this;

       // Select our the Medium:

       if (! Medium.Select(VNIC_MEDIUM_TYPE) )
              KNDIS_RETURN_ERROR (NDIS_STATUS_UNSUPPORTED_MEDIA);

       // Get network address (if any) from the Registry. If specified
       // it will be used instead of burned permanent address:
       if (Config.ReadNetworkAddress(m_CurrentAddress) != NDIS_STATUS_SUCCESS) {
              
              m_CurrentAddress.Invalidate();
              
              //生成一个随机的mac地址,以减少冲突的可能性
              CHAR temp[12];

              //指定随机数生成的种子
              srand( KeQueryTimeIncrement() );
      
              for(int i = 0; i <= 5; i++) {
                     m_CurrentAddress.m_bytes = rand() % 256;
              }

              //转化mac地址
              TranslateAddr(temp, m_CurrentAddress.m_bytes);
              //将生成的mac地址写入注册表
              KNdisString valueStr((PSTR)&temp);
              Config.Write(KNDIS_STRING_CONST("NetworkAddress"), PNDIS_STRING(valueStr));

       }

       //保存mac地址到一个全局变量
       for(int i = 0; i <= 5; i++) {
              mac = m_CurrentAddress.m_bytes;
       }

       // TODO: Read some other config stuff from the Registry, e.g.
      

    // Now let NDIS know about the BUS the NIC is on. Here's where the NDIS/Adapter-instance
       // handshake takes place. This should happen *before* allocating the h/w resources:
       ULONG AttributeFlags =
                     0
#if NDIS51_MINIPORT
                     | NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK // meaning can support surprise removal. See PnpEventNotify()
#endif
              ;

       SetAttributesEx(
              NdisInterfaceInternal,
              AttributeFlags
              );


       // TODO: Configure the bus device further      

       // TODO: Read perm address from the card instead
       m_PermanentAddress = m_CurrentAddress;

       // Set default filter and MAC options. In principle, we should also
       // relay that to our card...
       m_uPacketFilter = NDIS_PACKET_TYPE_DIRECTED |
                                     NDIS_PACKET_TYPE_MULTICAST |
                                     NDIS_PACKET_TYPE_BROADCAST;

       m_uMacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
                                NDIS_MAC_OPTION_RECEIVE_SERIALIZED  |
                                   NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
                                   NDIS_MAC_OPTION_NO_LOOPBACK;

       // TODO:       Start the card up.
      
       //创建一个虚拟设备
    NDIS_STATUS  Status = CreateMyDevice();
       //显示调试信息
       TRACE("VNICAdapter Create Device: %s\n", ((Status)?"FAILED":"OK"));


       return NDIS_STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////
// VNICAdapter::Halt
//
// MiniportHalt is a required function that deallocates resources when
// the NIC is removed and halts the NIC.
//
// Parameters:
//              None
// IRQL:
//              PASSIVE_LEVEL
// Return Mode:
//              Synchronous
//
// NOTE: Miniports has no "unload" for the driver. The Halt() is the last
//       function called into a miniport, so everything should be stopped
//               and freed right here. The KNDIS framework takes care of destroying
//               the adapter object itself, so this member function is merery required
//       to undo things done by the Initialize() above - in the inversed order.
//
//               Alternatevely, the driver writer can move all the deallocations to the
//       destructor: the destructor will be called immediatelly after Halt()
//               returns. Our sample follows this practice.
//
VOID VNICAdapter::Halt(VOID)
{
       TRACE("VNICAdapter::Halt() Entered\n");
       // TODO: Stop the card. Theoretically, however,
       //              our Isr() still can be called, so we should be prepared.


       //删除虚拟出来的设备
#if VNIC_WIN2K
       // win2k,xp系统
       if (m_DeviceHandle) {
              NdisMDeregisterDevice(m_DeviceHandle);
              m_DeviceHandle = NULL;
       }
#else
       // win98系统      
       if (m_pDeviceObject)
              IoDeleteDevice(m_pDeviceObject);              
#endif
       m_pDeviceObject=NULL;

}

////////////////////////////////////////////////////////////////////
// VNICAdapter::Reset
//
// MiniportReset is a required function that issues a hardware reset
// to the NIC and/or resets the driver's software state.
//
// Parameters:
//              AddressingReset
//                     Points to a variable that MiniportReset sets to TRUE if the
//                     NDIS library should call MiniportSetInformation to restore
//                     addressing information to the current values.
// IRQL:
//              DISPATCH_LEVEL
// Return Mode:
//              Synchronous
//
NDIS_STATUS VNICAdapter::Reset
                     (OUT PBOOLEAN AddressingReset)
{
       TRACE("VNICAdapter::Reset() Entered\n");

       // TODO:       Reset the card

       return NDIS_STATUS_SUCCESS;
}
      
////////////////////////////////////////////////////////////////////
// VNICAdapter::Shutdown
//
// MiniportShutdown does nothing more than restore the NIC to its
// initial state (before the miniport's DriverEntry function runs)
//
// Parameters:
//              None
// IRQL:
//              If MiniportShutdown is called due to a user-initiated system shutdown,
//              it runs at IRQL PASSIVE_LEVEL in a system-thread context. If it is called
//              due to an unrecoverable error, MiniportShutdown runs at an arbitrary IRQL
//              and in the context of whatever component raised the error.
// Return Mode:
//              Synchronous
//
VOID VNICAdapter::Shutdown(VOID)
{
       TRACE("VNICAdapter::Shutdown() Entered\n");

       // TODO:       Reset the card for good
}

////////////////////////////////////////////////////////////////////
// VNICAdapter::Send
//
// Transfers a protocol-supplied packet over the network
//
// Parameters:
//              Packet
//                     Points to a packet descriptor specifying the sndData to be transmitted.
//              Flags
//                     Specifies the packet flags, if any, set by the protocol.
// IRQL:
//              DISPATCH_LEVEL
// Return Mode:
//              Asynchronous
// NOTE:
//              The return code determines the ownership of the packet and further
//              interaction between NDIS and our driver. Specifically,
//
//      NDIS_STATUS_SUCCESS - Done with.
//      NDIS_STATUS_PENDING - We keep it until further notice.
//      NDIS_STATUS_RESOURCES - We didn't have the resouces *now*, so tell NDIS
//                              please hold it on until further notice.
// NOTE: Deserialized Miniports should never return NDIS_STATUS_RESOURCES to NDIS,
// and must instead queue it internally.
//
NDIS_STATUS VNICAdapter::Send(
                     IN       PNDIS_PACKET                     Packet,
                     IN       UINT                                   Flags
                     )
{      
      
       TRACE("VNICAdapter::Send() Entered\n");

       // declare for convenience
       KNdisPacket pkt(Packet);
       //保存包的执针
       pPacket = Packet;
       // TODO:       Manage the packet into the hardware.
       // Return NDIS_STATUS_SUCCESS if the packet got submitted to the h/w and
       // NDIS_STATUS_PENDING if it's been queued into m_TxQueue.
       //

       if(notify) {
      
              //把包的内容填充到数据数组中
              KNdisBuffer buf = pkt.QueryFirstBuffer();
              UINT nBufCnt = pkt.QueryBufferCount();
              UINT start = 0;
      
              
              for(UINT i = 0; i < nBufCnt; i++)
              {
                     if(buf.IsValid())
                     {
                            PUCHAR src = (PUCHAR)buf.Address();
                            UINT len = buf.Length();
                            for(UINT j=0; j<len;j++)
                            {
                                   sndData[start + j] = src[j];
                            }

                            start = start + len;

                            buf = buf.GetNext();
                     }

              }
              
      
              //更新包的长度
              packetSize = start;

              //设置事件通知应用程序来取数据
              notify = false;
              pEvent->Set();
              
       } else {

              return NDIS_STATUS_FAILURE;
       }

       if ( 0/* have to postpone the packet */)
       {
              m_TxQueue.InsertTail(pkt);
              return NDIS_STATUS_PENDING;
       }
      
       //更新发送包的数量
       m_GenStats->xmit_ok++;
       return NDIS_STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////
// VNICAdapter::ReturnPacket
//
// This method is called when NDIS returns a packet previuosly
// indicated by IndicateReceive() back to the miniport
//
// Parameters:
//              Packet
//                     Points to a packet descriptor specifying the packet
// IRQL:
//              DISPATCH_LEVEL
// Return Mode:
//              n/a
// NOTE:
//              The packet returns to the "free list" in the Rx area.
//              Reclaim() does the necessary reset of the chained buffer
//              and OOB sndData if any.
VOID VNICAdapter::ReturnPacket(IN PNDIS_PACKET Packet)
{
       TRACE("VNICAdapter::ReturnPacket() Entered Packet=%p\n, Packet");

       // declare for convenience
       KNdisPacket pkt(Packet);
      
       // TODO:       Reclaim the packet back to an internal list


}

////////////////////////////////////////////////////////////////////
// VNICAdapter::CheckForHang
//              Optional function that reports the state of the NIC or monitors
//               the responsiveness of an underlying device driver.
// Parameters:
//              none
// IRQL:
//              IRQL DISPATCH_LEVEL
// Return Mode:
//              Synchronous
// NOTE:
//              By default, the NDIS library calls MiniportCheckForHang
//              approximately every two seconds. If MiniportCheckForHang returns
//              TRUE, NDIS then calls the driver's MiniportReset function.
BOOLEAN VNICAdapter::CheckForHang()
{
       // TODO:       Check the h/w for hang
       return FALSE;
}


#if defined(NDIS51_MINIPORT)
///////////////////////////////////////////////////////////////////////
// Notify on PNP or Power Event (5.1)
//
// Parameters:
//        PnPEvent             - PNP Event Type
//        InformationBuffer    - Buffer With Extra info
//        InformationBufferLength - Size of the buffer
// Returns:
//        none
// Comments:
//        See DDK MiniportPnPEventNotify
VOID VNICAdapter::PnPEventNotify(
                     IN NDIS_DEVICE_PNP_EVENT  PnPEvent,
                     IN PVOID  InformationBuffer,
                     IN ULONG  InformationBufferLength
                  )
{
       switch(PnPEvent) {
       case NdisDevicePnPEventSurpriseRemoved:
              // Surprise Removal
              // "When a miniport driver receives notification of a surprise removal, it should note internally
              // that the device has been removed and cancel any pending IRPs that it sent down to the underlying
              // bus driver. After calling the MiniportPnPEventNotify function to indicate the surprise removal,
              // NDIS calls the miniport's MiniportHalt function. If the miniport driver receives any requests to send
              // packets or query or set OIDs before its MiniportHalt function is called, it should immediately complete
              // such requests with a status value of NDIS_STATUS_NOT_ACCEPTED"
              //
              // @@TODO: Figure what exactly we must do here.
              //         The Halt() method takes care of cancelling the IRPs.
              //                 So, should we do that here now? Or it is OK no still do it on Halt()?
              //                 What's the point of this notification except we know WHY
              //                 the adapter is being Halted...
              //
              TRACE("VNICAdapter::PnPEventNotify: Surprised Removal!\n");
              break;

       case NdisDevicePnPEventPowerProfileChanged:
              //
              // Power change notification.
              // The "AC" notification also triggers when the computer exits the standby mode.
              // TODO: Apply some operational mode adjustments if needed.
              //       E.g., reduce power consumption when switching to battery.
              //
              {
              bool bOnBattery = (*PULONG(InformationBuffer))==NdisPowerProfileBattery;
              TRACE("VNICAdapter::PnPEventNotify: Running on %s\n", (bOnBattery)?"Batterry":"AC");
              }
              break;
       default:
              //
              // Everything else is non-documented in XP DDK
              //
              TRACE("VNICAdapter::PnPEventNotify: Event %u\n", PnPEvent);
              break;
       }
}

///////////////////////////////////////////////////////////////////////
// Cancel Packets Being Sent (5.1)
//
// Parameters:
//        CancelId             - An identifier specifying the packet or group
//                                            of packets whose transmission is being canceled.
// Returns:
//        none
// Comments:
//        Walk the list of not-yet-transmitted packets and cancel them
//
VOID VNICAdapter::CancelSendPackets(              
                     IN PVOID       CancelId
                     )
{
       TRACE("VNICAdapter::CancelSendPackets ID=%p\n", CancelId);

       // m_TxQueue contains the list of packets waiting for resources (IRPs, buffers)
       // to become available. Search for packets with the specified ID.

       KNdisPacketList CancelList;

       m_TxQueue.Lock();                                                 // protect the loop
       PNDIS_PACKET p = m_TxQueue.HeadNoLock();
       while (p)  {
              PNDIS_PACKET thepacket = p;
              p = m_TxQueue.NextNoLock(p);
              if (NDIS_GET_PACKET_CANCEL_ID(thepacket)==CancelId) {
                     m_TxQueue.RemoveNoLock(thepacket);
                     CancelList.InsertTailNoLock(thepacket);
              }
       }
       m_TxQueue.Unlock();                                                 // protect the loop

       // CancelList contains the packets (if any) with given ID. Abort them.

       while (!CancelList.IsEmpty()) {      
              KNdisPacket p = CancelList.RemoveHead();
              SendComplete(p, NDIS_STATUS_REQUEST_ABORTED);
       }

};
#endif // NDIS51_MINIPORT


////////////////////////////////////////////////////////////////////
// VNICAdapter::TranslateAddr
//              将mac地址转化为对应的字符串
// Parameters:
//              char des[]              -存储mac地址转化后对应的字符串
//              UCHAR addr[]       -待转化的mac地址
// Return Mode:
//              NULL
// NOTE:
//              通过队mac地址的每一字节移位实现转化
//
void VNICAdapter::TranslateAddr(char des[], UCHAR addr[])
{      
       USHORT a[12];
       int i,j;

       for( i = j = 0; i < 6; i++) {
              a[j] = (addr >> 4) & 0xf;
              j++;
              a[j] = addr & 0xf;
              j++;
       }

       for( i = 0; i < 12; i++) {
              if(a >= 0 && a <= 9) {
                     des = 48 + a;
              } else {
                     des = 65 + a - 0xa;
              }
       }

}


////////////////////////////////////////////////////////////////////
// VNICAdapter::CreateMyDevice
//              创建一个可以从 user mode 访问的I/O设备对象
// Parameters:
//              none
// IRQL:
//              PASSIVE_LEVEL
// Return:
//              STATUS_SUCCESS 如果设备创建成功
// Note:
//              该方法调用的NdisMRegisterDevice()不适用于win98
NDIS_STATUS VNICAdapter::CreateMyDevice()
{
       NDIS_STATUS Status;

#if VNIC_WIN2K
       //WIN2K, XP系统下
    static PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
       //初始化MajorFuction
       NdisZeroMemory(MajorFunction, sizeof(MajorFunction));
      
       //指定irp处理例程
       MajorFunction[IRP_MJ_CREATE] =
    MajorFunction[IRP_MJ_CLOSE] =
    MajorFunction[IRP_MJ_CLEANUP] =
    MajorFunction[IRP_MJ_READ] =
    MajorFunction[IRP_MJ_WRITE] =
    MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoDispatch;

       //注册设备
       Status = NdisMRegisterDevice(
              *KNdisMiniDriver::DriverInstance(),
              KNDIS_STRING_CONST("\\Device\\VNICDevice"),
              KNDIS_STRING_CONST("\\DosDevices\\VNICDevice"),
              MajorFunction,
              &m_pDeviceObject,
              &m_DeviceHandle);
#else
       //win98环境
       static PDRIVER_OBJECT pDriverObject = KNdisMiniDriver::DriverInstance()->DriverObject();
      
       //指定irp处理例程
       pDriverObject->MajorFunction[IRP_MJ_CREATE] =
    pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
    pDriverObject->MajorFunction[IRP_MJ_CLEANUP] =
    pDriverObject->MajorFunction[IRP_MJ_READ] =
    pDriverObject->MajorFunction[IRP_MJ_WRITE] =
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoDispatch;
      
       //注册设备
       Status = IOCreatDevice(
              pDriverObject,
              0,
              KNDIS_STRING_CONST("\\Device\\VNICDevice"),
              FILE_DEVICE_NETWORK,
              0,
              FALSE,
              &m_pDeviceObject);

       if(STATUS_SUCCESS == Status)
              m_pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

#endif

       return Status;

}

////////////////////////////////////////////////////////////////////
// VNICAdapter::IoDispatch
//              处理对该驱动的IRP请求.
//              静态方法.
// Parameters:
//              DeviceObject              - 一个指向设备对象的指针
//              Irp                                   - 一个指向IRP请求的指针
// IRQL:
//              PASSIVE_LEVEL
// Return:
//              STATUS
NTSTATUS VNICAdapter::IoDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{      
      
       NTSTATUS Status = STATUS_SUCCESS;
       //将IRP指针转化为KIrp类
       KIrp       I(Irp);
      
       //显示调试信息
       TRACE("VNICAdapter::IoDispatch func 0x%02x \n", I.MajorFunction());
      
       switch (I.MajorFunction()) {
              case IRP_MJ_CREATE:                    
                     // TODO:获取应用程序文件指针
                     if(pFile == 0) {
                            //没有应用程序打开设备的情况
                            pFile = I.FileObject();
                     } else {
                            Status = STATUS_UNSUCCESSFUL;
                     }

                     I.Information() = 0;
                     break;

              case IRP_MJ_CLOSE:                    
                     // TODO: 删除应用程序文件指针
                     I.Information() = 0;

                     if(pFile == I.FileObject()) {
                            pFile = 0;
                     } else {
                            Status = STATUS_UNSUCCESSFUL;
                     }
                    
                     //清楚notify标记
                     notify = false;

                     //if(pEvent != NULL)
                     //{
                     //       delete pEvent;
                     //}
                     break;

              case IRP_MJ_CLEANUP:              
                     // TODO:
                     break;

              case IRP_MJ_READ:                    
                     // TODO
                     break;

              case IRP_MJ_WRITE:                    
                     // TODO
                     break;

              case IRP_MJ_DEVICE_CONTROL:
                     // TODO: 处理用户自定义的I/O控制命令
                    
                     try {

                            switch(I.IoctlCode()) {
                                  
                                   I.Information() = 0;

                                   case VNIC_IOCTL_SETEVENT:
                                          //TODO: 设置事件
                                          {
                                                 //获取应用程序设置的句柄
                                                 HANDLE hEvent = *(HANDLE*)I.IoctlBuffer();
                                                
                                                 if(pEvent)
                                                 {
                                                        delete pEvent;
                                                 }
                                                 //构造系统事件函数
                                                 pEvent = new (NonPagedPool)KEvent(hEvent, OBJECT_TYPE_ALL_ACCESS);
                                                 notify = true;
                                                 break;
                                          }
                                  
                                   case VNIC_IOCTL_ENABLE_NOTIY:
                                          //TODO: 将notify设为true
                                          notify = true;
                                          break;
                                  
                                   case VNIC_IOCTL_GETMAC:
                                          //TODO: 获取网卡的mac地址
                                          {
                                                 PUCHAR out = (PUCHAR)I.IoctlBuffer();
                                                 for(UINT i = 0; i <= 5; i++)
                                                 {
                                                        out = mac;
                                                 }
                                                 I.Information() = 6;
                                                 break;
                                          }

                                   case VNIC_IOCTL_READFRAME:
                                          //TODO: 读取帧
                                          {
                                                 PUCHAR out = (PUCHAR)I.IoctlBuffer();
                                                 //向服务程序输出发送的帧
                                                
                                                 for(UINT i = 0; i < packetSize; i++)
                                                 {
                                                        out = sndData;
                                                 }
                    
                                                 I.Information() = packetSize;
                                                
                                                 //
                                                 //if(pAdapter != NULL)
                                                 //{
                                                 //       pAdapter->SendComplete(pPacket);
                                                 //}

                                                 notify = true;
                                                 break;
                                          }

                                   case VNIC_IOCTL_WRITEFRAME:
                                          //TODO: 写帧
                                          {      
                                                 PUCHAR in = (PUCHAR)I.IoctlBuffer();
              
                                                 //指定堆栈为当前堆栈
                                                 EStackLocation s = CURRENT;
                                                 //获取输入缓冲区的长度
                                                 UINT size = I.IoctlInputBufferSize(s);

                                                 for(UINT i = 0; i< size; i++)
                                                 {
                                                        recData = in;
                                                 }

                                                 //产生一个收包信号
                                                 if(pAdapter != NULL)
                                                 {
                                                        //pAdapter是指向当前Adapter的指针
                                                        NdisMEthIndicateReceive(*pAdapter,
                                                                                                  *pAdapter,
                                                                                                  (PCHAR)recData,
                                                                                                  ETHE_HEADER_LEN,
                                                                                                  (PCHAR)recData + ETHE_HEADER_LEN,
                                                                                                  size - ETHE_HEADER_LEN,
                                                                                                  size - ETHE_HEADER_LEN);

                                                        NdisMEthIndicateReceiveComplete(*pAdapter);
                                                 }
                                                 else
                                                 {
                                                        TRACE("receive packet failed!");
                                                 }
                                          

                                          }

                                          break;

                                   default:

                                          Status = STATUS_INVALID_PARAMETER;
                                          break;
                            }
                     }
                     catch(...)
                     {
                            TRACE("Caught Default Exception");
                            
                            //释放Event指针
                            if(pEvent)
                            {
                                   delete pEvent;
                            }
                     }
                            
                     break;

              default:
                     Status = STATUS_UNSUCCESSFUL;

       };

       return I.Complete(Status);
}

// end of file

最新喜欢:

wingmanwingma...
anylin
驱动牛犊
驱动牛犊
  • 注册日期2005-06-07
  • 最后登录2008-11-04
  • 粉丝0
  • 关注0
  • 积分365分
  • 威望45点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-07-23 22:13
主要是在send 和 IoDispatch两个函数里

这几天问了好多问题都还没解决,还不如直接把代码贴出来

大家多帮忙看看有什么问题啊!

很奇怪啊 为什么“[ i ]” 之类的贴上来候都没了呢
大家看到怪怪的地方可能变量名后面还有个"[ i ]"
游客

返回顶部