[ros-diffs] [cgutman] 54897: [NDISUIO] - Store the correct length in Irp->IoStatus.Information so bytes don't get chopped off - Fix multiple bugs in the receive path (which now works correctly) [WLANCONF] - Us...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Tue Jan 10 01:52:24 UTC 2012


Author: cgutman
Date: Tue Jan 10 01:52:18 2012
New Revision: 54897

URL: http://svn.reactos.org/svn/reactos?rev=54897&view=rev
Log:
[NDISUIO]
- Store the correct length in Irp->IoStatus.Information so bytes don't get chopped off
- Fix multiple bugs in the receive path (which now works correctly)
[WLANCONF]
- Use the correct length for NDIS requests
- Indicate success to the console for -c or -d
- Print current association info if called with no parameters

Modified:
    branches/wlan-bringup/base/applications/network/wlanconf/wlanconf.c
    branches/wlan-bringup/drivers/network/ndisuio/ioctl.c
    branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h
    branches/wlan-bringup/drivers/network/ndisuio/protocol.c

Modified: branches/wlan-bringup/base/applications/network/wlanconf/wlanconf.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/base/applications/network/wlanconf/wlanconf.c?rev=54897&r1=54896&r2=54897&view=diff
==============================================================================
--- branches/wlan-bringup/base/applications/network/wlanconf/wlanconf.c [iso-8859-1] (original)
+++ branches/wlan-bringup/base/applications/network/wlanconf/wlanconf.c [iso-8859-1] Tue Jan 10 01:52:18 2012
@@ -94,7 +94,7 @@
     PNDISUIO_QUERY_OID QueryOid;
     DWORD QueryOidSize;
 
-    QueryOidSize = sizeof(NDISUIO_QUERY_OID) + sizeof(NDIS_802_11_SSID);
+    QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_SSID);
     QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
     if (!QueryOid)
         return FALSE;
@@ -216,8 +216,11 @@
                                0,
                                &dwBytesReturned,
                                NULL);
-
-    return bSuccess;
+    if (!bSuccess)
+        return FALSE;
+
+    _tprintf(_T("The operation completed successfully.\n"));
+    return TRUE;
 }
 
 static
@@ -266,6 +269,263 @@
 }
 
 BOOL
