- Implement IOCTL_AFD_GET_CONNECT_DATA, IOCTL_AFD_SET_CONNECT_DATA, IOCTL_AFD_SET_CO...
authorCameron Gutman <aicommander@gmail.com>
Wed, 2 Dec 2009 23:57:57 +0000 (23:57 +0000)
committerCameron Gutman <aicommander@gmail.com>
Wed, 2 Dec 2009 23:57:57 +0000 (23:57 +0000)
 - Check that the socket allows connections in AfdDisconnect and AfdStreamSocketConnect
 - Allocate the receive window in connectionless sockets when the socket is bound instead of at FCB creation
 - Remove a horrible hack in UnlockRequest
 - Remove an incorrect call to MmUnmapLockedPages (the pages aren't mapped!)
 - Replace the recursive mutex with a KMUTEX for now (eventually I want to move to a fast mutex)
 - Fix a leak in LockRequest in failure case

svn path=/branches/aicom-network-branch/; revision=44370

drivers/network/afd/afd/bind.c
drivers/network/afd/afd/connect.c
drivers/network/afd/afd/listen.c
drivers/network/afd/afd/lock.c
drivers/network/afd/afd/main.c
drivers/network/afd/afd/tdi.c
drivers/network/afd/include/afd.h
drivers/network/afd/include/tdi_proto.h

index 1b5072f..d7504b8 100644 (file)
@@ -57,24 +57,22 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
 
     if( FCB->LocalAddress )
     FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
 
     if( FCB->LocalAddress )
-       Status = WarmSocketForBind( FCB );
-    else Status = STATUS_NO_MEMORY;
-
-    if( NT_SUCCESS(Status) )
-       FCB->State = SOCKET_STATE_BOUND;
-    else return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
-
-    AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
-
-    if( FCB->Flags & SGID_CONNECTIONLESS ) {
-       /* This will be the from address for subsequent recvfrom calls */
        TdiBuildConnectionInfo( &FCB->AddressFrom,
                                FCB->LocalAddress );
 
        TdiBuildConnectionInfo( &FCB->AddressFrom,
                                FCB->LocalAddress );
 
-       if( !FCB->AddressFrom ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
+    if( FCB->AddressFrom )
+       Status = WarmSocketForBind( FCB );
+    else return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
 
 
+    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
        AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
 
        AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
 
+        FCB->Recv.Window = ExAllocatePool(PagedPool, FCB->Recv.Size);
+        if (!FCB->Recv.Window)
+            return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
        Status = TdiReceiveDatagram
            ( &FCB->ReceiveIrp.InFlightRequest,
              FCB->AddressFile.Object,
        Status = TdiReceiveDatagram
            ( &FCB->ReceiveIrp.InFlightRequest,
              FCB->AddressFile.Object,
@@ -90,6 +88,9 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
        if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
     }
 
        if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
     }
 
+    if (NT_SUCCESS(Status))
+        FCB->State = SOCKET_STATE_BOUND;
+
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
index 9b0beeb..1da57e2 100644 (file)
 #include "tdiconn.h"
 #include "debug.h"
 
 #include "tdiconn.h"
 #include "debug.h"
 
+NTSTATUS NTAPI
+AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->ConnectOptionsSize == 0)
+        return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+    ASSERT(FCB->ConnectOptions);
+
+    if (FCB->FilledConnectOptions < BufferSize) BufferSize = FCB->FilledConnectOptions;
+
+    RtlCopyMemory(Irp->UserBuffer,
+                  FCB->ConnectOptions,
+                  BufferSize);
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+}
+
+NTSTATUS
+NTAPI
+AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                  PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PVOID ConnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->ConnectOptions)
+    {
+        ExFreePool(FCB->ConnectOptions);
+        FCB->ConnectOptions = NULL;
+        FCB->ConnectOptionsSize = 0;
+        FCB->FilledConnectOptions = 0;
+    }
+
+    FCB->ConnectOptions = ExAllocatePool(PagedPool, ConnectOptionsSize);
+    if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    RtlCopyMemory(FCB->ConnectOptions,
+                  ConnectOptions,
+                  ConnectOptionsSize);
+
+    FCB->ConnectOptionsSize = ConnectOptionsSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS
+NTAPI
+AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                      PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PUINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (BufferSize < sizeof(UINT))
+        return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+    if (FCB->ConnectOptions)
+    {
+        ExFreePool(FCB->ConnectOptions);
+        FCB->ConnectOptionsSize = 0;
+        FCB->FilledConnectOptions = 0;
+    }
+
+    FCB->ConnectOptions = ExAllocatePool(PagedPool, *ConnectOptionsSize);
+    if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    FCB->ConnectOptionsSize = *ConnectOptionsSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS NTAPI
+AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->ConnectDataSize == 0)
+        return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+    ASSERT(FCB->ConnectData);
+
+    if (FCB->FilledConnectData < BufferSize) BufferSize = FCB->FilledConnectData;
+
+    RtlCopyMemory(Irp->UserBuffer,
+                  FCB->ConnectData,
+                  BufferSize);
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+}
+
+NTSTATUS
+NTAPI
+AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                  PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PVOID ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->ConnectData)
+    {
+        ExFreePool(FCB->ConnectData);
+        FCB->ConnectData = NULL;
+        FCB->ConnectDataSize = 0;
+        FCB->FilledConnectData = 0;
+    }
+
+    FCB->ConnectData = ExAllocatePool(PagedPool, ConnectDataSize);
+    if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    RtlCopyMemory(FCB->ConnectData,
+                  ConnectData,
+                  ConnectDataSize);
+
+    FCB->ConnectDataSize = ConnectDataSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS
+NTAPI
+AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                      PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PUINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (BufferSize < sizeof(UINT))
+        return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+    if (FCB->ConnectData)
+    {
+        ExFreePool(FCB->ConnectData);
+        FCB->ConnectDataSize = 0;
+        FCB->FilledConnectData = 0;
+    }
+
+    FCB->ConnectData = ExAllocatePool(PagedPool, *ConnectDataSize);
+    if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    FCB->ConnectDataSize = *ConnectDataSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+
 NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
     NTSTATUS Status;
 
 NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
     NTSTATUS Status;
 
@@ -35,6 +208,9 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
 NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) {
     NTSTATUS Status;
 
 NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) {
     NTSTATUS Status;
 
+    ASSERT(!FCB->Recv.Window);
+    ASSERT(!FCB->Send.Window);
+
     /* Allocate the receive area and start receiving */
     FCB->Recv.Window =
        ExAllocatePool( PagedPool, FCB->Recv.Size );
     /* Allocate the receive area and start receiving */
     FCB->Recv.Window =
        ExAllocatePool( PagedPool, FCB->Recv.Size );
@@ -133,6 +309,22 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
            return Status;
        }
 
            return Status;
        }
 
+        FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength, FCB->ConnectDataSize);
+        if (FCB->FilledConnectData)
+        {
+            RtlCopyMemory(FCB->ConnectData,
+                          FCB->ConnectInfo->UserData,
+                          FCB->FilledConnectData);
+        }
+
+        FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength, FCB->ConnectOptionsSize);
+        if (FCB->FilledConnectOptions)
+        {
+            RtlCopyMemory(FCB->ConnectOptions,
+                          FCB->ConnectInfo->Options,
+                          FCB->FilledConnectOptions);
+        }
+
        if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
            NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP,
        if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
            NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP,
@@ -162,10 +354,10 @@ NTSTATUS NTAPI
 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                       PIO_STACK_LOCATION IrpSp) {
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                       PIO_STACK_LOCATION IrpSp) {
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
-    PTDI_CONNECTION_INFORMATION TargetAddress;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_CONNECT_INFO ConnectReq;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_CONNECT_INFO ConnectReq;
+    PTDI_CONNECTION_INFORMATION TargetAddress;
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
@@ -180,6 +372,9 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
          IrpSp->Parameters.DeviceIoControl.InputBufferLength );
 #endif
 
          IrpSp->Parameters.DeviceIoControl.InputBufferLength );
 #endif
 
+   if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
+       return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
+
     switch( FCB->State ) {
     case SOCKET_STATE_CONNECTED:
        Status = STATUS_SUCCESS;
     switch( FCB->State ) {
     case SOCKET_STATE_CONNECTED:
        Status = STATUS_SUCCESS;
@@ -216,37 +411,42 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
            break;
        }
 
            break;
        }
 
-       if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
-       {
-           Status = STATUS_SUCCESS;
-           break;
-       }
-
        Status = WarmSocketForConnection( FCB );
 
        if( !NT_SUCCESS(Status) )
            break;
 
        Status = WarmSocketForConnection( FCB );
 
        if( !NT_SUCCESS(Status) )
            break;
 
-       FCB->State = SOCKET_STATE_CONNECTING;
-
        TdiBuildConnectionInfo
        TdiBuildConnectionInfo
-           ( &TargetAddress,
+           ( &FCB->ConnectInfo,
              &ConnectReq->RemoteAddress );
 
              &ConnectReq->RemoteAddress );
 
+        if( FCB->ConnectInfo )
+            TdiBuildConnectionInfo(&TargetAddress,
+                                   &ConnectReq->RemoteAddress);
+
+
        if( TargetAddress ) {
        if( TargetAddress ) {
+            TargetAddress->UserData = FCB->ConnectData;
+            TargetAddress->UserDataLength = FCB->ConnectDataSize;
+            TargetAddress->Options = FCB->ConnectOptions;
+            TargetAddress->OptionsLength = FCB->ConnectOptionsSize;
+
            Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
                                 FCB->Connection.Object,
                                 TargetAddress,
            Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
                                 FCB->Connection.Object,
                                 TargetAddress,
+                                FCB->ConnectInfo,
                                 &FCB->ConnectIrp.Iosb,
                                 StreamSocketConnectComplete,
                                 FCB );
 
                                 &FCB->ConnectIrp.Iosb,
                                 StreamSocketConnectComplete,
                                 FCB );
 
-           ExFreePool( TargetAddress );
+            ExFreePool(TargetAddress);
 
            AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
 
 
            AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
 
-           if( Status == STATUS_PENDING )
+           if( Status == STATUS_PENDING ) {
+                FCB->State = SOCKET_STATE_CONNECTING;
                return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
                return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
+            }
        } else Status = STATUS_NO_MEMORY;
        break;
 
        } else Status = STATUS_NO_MEMORY;
        break;
 
index 65c49eb..d16550e 100644 (file)
@@ -36,6 +36,9 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
     else
        Status = MakeSocketIntoConnection( FCB );
 
     else
        Status = MakeSocketIntoConnection( FCB );
 
+    if (NT_SUCCESS(Status))
+        Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, FCB->RemoteAddress);
+
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
index bdfc20e..7605f8d 100644 (file)
@@ -40,6 +40,7 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
            MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
 
        if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
            MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
 
        if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
+            MmUnlockPages( Irp->MdlAddress );
            IoFreeMdl( Irp->MdlAddress );
            Irp->MdlAddress = NULL;
            return NULL;
            IoFreeMdl( Irp->MdlAddress );
            Irp->MdlAddress = NULL;
            return NULL;
@@ -49,14 +50,10 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
     } else return NULL;
 }
 
     } else return NULL;
 }
 
-VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
-    PVOID Buffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
-    if( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer == Buffer || Buffer == NULL ) {
-       MmUnmapLockedPages( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, Irp->MdlAddress );
-        MmUnlockPages( Irp->MdlAddress );
-        IoFreeMdl( Irp->MdlAddress );
-    }
-
+VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
+{
+    MmUnlockPages( Irp->MdlAddress );
+    IoFreeMdl( Irp->MdlAddress );
     Irp->MdlAddress = NULL;
 }
 
     Irp->MdlAddress = NULL;
 }
 
@@ -213,78 +210,18 @@ VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
     HandleArray = NULL;
 }
 
     HandleArray = NULL;
 }
 
-/* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
-UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
-    NTSTATUS Status = STATUS_SUCCESS;
-    PVOID CurrentThread = KeGetCurrentThread();
-
-    ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
-    AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
-
-    /* Wait for the previous user to unlock the FCB state.  There might be
-     * multiple waiters waiting to change the state.  We need to check each
-     * time we get the event whether somebody still has the state locked */
-
+BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ) {
     if( !FCB ) return FALSE;
 
     if( !FCB ) return FALSE;
 
-    if( CurrentThread == FCB->CurrentThread ) {
-       FCB->LockCount++;
-       AFD_DbgPrint(MID_TRACE,
-                    ("Same thread, lock count %d\n", FCB->LockCount));
-       return TRUE;
-    } else {
-       AFD_DbgPrint(MID_TRACE,
-                    ("Thread %x opposes lock thread %x\n",
-                     CurrentThread, FCB->CurrentThread));
-    }
-
-
-    ExAcquireFastMutex( &FCB->Mutex );
-
-    while( FCB->Locked ) {
-       AFD_DbgPrint
-           (MID_TRACE,("FCB %x is locked, waiting for notification\n",
-                       FCB));
-       ExReleaseFastMutex( &FCB->Mutex );
-       Status = KeWaitForSingleObject( &FCB->StateLockedEvent,
-                                       UserRequest,
-                                       KernelMode,
-                                       FALSE,
-                                       NULL );
-       ExAcquireFastMutex( &FCB->Mutex );
-    }
-    FCB->Locked = TRUE;
-    FCB->CurrentThread = CurrentThread;
-    FCB->LockCount++;
-    ExReleaseFastMutex( &FCB->Mutex );
-
-    AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
-
-    return TRUE;
+    return !KeWaitForMutexObject(&FCB->Mutex,
+                                 Executive,
+                                 KernelMode,
+                                 FALSE,
+                                 NULL);
 }
 
 VOID SocketStateUnlock( PAFD_FCB FCB ) {
 }
 
 VOID SocketStateUnlock( PAFD_FCB FCB ) {
-#if DBG
-    PVOID CurrentThread = KeGetCurrentThread();
-#endif
-    ASSERT(FCB->LockCount > 0);
-    ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
-    ExAcquireFastMutex( &FCB->Mutex );
-    FCB->LockCount--;
-
-    if( !FCB->LockCount ) {
-       FCB->CurrentThread = NULL;
-       FCB->Locked = FALSE;
-
-       AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
-       KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
-    } else {
-       AFD_DbgPrint(MAX_TRACE,("New lock count: %d (Thr: %x)\n",
-                               FCB->LockCount, CurrentThread));
-    }
-    ExReleaseFastMutex( &FCB->Mutex );
+    KeReleaseMutex(&FCB->Mutex, FALSE);
 }
 
 NTSTATUS NTAPI UnlockAndMaybeComplete
 }
 
 NTSTATUS NTAPI UnlockAndMaybeComplete
