More work on winsock stack (ping is now working)
[reactos.git] / reactos / drivers / net / afd / afd / opnclose.c
index c882531..324d514 100644 (file)
@@ -16,13 +16,13 @@ PAFDFCB AfdInitializeFCB(
  * FUNCTION: Allocates and initializes a File Control Block structure
  */
 {
-    PAFDFCB NewFCB;
+  PAFDFCB NewFCB;
 
-    NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
-    if (!NewFCB)
-        return NULL;
+  NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
+  if (!NewFCB)
+    return NULL;
 
-    RtlZeroMemory(NewFCB, sizeof(AFDFCB));
+  RtlZeroMemory(NewFCB, sizeof(AFDFCB));
 
        ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
        ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
@@ -31,17 +31,25 @@ PAFDFCB AfdInitializeFCB(
        NewFCB->ReferenceCount  = 1;
        NewFCB->OpenHandleCount = 1;
 
-    NewFCB->TdiAddressObjectHandle    = INVALID_HANDLE_VALUE;
-    NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
+  NewFCB->TdiAddressObjectHandle    = INVALID_HANDLE_VALUE;
+  NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
+
+  InitializeListHead(&NewFCB->CCBListHead);
 
-    InitializeListHead(&NewFCB->CCBListHead);
+  InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
 
-    InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
+  InitializeListHead(&NewFCB->ReceiveQueue);
+  KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
+
+  InitializeListHead(&NewFCB->ReadRequestQueue);
+  KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
 
        if (FileObject)
-               FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
+               FileObject->FsContext = (PVOID)NewFCB;
+
+  AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
 
-    return NewFCB;
+  return NewFCB;
 }
 
 
@@ -66,11 +74,15 @@ PAFDCCB AfdInitializeCCB(
 
     InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
 
+    AFD_DbgPrint(MAX_TRACE, ("CCB created for file object (0x%X) at (0x%X).\n", FileObject, NewCCB));
+
     return NewCCB;
 }
 
 
-NTSTATUS AfdCreate(
+NTSTATUS
+STDCALL
+AfdCreate(
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp)
 {
@@ -85,7 +97,9 @@ NTSTATUS AfdCreate(
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
     PFILE_OBJECT FileObject  = IrpSp->FileObject;
 
-    AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
+    AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    assert(DeviceObject);
 
     DeviceExt = DeviceObject->DeviceExtension;
 
@@ -114,17 +128,53 @@ NTSTATUS AfdCreate(
     /* FIXME: File/socket could already be open, do a search for it */
 
     FCB = AfdInitializeFCB(DeviceExt, FileObject);
+
     CCB = AfdInitializeCCB(FCB, FileObject);
+
     if (CCB && FCB) {
-        FCB->AddressFamily      = SocketInfo->AddressFamily;
-        FCB->SocketType         = SocketInfo->SocketType;
-        FCB->Protocol           = SocketInfo->Protocol;
-        FCB->HelperContext      = SocketInfo->HelperContext;
-        FCB->NotificationEvents = SocketInfo->NotificationEvents;
-        RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
-    } else {
+        FCB->CommandChannel = SocketInfo->CommandChannel;
+
+        if (!FCB->CommandChannel) {
+            FCB->AddressFamily      = SocketInfo->AddressFamily;
+            FCB->SocketType         = SocketInfo->SocketType;
+            FCB->Protocol           = SocketInfo->Protocol;
+            FCB->SocketName         = SocketInfo->Name;
+            FCB->HelperContext      = SocketInfo->HelperContext;
+            FCB->NotificationEvents = SocketInfo->NotificationEvents;
+
+            if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) {
+
+                RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
+
+                AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
+
+                /* Open address file now for raw sockets */
+                if (FCB->SocketType == SOCK_RAW) {
+                    AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
+
+                    Status = TdiOpenAddressFile(
+                        &FCB->TdiDeviceName,
+                        &SocketInfo->Name,
+                        &FCB->TdiAddressObjectHandle,
+                        &FCB->TdiAddressObject);
+                    if (NT_SUCCESS(Status)) {
+                        Status = AfdRegisterEventHandlers(FCB);
+                        if (NT_SUCCESS(Status)) {
+                          FCB->State = SOCKET_STATE_BOUND;
+                        } else {
+                          AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status));
+                        }
+                    } else {
+                      AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status));
+                    }
+                } else
+                    Status = STATUS_SUCCESS;
+            } else
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+        } else
+            Status = STATUS_SUCCESS;
+    } else
         Status = STATUS_INSUFFICIENT_RESOURCES;
-    }
 
     if (!NT_SUCCESS(Status)) {
         /* FIXME: Cleanup */
@@ -135,13 +185,15 @@ NTSTATUS AfdCreate(
 
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    AFD_DbgPrint(MIN_TRACE, ("Leaving. Status (0x%X).\n", Status));
+    AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
 
     return Status;
 }
 
 
-NTSTATUS AfdClose(
+NTSTATUS
+STDCALL
+AfdClose(
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp)
 {
@@ -151,27 +203,32 @@ NTSTATUS AfdClose(
     PAFDFCB FCB;
     PAFDCCB CCB;
 
+    AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    assert(DeviceObject);
+    assert(FileObject);
+
     FCB = FileObject->FsContext;
     CCB = FileObject->FsContext2;
 
-    AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
-
     switch (IrpSp->MajorFunction) {
     /* Close a file object */
     case IRP_MJ_CLOSE:
         FCB->ReferenceCount--;
         if (FCB->ReferenceCount < 1) {
-            /* Close TDI connection file object */
-            if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
-                TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
-                FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
-            }
-
-            /* Close TDI address file object */
-            if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
-                AfdDeregisterEventHandlers(FCB);
-                TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
-                FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
+            if (!FCB->CommandChannel) {
+                /* Close TDI connection file object */
+                if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
+                    TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
+                    FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
+                }
+
+                /* Close TDI address file object */
+                if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
+                    AfdDeregisterEventHandlers(FCB);
+                    TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
+                    FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
+                }
             }
 
             ExFreePool(FCB);