📄 ksutil.c
字号:
// the _I_KS_DestroyTransportAddress function is finally called to destroy
// the transport address object.
//
VOID
_I_KS_DerefTransportAddress(
PKS_ADDRESS pKS_Address
)
{
LONG Result;
ASSERT( pKS_Address );
if( pKS_Address )
{
if( pKS_Address->m_ReferenceCount ) // ATTENTION!!! Is this test OK on SMP???
{
Result = InterlockedDecrement( &pKS_Address->m_ReferenceCount );
if( !Result )
{
//
// Destroy The Transport Address
//
_I_KS_DestroyTransportAddress( pKS_Address );
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
//// KS_CloseTransportAddress
//
// Purpose
// This routine closes the transport address object specified by pKS_ADDRESS.
//
// Parameters
// pKS_Address
// Pointer to the KS_ADDRESS structure that specifies the transport
// address object pointer and handle to be closed.
//
// Return Value
// Status
//
// Remarks
// This function calls _I_KS_DerefTransportAddress to decrement the reference
// count for the KS_ADDRESS structure. If the reference count is decremented
// to zero by this call, the transport address object specified by pKS_ADDRESS
// will actually be closed.
//
// Callers of KS_TransportAddress must be running at IRQL PASSIVE_LEVEL.
//
NTSTATUS
KS_CloseTransportAddress(
PKS_ADDRESS pKS_Address
)
{
KdPrint(("KS_CloseTransportAddress: Entry...\n"));
ASSERT( pKS_Address );
if( pKS_Address )
{
_I_KS_DerefTransportAddress( pKS_Address );
}
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// KS_SetEventHandlers
//
// Purpose
// Setup event handlers on the address object.
//
// Parameters
// pKS_Address
// Pointer to the KS_ADDRESS structure that specifies the transport
// address object pointer and handle that the event handlers will
// be set on.
// pEventContext
// Points to caller-determined context to be passed in to the ClientEventXxx
// routine as TdiEventContext when it is called by the transport.
// ConnectEventHandler
// ConnectEventHandler is an event handler the TDI driver calls in response
// to an incoming endpoint-to-endpoint connection offer from a remote node.
// DisconnectEventHandler
// DisconnectEventHandler is an event handler that the underlying TDI
// transport calls in response to an incoming disconnection notification
// from a remote node.
// ErrorReceiveHandler
// ErrorReceiveHandler is an event handler that the underlying TDI transport
// calls in response to an error, either in the transport itself or in a
// still lower network driver, that makes I/O on a particular local
// transport address unreliable or impossible.
// ReceiveEventHandler
// ReceiveEventHandler is an event handler that the underlying TDI transport
// calls in response to an incoming receive from a remote node with which
// the client has an established endpoint-to-endpoint connection. Usually,
// this is a normal TSDU unless the client has not registered a
// ReceiveExpeditedEventHandler handler.
// ReceiveDatagramEventHandler
// ReceiveDatagramEventHandler is an event handler that the underlying TDI
// transport calls in response to an incoming receive from a remote node
// that was directed to a local-node transport address that the client has
// opened.
// ReceiveExpeditedEventHandler
// ReceiveExpeditedEventHandler is an event handler that the underlying
// TDI transport calls in response to an incoming expedited receive from a
// remote node with which the client has an established endpoint-to-endpoint
// connection.
//
// Return Value
// Status
//
// Remarks
// Understand that TDI event handlers are setup on a transport address, not a
// connection endpoint.
//
// In general terms, "context" is simply some piece of information that you
// provide in one place and is given back to you when you need it most. For example,
// you pass a pEventContext value to KS_SetEventHandlers; this value is simply
// given back to you as TdiEventContext when your event handler is called.
//
// Often a context value is a pointer to a data structure that you have
// defined that contains the information that you will need when the event
// handler of callback is called. It doesn't have to be a pointer, however; it
// could be an index number into a table that you maintain, or anything else that
// will help you in your callback.
//
// See the NT DDK documentation topic "5.1 Opening a Transport Address"
// for more information.
//
// Callers of KS_SetEventHandlers must be running at IRQL PASSIVE_LEVEL.
//
NTSTATUS
KS_SetEventHandlers(
PKS_ADDRESS pKS_Address,
PVOID pEventContext,
PTDI_IND_CONNECT ConnectEventHandler,
PTDI_IND_DISCONNECT DisconnectEventHandler,
PTDI_IND_ERROR ErrorEventHandler,
PTDI_IND_RECEIVE ReceiveEventHandler,
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramEventHandler,
PTDI_IND_RECEIVE_EXPEDITED ReceiveExpeditedEventHandler
)
{
NTSTATUS Status;
PDEVICE_OBJECT pDeviceObject;
KdPrint(("KS_SetEventHandlers: Entry...\n") );
pDeviceObject = IoGetRelatedDeviceObject( pKS_Address->m_pFileObject );
//
// Set The Specified Event Handlers
//
do
{
//
// Set The Connect Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_CONNECT,
ConnectEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
//
// Set The Disconnect Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_DISCONNECT,
DisconnectEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
//
// Set The Error Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_ERROR,
ErrorEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
//
// Set The Receive Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_RECEIVE,
ReceiveEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
//
// Set The Receive Datagram Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_RECEIVE_DATAGRAM,
ReceiveDatagramEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
//
// Set The Receive Expedited Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_RECEIVE_EXPEDITED,
ReceiveExpeditedEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
#ifdef ZNEVER // Not Currently Supported By TDI
//
// Set The Send Possible Event Handler
//
TdiBuildSetEventHandler(
pKS_Address->m_pAtomicIrp,
pDeviceObject,
pKS_Address->m_pFileObject,
NULL,
NULL,
TDI_EVENT_SEND_POSSIBLE,
SendPossibleEventHandler,
pEventContext
);
//
// Submit The Request To The Transport
//
Status = KS_MakeSimpleTdiRequest(
pDeviceObject,
pKS_Address->m_pAtomicIrp
);
if (!NT_SUCCESS(Status))
{
break;
}
#endif // ZNEVER
//
// All Event Handlers Have Been Set
//
}
while(0);
return( Status );
}
/////////////////////////////////////////////////////////////////////////////
//// _I_KS_AddressRequestComplete (INTERNAL/PRIVATE)
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
static NTSTATUS
_I_KS_AddressRequestComplete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp,
IN PVOID Context
)
{
PKS_ADDRESS_REQUEST_CONTEXT pKS_RequestContext;
PKEVENT pEvent;
pKS_RequestContext = (PKS_ADDRESS_REQUEST_CONTEXT )Context;
if( pKS_RequestContext != NULL )
{
//
// Fill IoStatusBlock With Final Status And Information
//
(pKS_RequestContext->m_pIoStatusBlock)->Status = pIrp->IoStatus.Status;
(pKS_RequestContext->m_pIoStatusBlock)->Information = pIrp->IoStatus.Information;
//
// Set The Completion Event, If Specified
//
if( pKS_RequestContext->m_CompletionEvent )
{
KeSetEvent( pKS_RequestContext->m_CompletionEvent, 0, FALSE);
}
//
// Call The Completion Routine, If Specified
//
if( pKS_RequestContext->m_CompletionRoutine )
{
(pKS_RequestContext->m_CompletionRoutine)(
pKS_RequestContext->m_CompletionContext,
pKS_RequestContext->m_pIoStatusBlock,
pKS_RequestContext->m_Reserved
);
}
//
// Dereference The Address Object
//
_I_KS_DerefTransportAddress( pKS_RequestContext->m_pKS_Address );
//
// Free Memory Allocated For Private Completion Context
//
NdisFreeMemory(
pKS_RequestContext,
sizeof( KS_ADDRESS_REQUEST_CONTEXT ),
0
);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -