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/…
==============================================================================
--- 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/nd…
==============================================================================
--- 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/nd…
==============================================================================
--- 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/nd…
==============================================================================
--- 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,