mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
919 lines
29 KiB
919 lines
29 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
atkevent.c
|
|
|
|
Abstract:
|
|
|
|
Contains the event handlers that are called by the portable stack code. These will
|
|
in turn call the TDI event handler set on the address objects.
|
|
|
|
|
|
Author:
|
|
|
|
Nikhil Kamkolkar (NikhilK) 28-Jun-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "atalknt.h"
|
|
|
|
|
|
|
|
VOID
|
|
NTAdspConnectionEventHandler(
|
|
LONG ListenerRefNum,
|
|
ULONG EventContext,
|
|
PORTABLE_ADDRESS RemoteAddress,
|
|
LONG ConnectionRefNum
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PORTABLE_ERROR errorCode;
|
|
PADDRESS_FILE address;
|
|
PCONNECTION_FILE connection;
|
|
TA_APPLETALK_ADDRESS tdiAddress;
|
|
|
|
address = (PADDRESS_FILE)EventContext;
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspConnectionEventHandler - RefNum %d remsock %lx connrefnum %lx\n",
|
|
ListenerRefNum, RemoteAddress.socketNumber, ConnectionRefNum));
|
|
|
|
//
|
|
// BUGBUG: Have macros to change from tdi->portable and portable->tdi
|
|
// Build the tdi address
|
|
//
|
|
|
|
tdiAddress.TAAddressCount = 1;
|
|
tdiAddress.Address[0].AddressLength = sizeof(TDI_ADDRESS_APPLETALK);
|
|
tdiAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_APPLETALK;
|
|
tdiAddress.Address[0].Address[0].Network = RemoteAddress.networkNumber;
|
|
tdiAddress.Address[0].Address[0].Node = RemoteAddress.nodeNumber;
|
|
tdiAddress.Address[0].Address[0].Socket = RemoteAddress.socketNumber;
|
|
|
|
status = AtalkVerifyAddressObject(address);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
BOOLEAN handlerRegistered;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredConnectionHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
//
|
|
// BUGBUG: Follow resolution of the ConnectionContext issue.
|
|
//
|
|
|
|
CONNECTION_CONTEXT ConnectionContext;
|
|
|
|
status = (*address->ConnectionHandler)(
|
|
address->ConnectionHandlerContext,
|
|
sizeof(tdiAddress),
|
|
(PVOID)&tdiAddress,
|
|
0, // User data length
|
|
NULL, // User data
|
|
0, // Option length
|
|
NULL, // Options
|
|
&ConnectionContext);
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspConnectionEventHandler - returned indic status %lx\n",
|
|
status));
|
|
|
|
//
|
|
// This can return
|
|
// STATUS_EVENT_PENDING : ConnectionContext returned to indicate which
|
|
// connection will be used to accept the
|
|
// connection later on.
|
|
//
|
|
// STATUS_INSUFFICIENT_RESOURCES :
|
|
// Connection will never be accepted as not
|
|
// enough resources were present. We should
|
|
// deny the connection.
|
|
//
|
|
|
|
if (status == STATUS_EVENT_PENDING) {
|
|
|
|
PLIST_ENTRY p;
|
|
|
|
//
|
|
// Find the connection and set the refnum in there for a future
|
|
// accept
|
|
//
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspConnectionEventHandler - EventPend status %lx\n",
|
|
status));
|
|
|
|
//
|
|
// BUGBUG: Put in a routine, but this is going to change anyways,
|
|
// when the tdi spec changes.
|
|
//
|
|
|
|
ACQUIRE_SPIN_LOCK (&address->AddressLock);
|
|
p=address->ConnectionLinkage.Flink;
|
|
while (p != &address->ConnectionLinkage) {
|
|
|
|
connection = CONTAINING_RECORD (p, CONNECTION_FILE, Linkage);
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspConnectionEvent - Connection being checked: %lx\n",
|
|
connection));
|
|
|
|
if (connection->ConnectionContext == ConnectionContext) {
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspConnectionEvent - Connection to use: %lx\n",
|
|
connection));
|
|
|
|
//
|
|
// Set the state and the ref num
|
|
// BUGBUG: Should i grab the connection spinlock here?
|
|
//
|
|
|
|
ACQUIRE_SPIN_LOCK(&connection->ConnectionLock);
|
|
connection->Flags |= CONNECTION_FLAGS_LISTENCOMPLETEINDICATE;
|
|
connection->ConnectionRefNum = ConnectionRefNum;
|
|
RELEASE_SPIN_LOCK(&connection->ConnectionLock);
|
|
|
|
break;
|
|
}
|
|
|
|
p = p->Flink;
|
|
}
|
|
|
|
RELEASE_SPIN_LOCK (&address->AddressLock);
|
|
|
|
} else if (status == STATUS_INSUFFICIENT_RESOURCES) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveEventHandler - Resr/Deny status %lx\n",
|
|
status));
|
|
|
|
errorCode = AdspDenyConnectionRequest(
|
|
ListenerRefNum,
|
|
ConnectionRefNum);
|
|
|
|
#if DBG
|
|
status = ConvertToNTStatus(errorCode, SYNC_REQUEST);
|
|
ASSERT(NT_SUCCESS(status));
|
|
#endif
|
|
|
|
} else {
|
|
|
|
//
|
|
// BUGBUG:
|
|
// Should never happen?
|
|
//
|
|
|
|
KeBugCheck(0);
|
|
}
|
|
}
|
|
|
|
AtalkDereferenceAddress("IndConn", address,
|
|
AREF_VERIFY, SECONDARY_REFSET);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
NTAdspReceiveEventHandler(
|
|
LONG RefNum,
|
|
ULONG EventContext,
|
|
PCHAR LookaheadData,
|
|
LONG LookaheadDataSize,
|
|
BOOLEAN EndOfMessage,
|
|
LONG BytesAvailable
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PCONNECTION_FILE connection;
|
|
LONG bytesTaken = 0;
|
|
|
|
//
|
|
// BUGBUG: BytesAvailable counts the EOM as a byte - we use a flag to indicate
|
|
// and so decrement it here if EndOfMessage is true.
|
|
//
|
|
|
|
if (EndOfMessage) {
|
|
BytesAvailable--;
|
|
}
|
|
|
|
connection = (PCONNECTION_FILE)EventContext;
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveEventHandler - RefNum %d Lookahead %lx Len %d Total %d\n",
|
|
RefNum, LookaheadData, LookaheadDataSize, BytesAvailable));
|
|
|
|
//
|
|
// Verify the connection, this will verify if its closing also
|
|
//
|
|
|
|
status = AtalkVerifyConnectionObject(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Verify the associated address
|
|
//
|
|
|
|
status = AtalkConnVerifyAssocAddress(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
BOOLEAN handlerRegistered;
|
|
PADDRESS_FILE address = connection->AssociatedAddress;
|
|
PIRP receiveIrp = NULL;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredReceiveHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
status = (*address->ReceiveHandler)(
|
|
address->ReceiveHandlerContext,
|
|
connection->ConnectionContext,
|
|
TDI_RECEIVE_NORMAL, // ReceiveFlags
|
|
LookaheadDataSize,
|
|
BytesAvailable,
|
|
&bytesTaken,
|
|
LookaheadData,
|
|
&receiveIrp);
|
|
|
|
ASSERT((bytesTaken == 0) || (bytesTaken == BytesAvailable));
|
|
if (status == STATUS_SUCCESS) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveEventHandler - Indication status %lx\n",
|
|
status));
|
|
|
|
} else if (status == STATUS_DATA_NOT_ACCEPTED) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveEventHandler - Indication status %lx\n",
|
|
status));
|
|
|
|
} else if (status == STATUS_MORE_PROCESSING_REQUIRED) {
|
|
|
|
if (receiveIrp != NULL) {
|
|
|
|
//
|
|
// Post the receive as if it came from the io system
|
|
//
|
|
|
|
status= AtalkDispatchInternalDeviceControl(
|
|
(PDEVICE_OBJECT)AtalkDeviceObject[ATALK_DEVICE_ADSP],
|
|
receiveIrp);
|
|
|
|
ASSERT(status == STATUS_PENDING);
|
|
}
|
|
}
|
|
|
|
AtalkConnDereferenceAssocAddress(connection);
|
|
}
|
|
|
|
AtalkDereferenceConnection("IndRcv",connection,
|
|
CREF_VERIFY,SECONDARY_REFSET);
|
|
}
|
|
|
|
}
|
|
|
|
return(bytesTaken);
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
NTAdspReceiveAttnEventHandler(
|
|
LONG RefNum,
|
|
ULONG EventContext,
|
|
PCHAR LookaheadData,
|
|
LONG LookaheadDataSize,
|
|
LONG BytesAvailable
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PCONNECTION_FILE connection;
|
|
LONG bytesTaken = 0;
|
|
|
|
connection = (PCONNECTION_FILE)EventContext;
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveAttnEventHandler - Ref %d Look %lx Length %d Total %d\n",
|
|
RefNum, LookaheadData, LookaheadDataSize, BytesAvailable));
|
|
|
|
//
|
|
// Verify the connection, this will verify if its closing also
|
|
//
|
|
|
|
status = AtalkVerifyConnectionObject(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Verify the associated address
|
|
//
|
|
|
|
status = AtalkConnVerifyAssocAddress(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
BOOLEAN handlerRegistered;
|
|
PADDRESS_FILE address = connection->AssociatedAddress;
|
|
PIRP receiveExpeditedIrp = NULL;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredExpeditedDataHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
status = (*address->ExpeditedDataHandler)(
|
|
address->ExpeditedDataHandlerContext,
|
|
connection->ConnectionContext,
|
|
TDI_RECEIVE_EXPEDITED, // ReceiveFlags
|
|
LookaheadDataSize,
|
|
BytesAvailable,
|
|
&bytesTaken,
|
|
LookaheadData,
|
|
&receiveExpeditedIrp);
|
|
|
|
ASSERT((bytesTaken == 0) || (bytesTaken == BytesAvailable));
|
|
if (status == STATUS_SUCCESS) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveExpEventHandler - Indication status %lx\n",
|
|
status));
|
|
|
|
} else if (status == STATUS_DATA_NOT_ACCEPTED) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspReceiveExpEventHandler - Indication status %lx\n",
|
|
status));
|
|
|
|
} else if (status == STATUS_MORE_PROCESSING_REQUIRED) {
|
|
|
|
if (receiveExpeditedIrp != NULL) {
|
|
|
|
//
|
|
// Post the receive as if it came from the io system
|
|
//
|
|
|
|
status= AtalkDispatchInternalDeviceControl(
|
|
(PDEVICE_OBJECT)AtalkDeviceObject[ATALK_DEVICE_ADSP],
|
|
receiveExpeditedIrp);
|
|
|
|
ASSERT(status == STATUS_PENDING);
|
|
}
|
|
}
|
|
|
|
AtalkConnDereferenceAssocAddress(connection);
|
|
}
|
|
|
|
AtalkDereferenceConnection("IndExpRcv",connection,
|
|
CREF_VERIFY,SECONDARY_REFSET);
|
|
}
|
|
}
|
|
|
|
return(bytesTaken);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTAdspDisconnectEventHandler(
|
|
LONG RefNum,
|
|
ULONG EventContext,
|
|
PORTABLE_ERROR ErrorCode
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PCONNECTION_FILE connection;
|
|
|
|
connection = (PCONNECTION_FILE)EventContext;
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspDisconnectEventHandler - Ref %d Error %lx\n",
|
|
RefNum, ErrorCode));
|
|
|
|
//
|
|
// Verify the connection, this will verify if its closing also
|
|
//
|
|
|
|
status = AtalkVerifyConnectionObject(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Verify the associated address
|
|
//
|
|
|
|
status = AtalkConnVerifyAssocAddress(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
PADDRESS_FILE address = connection->AssociatedAddress;
|
|
BOOLEAN handlerRegistered;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredDisconnectHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
status = (*address->DisconnectHandler)(
|
|
address->DisconnectHandlerContext,
|
|
connection->ConnectionContext,
|
|
0, // Disc data length
|
|
NULL, // Disc data pointer
|
|
0, // Disc info length
|
|
NULL, // Disc info buffer
|
|
TDI_DISCONNECT_ABORT); // Disc flags
|
|
|
|
ASSERT(status == STATUS_SUCCESS);
|
|
}
|
|
|
|
AtalkConnDereferenceAssocAddress(connection);
|
|
}
|
|
|
|
AtalkDereferenceConnection("IndRcv",connection,CREF_VERIFY,SECONDARY_REFSET);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTPapConnectionEventHandler(
|
|
PORTABLE_ERROR ErrorCode,
|
|
ULONG EventContext,
|
|
LONG ConnectionRefNum,
|
|
SHORT WorkstationQuantum,
|
|
SHORT WaitTime
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PADDRESS_FILE address;
|
|
PORTABLE_ADDRESS remoteAddress;
|
|
PCONNECTION_FILE connection;
|
|
TA_APPLETALK_ADDRESS tdiAddress;
|
|
|
|
address = (PADDRESS_FILE)EventContext;
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEventHandler - RefNum %d - %lx\n",
|
|
ConnectionRefNum, ConnectionRefNum));
|
|
|
|
do {
|
|
|
|
status = ConvertToNTStatus(ErrorCode, SYNC_REQUEST);
|
|
if (!NT_SUCCESS(status)) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get the address of the remote on this connection
|
|
//
|
|
|
|
ErrorCode = PapGetRemoteAddressForJob(
|
|
ConnectionRefNum,
|
|
&remoteAddress);
|
|
|
|
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEventHandler - remote address %lx.%lx.%lx\n",
|
|
remoteAddress.networkNumber,
|
|
remoteAddress.nodeNumber,
|
|
remoteAddress.socketNumber));
|
|
|
|
status = ConvertToNTStatus(ErrorCode, SYNC_REQUEST);
|
|
if (!NT_SUCCESS(status)) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// BUGBUG: Have macros to change from tdi->portable and portable->tdi
|
|
// Build the tdi address
|
|
//
|
|
|
|
tdiAddress.TAAddressCount = 1;
|
|
tdiAddress.Address[0].AddressLength = sizeof(TDI_ADDRESS_APPLETALK);
|
|
tdiAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_APPLETALK;
|
|
tdiAddress.Address[0].Address[0].Network = remoteAddress.networkNumber;
|
|
tdiAddress.Address[0].Address[0].Node = remoteAddress.nodeNumber;
|
|
tdiAddress.Address[0].Address[0].Socket = remoteAddress.socketNumber;
|
|
|
|
status = AtalkVerifyAddressObject(address);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
BOOLEAN handlerRegistered;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredConnectionHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
//
|
|
// BUGBUG: Follow resolution of the ConnectionContext issue.
|
|
//
|
|
|
|
CONNECTION_CONTEXT ConnectionContext;
|
|
|
|
status = (*address->ConnectionHandler)(
|
|
address->ConnectionHandlerContext,
|
|
sizeof(tdiAddress),
|
|
(PVOID)&tdiAddress,
|
|
0, // User data length
|
|
NULL, // User data
|
|
0, // Option length
|
|
NULL, // Options
|
|
&ConnectionContext);
|
|
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEventHandler - returned indic status %lx\n",
|
|
status));
|
|
|
|
//
|
|
// This can return
|
|
// STATUS_EVENT_PENDING : ConnectionContext returned to indicate which
|
|
// connection will be used for this connect.
|
|
//
|
|
// STATUS_INSUFFICIENT_RESOURCES :
|
|
// Connection will never be accepted as not
|
|
// enough resources were present. We should
|
|
// disconnect the connection.
|
|
//
|
|
|
|
if (status == STATUS_EVENT_PENDING) {
|
|
|
|
PLIST_ENTRY p;
|
|
|
|
//
|
|
// Find the connection and set the refnum in there for a future
|
|
// accept
|
|
//
|
|
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEventHandler - EventPend status %lx\n",
|
|
status));
|
|
|
|
//
|
|
// BUGBUG: Put in a routine, but this is going to change anyways,
|
|
// when the tdi spec changes.
|
|
//
|
|
|
|
ACQUIRE_SPIN_LOCK (&address->AddressLock);
|
|
p=address->ConnectionLinkage.Flink;
|
|
while (p != &address->ConnectionLinkage) {
|
|
|
|
connection = CONTAINING_RECORD (p, CONNECTION_FILE, Linkage);
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEvent - Connection checked: %lx\n",
|
|
connection));
|
|
|
|
if (connection->ConnectionContext == ConnectionContext) {
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapConnectionEvent - Connection use: %lx\n",
|
|
connection));
|
|
|
|
//
|
|
// Set the state and the ref num
|
|
// BUGBUG: Should i grab the connection spinlock here?
|
|
//
|
|
|
|
ACQUIRE_SPIN_LOCK(&connection->ConnectionLock);
|
|
connection->Flags |=
|
|
CONNECTION_FLAGS_LISTENCOMPLETEINDICATE;
|
|
|
|
connection->ConnectionRefNum = ConnectionRefNum;
|
|
RELEASE_SPIN_LOCK(&connection->ConnectionLock);
|
|
|
|
break;
|
|
}
|
|
|
|
p = p->Flink;
|
|
}
|
|
|
|
RELEASE_SPIN_LOCK (&address->AddressLock);
|
|
|
|
} else if (status == STATUS_INSUFFICIENT_RESOURCES) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapReceiveEventHandler - Resr status %lx\n",
|
|
status));
|
|
|
|
ErrorCode = PapCloseJob(
|
|
ConnectionRefNum,
|
|
FALSE, // Closed by remote
|
|
FALSE); // Closed by timer
|
|
|
|
#if DBG
|
|
status = ConvertToNTStatus(ErrorCode, SYNC_REQUEST);
|
|
ASSERT(NT_SUCCESS(status));
|
|
#endif
|
|
|
|
} else {
|
|
|
|
//
|
|
// BUGBUG:
|
|
// Should never happen?
|
|
//
|
|
|
|
KeBugCheck(0);
|
|
}
|
|
}
|
|
|
|
AtalkDereferenceAddress("IndConn", address,
|
|
AREF_VERIFY, SECONDARY_REFSET);
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTPapDisconnectEventHandler(
|
|
PORTABLE_ERROR ErrorCode,
|
|
ULONG EventContext,
|
|
LONG ConnectionRefNum
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PCONNECTION_FILE connection;
|
|
|
|
connection = (PCONNECTION_FILE)EventContext;
|
|
|
|
DBGPRINT(ATALK_DEBUG_PAP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapDisconnectEventHandler - RefNum %d - %lx\n",
|
|
ConnectionRefNum, ConnectionRefNum));
|
|
|
|
status = ConvertToNTStatus(ErrorCode, SYNC_REQUEST);
|
|
if (status != STATUS_LOCAL_DISCONNECT) {
|
|
|
|
//
|
|
// Verify the connection, this will verify if its closing also
|
|
//
|
|
|
|
status = AtalkVerifyConnectionObject(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Verify the associated address
|
|
//
|
|
|
|
status = AtalkConnVerifyAssocAddress(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
BOOLEAN handlerRegistered;
|
|
PLIST_ENTRY p;
|
|
PADDRESS_FILE address = connection->AssociatedAddress;
|
|
CONNECTION_CONTEXT connectionContext = NULL;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredDisconnectHandler;
|
|
|
|
//
|
|
// BUGBUG: SetCookie instead?
|
|
//
|
|
|
|
p=address->ConnectionLinkage.Flink;
|
|
while (p != &address->ConnectionLinkage) {
|
|
|
|
connection = CONTAINING_RECORD (p, CONNECTION_FILE, Linkage);
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapDisconnectEvent - Connection checked: %lx\n",
|
|
connection));
|
|
|
|
if (connection->ConnectionRefNum == (ULONG)ConnectionRefNum) {
|
|
DBGPRINT(ATALK_DEBUG_ADDROBJ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTPapDisconnectEvent - Connection use: %lx\n",
|
|
connection));
|
|
|
|
connectionContext = connection->ConnectionContext;
|
|
break;
|
|
}
|
|
|
|
p = p->Flink;
|
|
}
|
|
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
status = (*address->DisconnectHandler)(
|
|
address->DisconnectHandlerContext,
|
|
connectionContext,
|
|
0, // Disc data length
|
|
NULL, // Disc data pointer
|
|
0, // Disc info length
|
|
NULL, // Disc info buffer
|
|
TDI_DISCONNECT_ABORT); // Disc flags
|
|
|
|
ASSERT(status == STATUS_SUCCESS);
|
|
}
|
|
|
|
AtalkConnDereferenceAssocAddress(connection);
|
|
}
|
|
|
|
AtalkDereferenceConnection("IndRcv",connection,CREF_VERIFY,SECONDARY_REFSET);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTGenericSendPossibleEventHandler(
|
|
LONG RefNum,
|
|
ULONG EventContext,
|
|
LONG WindowSize
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PCONNECTION_FILE connection;
|
|
|
|
connection = (PCONNECTION_FILE)EventContext;
|
|
|
|
DBGPRINT(ATALK_DEBUG_ADSP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTAdspSendOkayEventHandler - Ref %d Window %lx\n",
|
|
RefNum, WindowSize));
|
|
|
|
//
|
|
// Verify the connection, this will verify if its closing also
|
|
//
|
|
|
|
status = AtalkVerifyConnectionObject(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Verify the associated address
|
|
//
|
|
|
|
status = AtalkConnVerifyAssocAddress(connection);
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Call the event handler
|
|
//
|
|
|
|
PADDRESS_FILE address = connection->AssociatedAddress;
|
|
BOOLEAN handlerRegistered;
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredSendPossibleHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
status = (*address->SendPossibleHandler)(
|
|
address->SendPossibleHandlerContext,
|
|
connection->ConnectionContext,
|
|
WindowSize);
|
|
|
|
ASSERT(status == STATUS_SUCCESS);
|
|
}
|
|
|
|
AtalkConnDereferenceAssocAddress(connection);
|
|
}
|
|
|
|
AtalkDereferenceConnection("IndRcv",connection,CREF_VERIFY,SECONDARY_REFSET);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
NTDdpReceiveDatagramEventHandler(
|
|
PORTABLE_ERROR Error,
|
|
ULONG UserData,
|
|
INT Port,
|
|
PORTABLE_ADDRESS Source,
|
|
INT DestinationSocket,
|
|
INT ProtocolType,
|
|
PVOID Datagram,
|
|
INT DatagramLength,
|
|
PORTABLE_ADDRESS ActualDestination
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PADDRESS_FILE address;
|
|
LONG bytesTaken = DatagramLength;
|
|
|
|
|
|
DBGPRINT(ATALK_DEBUG_DDP, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTDdpReceiveDatagramEventHandler - Port %d Datagram %lx Length %d\n",
|
|
Port, Datagram, DatagramLength));
|
|
|
|
//
|
|
// Verify the address, this will verify if its closing also
|
|
//
|
|
|
|
address = (PADDRESS_FILE)UserData;
|
|
status = AtalkVerifyAddressObject(address);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
TA_APPLETALK_ADDRESS sourceAddress;
|
|
PIRP receiveDatagramIrp = NULL;
|
|
BOOLEAN handlerRegistered;
|
|
|
|
//
|
|
// Event handler will never be NULL, just check for TRUE/FALSE
|
|
//
|
|
|
|
ACQUIRE_SPIN_LOCK(&address->AddressLock);
|
|
handlerRegistered = address->RegisteredReceiveDatagramHandler;
|
|
RELEASE_SPIN_LOCK(&address->AddressLock);
|
|
|
|
if (handlerRegistered) {
|
|
|
|
//
|
|
// Set the source address
|
|
//
|
|
|
|
sourceAddress.TAAddressCount = 1;
|
|
sourceAddress.Address[0].AddressLength = sizeof(TDI_ADDRESS_APPLETALK);
|
|
sourceAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_APPLETALK;
|
|
sourceAddress.Address[0].Address[0].Network = Source.networkNumber;
|
|
sourceAddress.Address[0].Address[0].Node = Source.nodeNumber;
|
|
sourceAddress.Address[0].Address[0].Socket = Source.socketNumber;
|
|
|
|
status = (*address->ReceiveDatagramHandler)(
|
|
address->ReceiveDatagramHandlerContext,
|
|
sizeof(TA_APPLETALK_ADDRESS),
|
|
&sourceAddress,
|
|
0, // Options length
|
|
NULL, // Options
|
|
(ULONG)DatagramLength, // Bytes indicated
|
|
(ULONG)DatagramLength, // Bytes available
|
|
(ULONG *)&bytesTaken,
|
|
Datagram,
|
|
&receiveDatagramIrp);
|
|
|
|
ASSERT((bytesTaken == 0) || (bytesTaken == DatagramLength));
|
|
|
|
if (receiveDatagramIrp != NULL) {
|
|
|
|
//
|
|
// Post the receive as if it came from the io system
|
|
//
|
|
|
|
status= AtalkDispatchInternalDeviceControl(
|
|
(PDEVICE_OBJECT)AtalkDeviceObject[ATALK_DEVICE_DDP],
|
|
receiveDatagramIrp);
|
|
|
|
ASSERT(status == STATUS_PENDING);
|
|
}
|
|
}
|
|
|
|
AtalkDereferenceAddress("DGInd", address, AREF_VERIFY, SECONDARY_REFSET);
|
|
}
|
|
|
|
return(bytesTaken);
|
|
}
|
|
|