+WlanPrintCurrentStatus(HANDLE hAdapter)
+{
+    PNDISUIO_QUERY_OID QueryOid;
+    DWORD QueryOidSize;
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    PNDIS_802_11_SSID SsidInfo;
+    CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1];
+    DWORD i;
+    
+    QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_SSID);
+    QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
+    if (!QueryOid)
+        return FALSE;
+    
+    QueryOid->Oid = OID_802_11_SSID;
+    SsidInfo = (PNDIS_802_11_SSID)QueryOid->Data;
+
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return FALSE;
+    }
+
+    if (SsidInfo->SsidLength == 0)
+    {
+        _tprintf(_T("\nWLAN disconnected\n"));
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return TRUE;
+    }
+    else
+    {
+        _tprintf(_T("\nCurrent wireless association information:\n\n"));
+    }
+    
+    /* Copy the SSID to our internal buffer and terminate it */
+    RtlCopyMemory(SsidBuffer, SsidInfo->Ssid, SsidInfo->SsidLength);
+    SsidBuffer[SsidInfo->SsidLength] = 0;
+    
+    _tprintf(_T("SSID: %s\n"), SsidBuffer);
+
+    HeapFree(GetProcessHeap(), 0, QueryOid);
+    QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS);
+    QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
+    if (!QueryOid)
+        return FALSE;
+
+    QueryOid->Oid = OID_802_11_BSSID;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return FALSE;
+    }
+
+    _tprintf(_T("BSSID: "));
+    for (i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
+    {
+        UINT BssidData = QueryOid->Data[i];
+
+        _tprintf(_T("%.2x"), BssidData);
+
+        if (i != sizeof(NDIS_802_11_MAC_ADDRESS) - 1)
+            _tprintf(_T(":"));
+    }
+    _tprintf(_T("\n"));
+    
+    HeapFree(GetProcessHeap(), 0, QueryOid);
+    QueryOidSize = sizeof(NDISUIO_QUERY_OID);
+    QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
+    if (!QueryOid)
+        return FALSE;
+    
+    QueryOid->Oid = OID_802_11_INFRASTRUCTURE_MODE;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return FALSE;
+    }
+    
+    _tprintf(_T("Network mode: %s\n"), (*(PUINT)QueryOid->Data == Ndis802_11IBSS) ? "Adhoc" : "Infrastructure");
+    
+    QueryOid->Oid = OID_802_11_WEP_STATUS;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return FALSE;
+    }
+    
+    _tprintf(_T("WEP enabled: %s\n"), (*(PUINT)QueryOid->Data == Ndis802_11WEPEnabled) ? "Yes" : "No");
+    
+    _tprintf("\n");
+    QueryOid->Oid = OID_802_11_RSSI;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        /* This OID is optional */
+        _tprintf(_T("RSSI: %i dBm\n"), *(PINT)QueryOid->Data);
+    }
+    
+    QueryOid->Oid = OID_802_11_TX_POWER_LEVEL;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        /* This OID is optional */
+        _tprintf(_T("Transmission power: %d mW\n"), *(PUINT)QueryOid->Data);
+    }
+    
+    _tprintf(_T("\n"));
+    
+    QueryOid->Oid = OID_802_11_NUMBER_OF_ANTENNAS;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        /* This OID is optional */
+        _tprintf(_T("Antenna count: %d\n"), *(PUINT)QueryOid->Data);
+    }
+    
+    QueryOid->Oid = OID_802_11_TX_ANTENNA_SELECTED;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        UINT TransmitAntenna = *(PUINT)QueryOid->Data;
+        
+        if (TransmitAntenna != 0xFFFFFFFF)
+            _tprintf(_T("Transmit antenna: %d\n"), TransmitAntenna);
+        else
+            _tprintf(_T("Transmit antenna: Any\n"));
+    }
+    
+    QueryOid->Oid = OID_802_11_RX_ANTENNA_SELECTED;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        UINT ReceiveAntenna = *(PUINT)QueryOid->Data;
+        
+        if (ReceiveAntenna != 0xFFFFFFFF)
+            _tprintf(_T("Receive antenna: %d\n"), ReceiveAntenna);
+        else
+            _tprintf(_T("Receive antenna: Any\n"));
+    }
+    
+    _tprintf(_T("\n"));
+    
+    QueryOid->Oid = OID_802_11_FRAGMENTATION_THRESHOLD;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        /* This OID is optional */
+        _tprintf(_T("Fragmentation threshold: %d bytes\n"), *(PUINT)QueryOid->Data);
+    }
+    
+    QueryOid->Oid = OID_802_11_RTS_THRESHOLD;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (bSuccess)
+    {
+        /* This OID is optional */
+        _tprintf(_T("RTS threshold: %d bytes\n"), *(PUINT)QueryOid->Data);
+    }
+    
+    HeapFree(GetProcessHeap(), 0, QueryOid);
+    
+    _tprintf(_T("\n"));
+    return TRUE;
+}
+
+BOOL
 WlanConnect(HANDLE hAdapter)
 {
     BOOL bSuccess;
@@ -321,7 +581,8 @@
         
         HeapFree(GetProcessHeap(), 0, SetOid);
 
-        SetOidSize = sizeof(NDISUIO_SET_OID) + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) +
+        SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) +
+                     FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) +
                      (strlen(sWepKey) >> 1);
         SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
         if (!SetOid)
@@ -378,7 +639,7 @@
     }
     
     HeapFree(GetProcessHeap(), 0, SetOid);
-    SetOidSize = sizeof(NDISUIO_SET_OID) + sizeof(NDIS_802_11_MAC_ADDRESS);
+    SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS);
     SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
     if (!SetOid)
         return FALSE;
@@ -402,7 +663,7 @@
     }
     
     HeapFree(GetProcessHeap(), 0, SetOid);
-    SetOidSize = sizeof(NDISUIO_SET_OID) + sizeof(NDIS_802_11_SSID);
+    SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_SSID);
     SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
     if (!SetOid)
         return FALSE;
@@ -425,7 +686,11 @@
     
     HeapFree(GetProcessHeap(), 0, SetOid);
     
-    return bSuccess;
+    if (!bSuccess)
+        return FALSE;
+
+    _tprintf(_T("The operation completed successfully.\n"));
+    return TRUE;
 }
 
 BOOL
@@ -546,7 +811,8 @@
     "     -w WEP     Specifies a WEP key to use.\n"
     "     -a         Specifies the target network is ad-hoc\n"
     "  -d            Disconnects from the current AP.\n"
-    "  -s            Scans and displays a list of access points in range.\n"));
+    "  -s            Scans and displays a list of access points in range.\n\n"
+    " Passing no parameters will print information about the current WLAN connection\n"));
 }
 
 
@@ -599,12 +865,6 @@
         }
     }
 
-    if (!bScan && !bDisconnect && !bConnect)
-    {
-        Usage();
-        return FALSE;
-    }
-
     return TRUE;
 }
 
@@ -640,7 +900,7 @@
             return -1;
         }
     }
-    else
+    else if (bConnect)
     {
         if (!WlanConnect(hAdapter))
         {
@@ -649,6 +909,15 @@
             return -1;
         }
     }
+    else
+    {
+        if (!WlanPrintCurrentStatus(hAdapter))
+        {
+            DoFormatMessage(GetLastError());
+            CloseHandle(hAdapter);
+            return -1;
+        }
+    }
 
     CloseHandle(hAdapter);
     return 0;

Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndisuio/ioctl.c?rev=54897&r1=54896&r2=54897&view=diff
==============================================================================
--- branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] (original)
+++ branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] Tue Jan 10 01:52:18 2012
@@ -160,8 +160,16 @@
         /* Setup the NDIS request */
         Request.RequestType = NdisRequestSetInformation;
         Request.DATA.SET_INFORMATION.Oid = SetOidRequest->Oid;
-        Request.DATA.SET_INFORMATION.InformationBuffer = SetOidRequest->Data;
         Request.DATA.SET_INFORMATION.InformationBufferLength = RequestLength - sizeof(NDIS_OID);
+        if (Request.DATA.SET_INFORMATION.InformationBufferLength != 0)
+        {
+            Request.DATA.SET_INFORMATION.InformationBuffer = SetOidRequest->Data;
+        }
+        else
+        {
+            Request.DATA.SET_INFORMATION.InformationBuffer = NULL;
+        }
+        Request.DATA.SET_INFORMATION.BytesRead = 0;
 
         DPRINT("Setting OID 0x%x on adapter %wZ\n", SetOidRequest->Oid, &AdapterContext->DeviceName);
 
@@ -182,7 +190,9 @@
         }
 
         /* Return the bytes read */
-        if (NT_SUCCESS(Status)) Irp->IoStatus.Information = Request.DATA.SET_INFORMATION.BytesRead;
+        if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(NDIS_OID) + Request.DATA.SET_INFORMATION.BytesRead;
+
+        DPRINT("Final request status: 0x%x (%d)\n", Status, Irp->IoStatus.Information);
     }
     else
     {
@@ -216,9 +226,17 @@
         /* Setup the NDIS request */
         Request.RequestType = NdisRequestQueryInformation;
         Request.DATA.QUERY_INFORMATION.Oid = QueryOidRequest->Oid;
-        Request.DATA.QUERY_INFORMATION.InformationBuffer = QueryOidRequest->Data;
         Request.DATA.QUERY_INFORMATION.InformationBufferLength = RequestLength - sizeof(NDIS_OID);
-        
+        if (Request.DATA.QUERY_INFORMATION.InformationBufferLength != 0)
+        {
+            Request.DATA.QUERY_INFORMATION.InformationBuffer = QueryOidRequest->Data;
+        }
+        else
+        {
+            Request.DATA.QUERY_INFORMATION.InformationBuffer = NULL;
+        }
+        Request.DATA.QUERY_INFORMATION.BytesWritten = 0;
+
         DPRINT("Querying OID 0x%x on adapter %wZ\n", QueryOidRequest->Oid, &AdapterContext->DeviceName);
         
         /* Dispatch the request */
@@ -238,7 +256,9 @@
         }
 
         /* Return the bytes written */
