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/n... ============================================================================== --- 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/ndi... ============================================================================== --- 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/ndi... ============================================================================== --- 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/ndi... ============================================================================== --- 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,