minor corrections by M.Taguchi
[reactos.git] / reactos / drivers / net / afd / afd / dispatch.c
index 7aac87e..d7cfdc2 100644 (file)
@@ -130,6 +130,23 @@ NTSTATUS AfdDispBind(
 }
 
 
+NTSTATUS
+STDCALL
+AfdDispCompleteListen(
+  PDEVICE_OBJECT DeviceObject,
+  PIRP Irp,
+  PVOID Context)
+{
+  PAFD_LISTEN_REQUEST ListenRequest = (PAFD_LISTEN_REQUEST) Context;
+
+  AFD_DbgPrint(MAX_TRACE, ("Called. ListenRequest (0x%X).\n", ListenRequest));
+
+  AFD_DbgPrint(MAX_TRACE, ("Fcb (0x%X).\n", ListenRequest->Fcb));
+
+  return STATUS_SUCCESS;
+}
+
+
 NTSTATUS AfdDispListen(
     PIRP Irp,
     PIO_STACK_LOCATION IrpSp)
@@ -148,6 +165,7 @@ NTSTATUS AfdDispListen(
   PFILE_REQUEST_LISTEN Request;
   PFILE_REPLY_LISTEN Reply;
   PAFDFCB FCB;
+  PAFD_LISTEN_REQUEST ListenRequest;
 
   InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
   OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
@@ -161,32 +179,72 @@ NTSTATUS AfdDispListen(
     Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
     Reply   = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
 
-    if (FCB->State == SOCKET_STATE_BOUND) {
+    if (FCB->State == SOCKET_STATE_BOUND)
+      {
+        /* We have a bound socket so go ahead and create a connection endpoint
+           and associate it with the address file object */
 
-      /* We have a bound socket so go ahead and create a connection endpoint
-         and associate it with the address file object */
-
-      Status = TdiOpenConnectionEndpointFile(
-        &FCB->TdiDeviceName,
-        &FCB->TdiConnectionObjectHandle,
-        &FCB->TdiConnectionObject);
+        Status = TdiOpenConnectionEndpointFile(
+          &FCB->TdiDeviceName,
+          &FCB->TdiConnectionObjectHandle,
+          &FCB->TdiConnectionObject);
 
-      if (NT_SUCCESS(Status)) {
-        Status = TdiAssociateAddressFile(
-          FCB->TdiAddressObjectHandle,
-          FCB->TdiConnectionObject);
+        if (NT_SUCCESS(Status))
+          {
+            Status = TdiAssociateAddressFile(
+              FCB->TdiAddressObjectHandle,
+              FCB->TdiConnectionObject);
+
+            if (NT_SUCCESS(Status))
+              {
+                           ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
+                if (ListenRequest != NULL)
+                  {
+                    ListenRequest->Fcb = FCB;
+                    /* FIXME: Protect ListenRequestQueue */
+                    InsertTailList(&FCB->ListenRequestQueue, &ListenRequest->ListEntry);
+
+                    Status = TdiListen(FCB->TdiConnectionObject, AfdDispCompleteListen, ListenRequest);
+                    if ((Status == STATUS_PENDING) || NT_SUCCESS(Status))
+                      {
+                        if (Status != STATUS_PENDING)
+                          {
+                            AFD_DbgPrint(MIN_TRACE, ("FIXME: Status (0x%X).\n", Status));
+                          }
+                        Status = STATUS_SUCCESS;
+                      }
+                               else
+                                 {
+                        /* FIXME: Cleanup ListenRequest */
+                        /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
+                                 }
+                  }
+                           else
+                             {
+                    /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
+                    Status = STATUS_NO_MEMORY;
+                             }
+              }
+                       else
+                         {
+                /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
+                         }
+          }
+
+        if (NT_SUCCESS(Status)) {
+          Reply->Status = NO_ERROR;
+        } else {
+          Reply->Status = WSAEINVAL;
+        }
       }
-
-      if (NT_SUCCESS(Status)) {
-        Reply->Status = NO_ERROR;
-      } else {
+    else if (FCB->State == SOCKET_STATE_CONNECTED)
+      {
+        Reply->Status = WSAEISCONN;
+      }
+    else
+      {
         Reply->Status = WSAEINVAL;
       }
-    } else if (FCB->State == SOCKET_STATE_CONNECTED) {
-      Reply->Status = WSAEISCONN;
-    } else {
-      Reply->Status = WSAEINVAL;
-    }
   }
 
   AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
@@ -254,7 +312,7 @@ NTSTATUS AfdDispSendTo(
 
       /* FIXME: Should we handle special cases here? */
       if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
-        DataBufferAddress = SystemVirtualAddress + sizeof(IPv4_HEADER);
+        DataBufferAddress = ((PCHAR)SystemVirtualAddress) + sizeof(IPv4_HEADER);
 
         /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
         ((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
@@ -311,21 +369,46 @@ NTSTATUS AfdDispSendTo(
 
 #if 0
 #ifdef _MSC_VER
-  try {
+    try {
 #endif
-      MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
+       MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
 #ifdef _MSC_VER
-  } except(EXCEPTION_EXECUTE_HANDLER) {
-      AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
-      IoFreeMdl(Mdl);
-      if (BufferSize != 0) {
-          ExFreePool(SystemVirtualAddress);
-      }
-      return STATUS_UNSUCCESSFUL;
-  }
+    } except(EXCEPTION_EXECUTE_HANDLER) {
+       AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
+       IoFreeMdl(Mdl);
+       if (BufferSize != 0) {
+           ExFreePool(SystemVirtualAddress);
+       }
+       return STATUS_UNSUCCESSFUL;
+    }
 #endif
 #endif
-
+    
+    if (!FCB->TdiAddressObject) {
+       struct sockaddr_in BindName;
+
+       RtlZeroMemory(&BindName,sizeof(BindName));
+       BindName.sin_family = AF_INET;
+
+       Status = TdiOpenAddressFile
+           (&FCB->TdiDeviceName,
+            (SOCKADDR *)&BindName,
+            &FCB->TdiAddressObjectHandle,
+            &FCB->TdiAddressObject);
+
+       if (NT_SUCCESS(Status)) {
+           AfdRegisterEventHandlers(FCB);
+           FCB->State = SOCKET_STATE_BOUND;
+           Reply->Status = NO_ERROR;
+       } else {
+           //FIXME: WSAEADDRNOTAVAIL
+           Reply->Status = WSAEINVAL;
+           MmUnlockPages(Mdl);
+           IoFreeMdl(Mdl);
+           return Status;
+       }
+    }
+    
     Status = TdiSendDatagram(FCB->TdiAddressObject,
         &Request->To,
         Mdl,
@@ -838,4 +921,61 @@ NTSTATUS AfdDispConnect(
   return Status;
 }
 
+
+NTSTATUS AfdDispGetName(
+  PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Get socket name
+ * ARGUMENTS:
+ *     Irp   = Pointer to I/O request packet
+ *     IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ *     Status of operation
+ */
+{
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_GETNAME Request;
+  PFILE_REPLY_GETNAME Reply;
+  PAFDFCB FCB;
+  PFILE_OBJECT FileObject;
+
+  AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  Status = STATUS_INVALID_PARAMETER;
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_GETNAME)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_GETNAME))) {
+    FCB = IrpSp->FileObject->FsContext;
+
+    Request = (PFILE_REQUEST_GETNAME)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_GETNAME)Irp->AssociatedIrp.SystemBuffer;
+
+    AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+    if (Request->Peer) {
+      if (FCB->State != SOCKET_STATE_CONNECTED) {
+        Reply->Status = WSAENOTCONN;
+        return STATUS_UNSUCCESSFUL;
+      }
+      FileObject = FCB->TdiConnectionObject;
+    } else {
+      FileObject = FCB->TdiAddressObject;
+    }
+
+    /* FIXME: Implement */
+    /* Make a TDI_QUERY_INFORMATION call to underlying TDI transport driver */
+    Status = STATUS_UNSUCCESSFUL;
+  }
+
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+  return Status;
+}
+
 /* EOF */