-        if (NT_SUCCESS(Status)) Irp->IoStatus.Information = Request.DATA.QUERY_INFORMATION.BytesWritten;
+        if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(NDIS_OID) + Request.DATA.QUERY_INFORMATION.BytesWritten;
+
+        DPRINT("Final request status: 0x%x (%d)\n", Status, Irp->IoStatus.Information);
     }
     else
     {

Modified: branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h?rev=54897&r1=54896&r2=54897&view=diff
==============================================================================
--- branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h [iso-8859-1] (original)
+++ branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h [iso-8859-1] Tue Jan 10 01:52:18 2012
@@ -36,6 +36,9 @@
     /* Receive packet list */
     LIST_ENTRY PacketList;
     KEVENT PacketReadEvent;
+    
+    /* Mac options */
+    ULONG MacOptions;
 
     /* Device name */
     UNICODE_STRING DeviceName;

Modified: branches/wlan-bringup/drivers/network/ndisuio/protocol.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndisuio/protocol.c?rev=54897&r1=54896&r2=54897&view=diff
==============================================================================
--- branches/wlan-bringup/drivers/network/ndisuio/protocol.c [iso-8859-1] (original)
+++ branches/wlan-bringup/drivers/network/ndisuio/protocol.c [iso-8859-1] Tue Jan 10 01:52:18 2012
@@ -116,13 +116,15 @@
     PNDIS_PACKET Packet;
     NDIS_STATUS Status;
     UINT BytesTransferred;
+    
+    DPRINT("Received a %d byte packet\n", PacketSize);
 
     /* Discard if nobody is waiting for it */
     if (AdapterContext->OpenCount == 0)
         return NDIS_STATUS_NOT_ACCEPTED;
     
     /* Allocate a buffer to hold the packet data and header */
-    PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize);
+    PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize + HeaderBufferSize);
     if (!PacketBuffer)
         return NDIS_STATUS_NOT_ACCEPTED;
 
@@ -137,13 +139,167 @@
     }
 
     /* Transfer the packet data into our data buffer */
-    NdisTransferData(&Status,
-                     AdapterContext->BindingHandle,
-                     MacReceiveContext,
-                     0,
-                     PacketSize,
-                     Packet,
-                     &BytesTransferred);
+    if (LookaheadBufferSize == PacketSize)
+    {
+        NdisCopyLookaheadData((PVOID)((PUCHAR)PacketBuffer + HeaderBufferSize),
+                              LookAheadBuffer,
+                              PacketSize,
+                              AdapterContext->MacOptions);
+        BytesTransferred = PacketSize;
+    }
+    else
+    {
+        NdisTransferData(&Status,
+                         AdapterContext->BindingHandle,
+                         MacReceiveContext,
+                         0,
+                         PacketSize,
+                         Packet,
+                         &BytesTransferred);
+        if (Status == NDIS_STATUS_PENDING)
+        {
+            KeWaitForSingleObject(&AdapterContext->AsyncEvent,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
+            Status = AdapterContext->AsyncStatus;
+        }
+        if (Status != NDIS_STATUS_SUCCESS)
+        {
+            DPRINT1("Failed to transfer data with status 0x%x\n", Status);
+            CleanupAndFreePacket(Packet, TRUE);
+            return NDIS_STATUS_NOT_ACCEPTED;
+        }
+    }
+    
+    /* Copy the header data */
+    RtlCopyMemory(PacketBuffer, HeaderBuffer, HeaderBufferSize);
+    
+    /* Free the packet descriptor and buffers 
+       but not the pool because we still need it */
+    CleanupAndFreePacket(Packet, FALSE);
+
+    /* Allocate a packet entry from pool */
+    PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY) + BytesTransferred + HeaderBufferSize - 1);
+    if (!PacketEntry)
+    {
+        ExFreePool(PacketBuffer);
+        return NDIS_STATUS_RESOURCES;
+    }
+
+    /* Initialize the packet entry and copy in packet data */
+    PacketEntry->PacketLength = BytesTransferred + HeaderBufferSize;
+    RtlCopyMemory(PacketEntry->PacketData, PacketBuffer, PacketEntry->PacketLength);
+    
+    /* Free the old buffer */
+    ExFreePool(PacketBuffer);
+
+    /* Insert the packet on the adapter's packet list */
+    ExInterlockedInsertTailList(&AdapterContext->PacketList,
+                                &PacketEntry->ListEntry,
+                                &AdapterContext->Spinlock);
+    
+    /* Signal the read event */
+    KeSetEvent(&AdapterContext->PacketReadEvent,
+               IO_NETWORK_INCREMENT,
+               FALSE);
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+NduReceiveComplete(NDIS_HANDLE ProtocolBindingContext)
+{
+    /* No op */
+}
+
+VOID
+NTAPI
+NduStatus(NDIS_HANDLE ProtocolBindingContext,
+          NDIS_STATUS GeneralStatus,
+          PVOID StatusBuffer,
+          UINT StatusBufferSize)
+{
+    /* FIXME: Implement status tracking */
+}
+
+VOID
+NTAPI
+NduStatusComplete(NDIS_HANDLE ProtocolBindingContext)
+{
+    /* FIXME: Implement status tracking */
+}
+
+static
+NDIS_STATUS
+UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
+{
+    KIRQL OldIrql;
+    PLIST_ENTRY CurrentEntry;
+    PNDISUIO_OPEN_ENTRY OpenEntry;
+    PNDISUIO_PACKET_ENTRY PacketEntry;
+    NDIS_STATUS Status;
+    
+    DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName);
+    
+    /* FIXME: We don't do anything with outstanding reads */
+
+    /* Remove the adapter context from the global list */
+    KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
+    RemoveEntryList(&AdapterContext->ListEntry);
+    KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
+    
+    /* Free the device name string */
+    RtlFreeUnicodeString(&AdapterContext->DeviceName);
+
+    /* Invalidate all handles to this adapter */
+    CurrentEntry = AdapterContext->OpenEntryList.Flink;
+    while (CurrentEntry != &AdapterContext->OpenEntryList)
+    {
+        OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry);
+
+        /* Make sure the entry is sane */
+        ASSERT(OpenEntry->FileObject);
+
+        /* Remove the adapter context pointer */
+        ASSERT(AdapterContext == OpenEntry->FileObject->FsContext);
+        OpenEntry->FileObject->FsContext = NULL;
+        AdapterContext->OpenCount--;
+
+        /* Remove the open entry pointer */
+        ASSERT(OpenEntry == OpenEntry->FileObject->FsContext2);
+        OpenEntry->FileObject->FsContext2 = NULL;
+        
+        /* Move to the next entry */
+        CurrentEntry = CurrentEntry->Flink;
+
+        /* Free the open entry */
+        ExFreePool(OpenEntry);
+    }
+
+    /* If this fails, we have a refcount mismatch somewhere */
+    ASSERT(AdapterContext->OpenCount == 0);
+    
+    /* Free all pending packet entries */
+    CurrentEntry = AdapterContext->PacketList.Flink;
+    while (CurrentEntry != &AdapterContext->PacketList)
+    {
+        PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry);
+
+        /* Move to the next entry */
+        CurrentEntry = CurrentEntry->Flink;
+
+        /* Free the packet entry */
+        ExFreePool(PacketEntry);
+    }
+    
+    /* Send the close request */
+    NdisCloseAdapter(&Status,
+                     AdapterContext->BindingHandle);
+    
+    /* Wait for a pending close */
     if (Status == NDIS_STATUS_PENDING)
     {
         KeWaitForSingleObject(&AdapterContext->AsyncEvent,
@@ -153,149 +309,6 @@
                               NULL);
         Status = AdapterContext->AsyncStatus;
     }
