Home › Forums › Discussions › Support › TDI-фильтр и ClientEventChainedReceive(Expedited)
- This topic has 4 replies, 2 voices, and was last updated 15 years ago by Vadim Smirnov.
-
AuthorPosts
-
October 26, 2009 at 8:58 am #5308
Всем привет!
Имеется TDI-фильтр.
Подменяю ClientEventChainedReceive(Expedited) на свой обработчик при TDI_SET_EVENT_HANDLER (TDI_EVENT_CHAINED_RECEIVE(_EXPEDITED)). Вот как выглядит мой обработчик:
NTSTATUS NewClientEventChainedReceive(
IN PVOID TdiEventContext,
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags,
IN ULONG ReceiveLength,
IN ULONG StartingOffset,
IN PMDL Tsdu,
IN PVOID TsduDescriptor
)
{
KIRQL oldIrql;
NTSTATUS ntStatus;
PCLIENT_EVENT_CONTEXT_INFO pClientEventContextInfo;
CLIENTEVENTCHAINEDRECEIVE RealClientEventChainedReceive;
//__asm int 3
KeAcquireSpinLock(&g_ClientEventReceiveSpinLock, &oldIrql);
pClientEventContextInfo = (PCLIENT_EVENT_CONTEXT_INFO)TdiEventContext;
RealClientEventChainedReceive = (CLIENTEVENTCHAINEDRECEIVE)pClientEventContextInfo->EventRealHandler;
KeReleaseSpinLock(&g_ClientEventReceiveSpinLock, oldIrql);
ntStatus = RealClientEventChainedReceive(pClientEventContextInfo->EventRealContext,
ConnectionContext,
ReceiveFlags,
ReceiveLength,
StartingOffset,
Tsdu,
TsduDescriptor);
TCPMODULE_KDPRINT(("In NewClientEventChainedReceive: ReceiveLength=%lu ntStatus=0x%08Xn", ReceiveLength, ntStatus));
return ntStatus;
}
RealClientEventChainedReceive возвращает мне STATUS_PENDING.
Вопрос такой… Будет ли при этом Tsdu содержать данные? Т.е. смогу я их прочитать при STATUS_PENDING? Проверить сейчас прям не могу… Вот и решил спросить теоритически.October 26, 2009 at 9:48 am #6847В данном случае STATUS_PENDING означает, что TDI клиент обработает полученные из сети данные позже и затем вернет переданный ему буфер. Данные из Tsdu лучше забрать до вызова оригинального обработчика, так как если это сделать позже, то можно получить race condition.
October 26, 2009 at 9:56 am #6848Большое спасибо!
October 28, 2009 at 8:15 am #6849Вот… Поправил немного:
NTSTATUS NewClientEventChainedReceive(
IN PVOID TdiEventContext,
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags,
IN ULONG ReceiveLength,
IN ULONG StartingOffset,
IN PMDL Tsdu,
IN PVOID TsduDescriptor
)
{
BOOLEAN bReceiveFlag = FALSE;
KIRQL oldIrql;
NTSTATUS ntStatus;
ULONG ulTcpDataType = 0;
PUCHAR puchData = NULL;
PUCHAR puchMdlData = NULL;
PCLIENT_EVENT_CONTEXT_INFO pClientEventContextInfo;
CLIENTEVENTCHAINEDRECEIVE RealClientEventChainedReceive;
/*__asm int 3*/
KeAcquireSpinLock(&g_ClientEventReceiveSpinLock, &oldIrql);
pClientEventContextInfo = (PCLIENT_EVENT_CONTEXT_INFO)TdiEventContext;
RealClientEventChainedReceive = (CLIENTEVENTCHAINEDRECEIVE)pClientEventContextInfo->EventRealHandler;
KeReleaseSpinLock(&g_ClientEventReceiveSpinLock, oldIrql);
do {
if( Tsdu == NULL || ReceiveLength == 0 )
break;
puchMdlData = (PUCHAR)MmGetSystemAddressForMdlSafe(Tsdu, LowPagePriority);
if( puchMdlData == NULL )
break;
puchData = (PUCHAR)ExAllocatePool(NonPagedPool, ReceiveLength);
if( puchData == NULL )
break;
RtlZeroMemory(puchData, ReceiveLength);
RtlCopyMemory(puchData, puchMdlData, ReceiveLength);
...
...
bReceiveFlag = TRUE;
} while( FALSE );
ntStatus = RealClientEventChainedReceive(pClientEventContextInfo->EventRealContext,
ConnectionContext,
ReceiveFlags,
ReceiveLength,
StartingOffset,
Tsdu,
TsduDescriptor);
TCPMODULE_KDPRINT(("In NewClientEventChainedReceive [RealClientEventChainedReceive]: ReceiveLength=%lu ntStatus=0x%08Xn", ReceiveLength, ntStatus));
if( bReceiveFlag ) {
if( ntStatus == STATUS_SUCCESS || ntStatus == STATUS_PENDING ) {
// Сохраняем данные для дальнейшего использования
}
else {
// Если статус STATUS_DATA_NOT_ACCEPTED, то чистим ранее выделенные ресурсы
}
}
return ntStatus;
}
т.е. в puchData у меня будет копия принятых данных. В случае, если реальный нотификатор вернет STATUS_DATA_NOT_ACCEPTED, то клиенту данные не нужны и я очищаю память… Если же реальный нотификатор вернет STATUS_SUCCESS или STATUS_PENDING, то сохраняею данные.
Я правильно все понял?October 30, 2009 at 12:34 pm #6850В общем да…
-
AuthorPosts
- You must be logged in to reply to this topic.