index fb4fc91..10ebe9a 100644 (file)
@@ -41,6 +41,178 @@ void OskitDumpBuffer( PCHAR Data, UINT Len ) {
 NTSTATUS NTAPI
 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
 
 NTSTATUS NTAPI
 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
 
+NTSTATUS NTAPI
+AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->DisconnectOptionsSize == 0)
+        return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+    ASSERT(FCB->DisconnectOptions);
+
+    if (FCB->FilledDisconnectOptions < BufferSize) BufferSize = FCB->FilledDisconnectOptions;
+
+    RtlCopyMemory(Irp->UserBuffer,
+                  FCB->DisconnectOptions,
+                  BufferSize);
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+}
+
+NTSTATUS
+NTAPI
+AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                  PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->DisconnectOptions)
+    {
+        ExFreePool(FCB->DisconnectOptions);
+        FCB->DisconnectOptions = NULL;
+        FCB->DisconnectOptionsSize = 0;
+        FCB->FilledDisconnectOptions = 0;
+    }
+
+    FCB->DisconnectOptions = ExAllocatePool(PagedPool, DisconnectOptionsSize);
+    if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    RtlCopyMemory(FCB->DisconnectOptions,
+                  DisconnectOptions,
+                  DisconnectOptionsSize);
+
+    FCB->DisconnectOptionsSize = DisconnectOptionsSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS
+NTAPI
+AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                      PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (BufferSize < sizeof(UINT))
+        return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+    if (FCB->DisconnectOptions)
+    {
+        ExFreePool(FCB->DisconnectOptions);
+        FCB->DisconnectOptionsSize = 0;
+        FCB->FilledDisconnectOptions = 0;
+    }
+
+    FCB->DisconnectOptions = ExAllocatePool(PagedPool, *DisconnectOptionsSize);
+    if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    FCB->DisconnectOptionsSize = *DisconnectOptionsSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS NTAPI
+AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->DisconnectDataSize == 0)
+        return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+    ASSERT(FCB->DisconnectData);
+
+    if (FCB->FilledDisconnectData < BufferSize) BufferSize = FCB->FilledDisconnectData;
+
+    RtlCopyMemory(Irp->UserBuffer,
+                  FCB->DisconnectData,
+                  BufferSize);
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+}
+
+NTSTATUS
+NTAPI
+AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                  PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (FCB->DisconnectData)
+    {
+        ExFreePool(FCB->DisconnectData);
+        FCB->DisconnectData = NULL;
+        FCB->DisconnectDataSize = 0;
+        FCB->FilledDisconnectData = 0;
+    }
+
+    FCB->DisconnectData = ExAllocatePool(PagedPool, DisconnectDataSize);
+    if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    RtlCopyMemory(FCB->DisconnectData,
+                  DisconnectData,
+                  DisconnectDataSize);
+
+    FCB->DisconnectDataSize = DisconnectDataSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
+NTSTATUS
+NTAPI
+AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                      PIO_STACK_LOCATION IrpSp)
+{
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+    if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+    if (BufferSize < sizeof(UINT))
+        return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+    if (FCB->DisconnectData)
+    {
+        ExFreePool(FCB->DisconnectData);
+        FCB->DisconnectDataSize = 0;
+        FCB->FilledDisconnectData = 0;
+    }
+
+    FCB->DisconnectData = ExAllocatePool(PagedPool, *DisconnectDataSize);
+    if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+    FCB->DisconnectDataSize = *DisconnectDataSize;
+
+    return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+}
+
 static NTSTATUS NTAPI
 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                PIO_STACK_LOCATION IrpSp) {
 static NTSTATUS NTAPI
 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                PIO_STACK_LOCATION IrpSp) {
@@ -101,9 +273,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
     FCB->Connection.Handle = INVALID_HANDLE_VALUE;
 
     FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
     FCB->Connection.Handle = INVALID_HANDLE_VALUE;
 
-    KeInitializeSpinLock( &FCB->SpinLock );
-    ExInitializeFastMutex( &FCB->Mutex );
-    KeInitializeEvent( &FCB->StateLockedEvent, NotificationEvent, FALSE );
+    KeInitializeMutex( &FCB->Mutex, 0 );
 
     for( i = 0; i < MAX_FUNCTIONS; i++ ) {
        InitializeListHead( &FCB->PendingIrpList[i] );
 
     for( i = 0; i < MAX_FUNCTIONS; i++ ) {
        InitializeListHead( &FCB->PendingIrpList[i] );
@@ -141,22 +311,15 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     FileObject->FsContext = FCB;
 
     /* It seems that UDP sockets are writable from inception */
     FileObject->FsContext = FCB;
 
     /* It seems that UDP sockets are writable from inception */
-    if( FCB->Flags & SGID_CONNECTIONLESS ) {
+    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
         AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
         AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
-       /* Allocate our backup buffer */
-       FCB->Recv.Window = ExAllocatePool( PagedPool, FCB->Recv.Size );
-       if( !FCB->Recv.Window ) Status = STATUS_NO_MEMORY;
-        if( NT_SUCCESS(Status) )
+        FCB->Send.Window = ExAllocatePool( PagedPool, FCB->Send.Size );
+       if (FCB->Send.Window)
         {
         {
-            FCB->Send.Window = ExAllocatePool( PagedPool, FCB->Send.Size );
-           if( !FCB->Send.Window ) {
-                if( FCB->Recv.Window ) ExFreePool( FCB->Recv.Window );
-                Status = STATUS_NO_MEMORY;
-            }
-            }
-       /* A datagram socket is always sendable */
-       FCB->PollState |= AFD_EVENT_SEND;
-        PollReeval( FCB->DeviceExt, FCB->FileObject );
+           /* A datagram socket is always sendable */
+           FCB->PollState |= AFD_EVENT_SEND;
+            PollReeval( FCB->DeviceExt, FCB->FileObject );
+        } else Status = STATUS_NO_MEMORY;
     }
 
     if( !NT_SUCCESS(Status) ) {
     }
 
     if( !NT_SUCCESS(Status) ) {
@@ -254,6 +417,21 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     if( FCB->AddressFrom )
        ExFreePool( FCB->AddressFrom );
 
     if( FCB->AddressFrom )
        ExFreePool( FCB->AddressFrom );
 
+    if( FCB->ConnectInfo )
+        ExFreePool( FCB->ConnectInfo );
+
+    if( FCB->ConnectData )
+        ExFreePool( FCB->ConnectData );
+
+    if( FCB->DisconnectData )
+        ExFreePool( FCB->DisconnectData );
+
+    if( FCB->ConnectOptions )
+        ExFreePool( FCB->ConnectOptions );
+
+    if( FCB->DisconnectOptions )
+        ExFreePool( FCB->DisconnectOptions );
+
     if( FCB->LocalAddress )
        ExFreePool( FCB->LocalAddress );
 
     if( FCB->LocalAddress )
        ExFreePool( FCB->LocalAddress );
 
@@ -303,8 +481,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_DISCONNECT_INFO DisReq;
     IO_STATUS_BLOCK Iosb;
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_DISCONNECT_INFO DisReq;
     IO_STATUS_BLOCK Iosb;
-    PTDI_CONNECTION_INFORMATION ConnInfo;
-    NTSTATUS Status;
+    PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
+    NTSTATUS Status = STATUS_SUCCESS;
     USHORT Flags = 0;
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
     USHORT Flags = 0;
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
@@ -313,39 +491,65 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
                                       Irp, 0 );
 
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
                                       Irp, 0 );
 
-    if (NULL == FCB->RemoteAddress)
-      {
-        ConnInfo = NULL;
-      }
-    else
-      {
-       Status = TdiBuildNullConnectionInfo
-           ( &ConnInfo, FCB->RemoteAddress->Address[0].AddressType );
+    if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+    {
+        if( !FCB->ConnectInfo )
+            return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
+                                           Irp, 0 );
+
+        ASSERT(FCB->RemoteAddress);
+
+        Status = TdiBuildNullConnectionInfo
+              ( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
 
 
-       if( !NT_SUCCESS(Status) || !ConnInfo )
+        if( !NT_SUCCESS(Status) )
            return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
            return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
-                                          Irp, 0 );
-      }
-
-    if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
-       Flags |= TDI_DISCONNECT_RELEASE;
-    if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
-       DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
-       Flags |= TDI_DISCONNECT_ABORT;
-
-    Status = TdiDisconnect( FCB->Connection.Object,
-                           &DisReq->Timeout,
-                           Flags,
-                           &Iosb,
-                           NULL,
-                           NULL,
-                           FCB->AddressFrom,
-                           ConnInfo);
-
-    if (ConnInfo) ExFreePool( ConnInfo );
-
-    FCB->PollState |= AFD_EVENT_DISCONNECT;
-    PollReeval( FCB->DeviceExt, FCB->FileObject );
+                                          Irp, 0 );
+
+        if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
+           Flags |= TDI_DISCONNECT_RELEASE;
+        if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
+           DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
+           Flags |= TDI_DISCONNECT_ABORT;
+
+        FCB->ConnectInfo->UserData = FCB->DisconnectData;
+        FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
+        FCB->ConnectInfo->Options = FCB->DisconnectOptions;
+        FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
+
+        Status = TdiDisconnect( FCB->Connection.Object,
+                               &DisReq->Timeout,
+                               Flags,
+                               &Iosb,
+                               NULL,
+                               NULL,
+                               FCB->ConnectInfo,
+                               ConnectionReturnInfo);
+
+        if (NT_SUCCESS(Status)) {
+            FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
+            if (FCB->FilledDisconnectData)
+            {
+                RtlCopyMemory(FCB->DisconnectData,
+                              ConnectionReturnInfo->UserData,
+                              FCB->FilledDisconnectData);
+            }
+
+            FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength);
+            if (FCB->FilledDisconnectOptions)
+            {
+                RtlCopyMemory(FCB->DisconnectOptions,
+                              ConnectionReturnInfo->Options,
+                              FCB->FilledDisconnectOptions);
+            }
+        }
+
+        ExFreePool( ConnectionReturnInfo );
+
+        FCB->PollState |= AFD_EVENT_DISCONNECT;
+        PollReeval( FCB->DeviceExt, FCB->FileObject );
+    } else
+        Status = STATUS_INVALID_PARAMETER;
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
@@ -455,56 +659,44 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
         case IOCTL_AFD_GET_PEER_NAME:
             return AfdGetPeerName( DeviceObject, Irp, IrpSp );
 
         case IOCTL_AFD_GET_PEER_NAME:
             return AfdGetPeerName( DeviceObject, Irp, IrpSp );
 