-    if (Status != NDIS_STATUS_SUCCESS)
-    {
-        DPRINT1("Failed to transfer data with status 0x%x\n", Status);
-        CleanupAndFreePacket(Packet, TRUE);
-        return NDIS_STATUS_NOT_ACCEPTED;
-    }
-    
-    /* Copy the header data */
-    RtlCopyMemory(PacketBuffer, HeaderBuffer, HeaderBufferSize);
-    
-    /* Free the packet descriptor and buffers 
-       but not the pool because we still need it */
-    CleanupAndFreePacket(Packet, FALSE);
-
-    /* Allocate a packet entry from pool */
-    PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY) + BytesTransferred + HeaderBufferSize - 1);
-    if (!PacketEntry)
-    {
-        ExFreePool(PacketBuffer);
-        return NDIS_STATUS_RESOURCES;
-    }
-
-    /* Initialize the packet entry and copy in packet data */
-    PacketEntry->PacketLength = BytesTransferred + HeaderBufferSize;
-    RtlCopyMemory(&PacketEntry->PacketData[0], PacketBuffer, PacketEntry->PacketLength);
-    
-    /* Free the old buffer */
-    ExFreePool(PacketBuffer);
-
-    /* Insert the packet on the adapter's packet list */
-    ExInterlockedInsertTailList(&AdapterContext->PacketList,
-                                &PacketEntry->ListEntry,
-                                &AdapterContext->Spinlock);
-    
-    /* Signal the read event */
-    KeSetEvent(&AdapterContext->PacketReadEvent,
-               IO_NETWORK_INCREMENT,
-               FALSE);
-
-    return NDIS_STATUS_SUCCESS;
-}
-
-VOID
-NTAPI
-NduReceiveComplete(NDIS_HANDLE ProtocolBindingContext)
-{
-    /* No op */
-}
-
-VOID
-NTAPI
-NduStatus(NDIS_HANDLE ProtocolBindingContext,
-          NDIS_STATUS GeneralStatus,
-          PVOID StatusBuffer,
-          UINT StatusBufferSize)
-{
-    /* FIXME: Implement status tracking */
-}
-
-VOID
-NTAPI
-NduStatusComplete(NDIS_HANDLE ProtocolBindingContext)
-{
-    /* FIXME: Implement status tracking */
-}
-
-static
-NDIS_STATUS
-UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
-{
-    KIRQL OldIrql;
-    PLIST_ENTRY CurrentEntry;
-    PNDISUIO_OPEN_ENTRY OpenEntry;
-    PNDISUIO_PACKET_ENTRY PacketEntry;
-    NDIS_STATUS Status;
-    
-    DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName);
-    
-    /* FIXME: We don't do anything with outstanding reads */
-
-    /* Remove the adapter context from the global list */
-    KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
-    RemoveEntryList(&AdapterContext->ListEntry);
-    KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
-    
-    /* Free the device name string */
-    RtlFreeUnicodeString(&AdapterContext->DeviceName);
-
-    /* Invalidate all handles to this adapter */
-    CurrentEntry = AdapterContext->OpenEntryList.Flink;
-    while (CurrentEntry != &AdapterContext->OpenEntryList)
-    {
-        OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry);
-
-        /* Make sure the entry is sane */
-        ASSERT(OpenEntry->FileObject);
-
-        /* Remove the adapter context pointer */
-        ASSERT(AdapterContext == OpenEntry->FileObject->FsContext);
-        OpenEntry->FileObject->FsContext = NULL;
-        AdapterContext->OpenCount--;
-
-        /* Remove the open entry pointer */
-        ASSERT(OpenEntry == OpenEntry->FileObject->FsContext2);
-        OpenEntry->FileObject->FsContext2 = NULL;
-        
-        /* Move to the next entry */
-        CurrentEntry = CurrentEntry->Flink;
-
-        /* Free the open entry */
-        ExFreePool(OpenEntry);
-    }
-
-    /* If this fails, we have a refcount mismatch somewhere */
-    ASSERT(AdapterContext->OpenCount == 0);
-    
-    /* Free all pending packet entries */
-    CurrentEntry = AdapterContext->PacketList.Flink;
-    while (CurrentEntry != &AdapterContext->PacketList)
-    {
-        PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry);
-
-        /* Move to the next entry */
-        CurrentEntry = CurrentEntry->Flink;
-
-        /* Free the packet entry */
-        ExFreePool(PacketEntry);
-    }
-    
-    /* Send the close request */
-    NdisCloseAdapter(&Status,
-                     AdapterContext->BindingHandle);
-    
-    /* Wait for a pending close */
-    if (Status == NDIS_STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = AdapterContext->AsyncStatus;
-    }
     
     /* Free the context */
     ExFreePool(AdapterContext);
@@ -312,6 +325,7 @@
     NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3};
     UINT SelectedMedium;
     NDIS_STATUS Status;
+    NDIS_REQUEST Request;
 
     /* Allocate the adapter context */
     AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
@@ -404,6 +418,51 @@
         return Status;
     }
     
+    /* Get the MAC options */
+    Request.RequestType = NdisRequestQueryInformation;
+    Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS;
+    Request.DATA.QUERY_INFORMATION.InformationBuffer = &AdapterContext->MacOptions;
+    Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
+    NdisRequest(&Status,
+                AdapterContext->BindingHandle,
+                &Request);
+
+    /* Wait for a pending request */
+    if (Status == NDIS_STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
+                              Executive,
+                              KernelMode,
+                              FALSE,
+                              NULL);
+        Status = AdapterContext->AsyncStatus;
+    }
+    
+    /* Check the final status */
+    if (Status != NDIS_STATUS_SUCCESS)
+    {
+        NDIS_STATUS CloseStatus;
+
+        DPRINT1("Failed to get MAC options with status 0x%x\n", Status);
+
+        NdisCloseAdapter(&CloseStatus,
+                         AdapterContext->BindingHandle);
+        if (CloseStatus == NDIS_STATUS_PENDING)
+        {
+            KeWaitForSingleObject(&AdapterContext->AsyncEvent,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
+        }
+
+        NdisFreePacketPool(AdapterContext->PacketPoolHandle);
+        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
+        RtlFreeUnicodeString(&AdapterContext->DeviceName);
+        ExFreePool(AdapterContext);
+        return Status;
+    }
+    
     /* Add the adapter context to the global list */
     ExInterlockedInsertTailList(&GlobalAdapterList,
                                 &AdapterContext->ListEntry,




More information about the Ros-diffs mailing list