-       case IOCTL_AFD_GET_TDI_HANDLES:
-           DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_CONNECT_DATA:
+           return AfdGetConnectData(DeviceObject, Irp, IrpSp);
 
        case IOCTL_AFD_SET_CONNECT_DATA:
 
        case IOCTL_AFD_SET_CONNECT_DATA:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
-
-       case IOCTL_AFD_SET_CONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+           return AfdSetConnectData(DeviceObject, Irp, IrpSp);
 
        case IOCTL_AFD_SET_DISCONNECT_DATA:
 
        case IOCTL_AFD_SET_DISCONNECT_DATA:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+           return AfdSetDisconnectData(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_DISCONNECT_DATA:
+           return AfdGetDisconnectData(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_GET_CONNECT_DATA:
-           DbgPrint("IOCTL_AFD_GET_CONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
+           return AfdSetConnectDataSize(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_GET_CONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_GET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
+           return AfdSetDisconnectDataSize(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_GET_DISCONNECT_DATA:
-           DbgPrint("IOCTL_AFD_GET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_OPTIONS:
+           return AfdSetConnectOptions(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_GET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
+           return AfdSetDisconnectOptions(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_CONNECT_OPTIONS:
+           return AfdGetConnectOptions(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
+           return AfdGetDisconnectOptions(DeviceObject, Irp, IrpSp);
 
 
-       case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
+           return AfdSetConnectOptionsSize(DeviceObject, Irp, IrpSp);
 
        case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
 
        case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
+           return AfdSetDisconnectOptionsSize(DeviceObject, Irp, IrpSp);
+
+       case IOCTL_AFD_GET_TDI_HANDLES:
+           DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
            break;
 
        case IOCTL_AFD_DEFER_ACCEPT:
            break;
 
        case IOCTL_AFD_DEFER_ACCEPT:
index 4516e2c..7367e55 100644 (file)
@@ -260,7 +260,8 @@ NTSTATUS TdiOpenConnectionEndpointFile(
 NTSTATUS TdiConnect(
     PIRP *Irp,
     PFILE_OBJECT ConnectionObject,
 NTSTATUS TdiConnect(
     PIRP *Irp,
     PFILE_OBJECT ConnectionObject,
-    PTDI_CONNECTION_INFORMATION RemoteAddress,
+    PTDI_CONNECTION_INFORMATION ConnectionCallInfo,
+    PTDI_CONNECTION_INFORMATION ConnectionReturnInfo,
     PIO_STATUS_BLOCK Iosb,
     PIO_COMPLETION_ROUTINE CompletionRoutine,
     PVOID CompletionContext)
     PIO_STATUS_BLOCK Iosb,
     PIO_COMPLETION_ROUTINE CompletionRoutine,
     PVOID CompletionContext)
@@ -306,8 +307,8 @@ NTSTATUS TdiConnect(
                                        CompletionRoutine,      /* Completion routine */
                                        CompletionContext,      /* Completion routine context */
                                        NULL,                   /* Time */
                                        CompletionRoutine,      /* Completion routine */
                                        CompletionContext,      /* Completion routine context */
                                        NULL,                   /* Time */
-                                       RemoteAddress,          /* Request connection information */
-                                       RemoteAddress);         /* Return connection information */
+                                       ConnectionCallInfo,     /* Request connection information */
+                                       ConnectionReturnInfo);  /* Return connection information */
 
        Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
 
 
        Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
 
index d75b147..c16afb6 100644 (file)
@@ -111,8 +111,6 @@ typedef struct IPADDR_ENTRY {
 #define DEFAULT_SEND_WINDOW_SIZE        16384
 #define DEFAULT_RECEIVE_WINDOW_SIZE     16384
 
 #define DEFAULT_SEND_WINDOW_SIZE        16384
 #define DEFAULT_RECEIVE_WINDOW_SIZE     16384
 
-#define SGID_CONNECTIONLESS             1 /* XXX Find this flag */
-
 /* XXX This is a hack we should clean up later
  * We do this in order to get some storage for the locked handle table
  * Maybe I'll use some tail item in the irp instead */
 /* XXX This is a hack we should clean up later
  * We do this in order to get some storage for the locked handle table
  * Maybe I'll use some tail item in the irp instead */
@@ -182,24 +180,34 @@ typedef struct _AFD_FCB {
     KIRQL OldIrql;
     UINT LockCount;
     PVOID CurrentThread;
     KIRQL OldIrql;
     UINT LockCount;
     PVOID CurrentThread;
-    KSPIN_LOCK SpinLock;
     PFILE_OBJECT FileObject;
     PAFD_DEVICE_EXTENSION DeviceExt;
     BOOLEAN DelayedAccept, NeedsNewListen;
     UINT ConnSeq;
     PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
     PFILE_OBJECT FileObject;
     PAFD_DEVICE_EXTENSION DeviceExt;
     BOOLEAN DelayedAccept, NeedsNewListen;
     UINT ConnSeq;
     PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
-    PTDI_CONNECTION_INFORMATION AddressFrom;
+    PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo;
     AFD_TDI_OBJECT AddressFile, Connection;
     AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp;
     AFD_DATA_WINDOW Send, Recv;
     AFD_TDI_OBJECT AddressFile, Connection;
     AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp;
     AFD_DATA_WINDOW Send, Recv;
-    FAST_MUTEX Mutex;
-    KEVENT StateLockedEvent;
+    KMUTEX Mutex;
     PKEVENT EventSelect;
     DWORD EventSelectTriggers;
     UNICODE_STRING TdiDeviceName;
     PVOID Context;
     DWORD PollState;
     UINT ContextSize;
     PKEVENT EventSelect;
     DWORD EventSelectTriggers;
     UNICODE_STRING TdiDeviceName;
     PVOID Context;
     DWORD PollState;
     UINT ContextSize;
+    PVOID ConnectData;
+    UINT FilledConnectData;
+    UINT ConnectDataSize;
+    PVOID DisconnectData;
+    UINT FilledDisconnectData;
+    UINT DisconnectDataSize;
+    PVOID ConnectOptions;
+    UINT FilledConnectOptions;
+    UINT ConnectOptionsSize;
+    PVOID DisconnectOptions;
+    UINT FilledDisconnectOptions;
+    UINT DisconnectOptionsSize;
     LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
     LIST_ENTRY DatagramList;
     LIST_ENTRY PendingConnections;
     LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
     LIST_ENTRY DatagramList;
     LIST_ENTRY PendingConnections;
@@ -219,6 +227,24 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB );
 NTSTATUS NTAPI
 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                       PIO_STACK_LOCATION IrpSp);
 NTSTATUS NTAPI
 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                       PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                  PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                      PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                    PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                     PIO_STACK_LOCATION IrpSp);
+NTSTATUS NTAPI
+AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                         PIO_STACK_LOCATION IrpSp);
 
 /* context.c */
 
 
 /* context.c */
 
@@ -266,7 +292,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
                         PVOID AddressBuf, PINT AddressLen,
                         BOOLEAN Write, BOOLEAN LockAddress );
 VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address );
                         PVOID AddressBuf, PINT AddressLen,
                         BOOLEAN Write, BOOLEAN LockAddress );
 VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address );
-UINT SocketAcquireStateLock( PAFD_FCB FCB );
+BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB );
 NTSTATUS NTAPI UnlockAndMaybeComplete
 ( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,
   UINT Information );
 NTSTATUS NTAPI UnlockAndMaybeComplete
 ( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,
   UINT Information );
index aa029e2..93354ba 100644 (file)
@@ -3,7 +3,8 @@
 
 NTSTATUS TdiConnect( PIRP *PendingIrp,
                     PFILE_OBJECT ConnectionObject,
 
 NTSTATUS TdiConnect( PIRP *PendingIrp,
                     PFILE_OBJECT ConnectionObject,
-                    PTDI_CONNECTION_INFORMATION RemoteAddress,
+                    PTDI_CONNECTION_INFORMATION ConnectionCallInfo,
+                    PTDI_CONNECTION_INFORMATION ConnectionReturnInfo,
                     PIO_STATUS_BLOCK Iosb,
                     PIO_COMPLETION_ROUTINE CompletionRoutine,
                     PVOID CompletionContext );
                     PIO_STATUS_BLOCK Iosb,
                     PIO_COMPLETION_ROUTINE CompletionRoutine,
                     PVOID CompletionContext );