diff --git a/base/applications/network/wlanconf/wlanconf.c b/base/applications/network/wlanconf/wlanconf.c index 545d664ef15..0a01407e26a 100644 --- a/base/applications/network/wlanconf/wlanconf.c +++ b/base/applications/network/wlanconf/wlanconf.c @@ -94,7 +94,7 @@ IsWlanAdapter(HANDLE hAdapter) 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 @@ WlanDisconnect(HANDLE hAdapter) 0, &dwBytesReturned, NULL); + if (!bSuccess) + return FALSE; - return bSuccess; + _tprintf(_T("The operation completed successfully.\n")); + return TRUE; } static @@ -265,6 +268,263 @@ CharToHex(CHAR Char) } } +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) { @@ -321,7 +581,8 @@ WlanConnect(HANDLE hAdapter) 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 @@ WlanConnect(HANDLE hAdapter) } 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 @@ WlanConnect(HANDLE hAdapter) } 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 @@ WlanConnect(HANDLE hAdapter) HeapFree(GetProcessHeap(), 0, SetOid); - return bSuccess; + if (!bSuccess) + return FALSE; + + _tprintf(_T("The operation completed successfully.\n")); + return TRUE; } BOOL @@ -546,7 +811,8 @@ VOID Usage() " -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 @@ BOOL ParseCmdline(int argc, char* argv[]) } } - if (!bScan && !bDisconnect && !bConnect) - { - Usage(); - return FALSE; - } - return TRUE; } @@ -640,7 +900,7 @@ int main(int argc, char* argv[]) return -1; } } - else + else if (bConnect) { if (!WlanConnect(hAdapter)) { @@ -649,6 +909,15 @@ int main(int argc, char* argv[]) return -1; } } + else + { + if (!WlanPrintCurrentStatus(hAdapter)) + { + DoFormatMessage(GetLastError()); + CloseHandle(hAdapter); + return -1; + } + } CloseHandle(hAdapter); return 0; diff --git a/drivers/network/ndisuio/ioctl.c b/drivers/network/ndisuio/ioctl.c index 774c20d7694..74070d60e70 100644 --- a/drivers/network/ndisuio/ioctl.c +++ b/drivers/network/ndisuio/ioctl.c @@ -160,8 +160,16 @@ SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) /* 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 @@ SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) } /* 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 @@ QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) /* 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 @@ QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) } /* 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 { diff --git a/drivers/network/ndisuio/ndisuio.h b/drivers/network/ndisuio/ndisuio.h index c5976e5b1dc..13f6d919239 100644 --- a/drivers/network/ndisuio/ndisuio.h +++ b/drivers/network/ndisuio/ndisuio.h @@ -36,6 +36,9 @@ typedef struct _NDISUIO_ADAPTER_CONTEXT /* Receive packet list */ LIST_ENTRY PacketList; KEVENT PacketReadEvent; + + /* Mac options */ + ULONG MacOptions; /* Device name */ UNICODE_STRING DeviceName; diff --git a/drivers/network/ndisuio/protocol.c b/drivers/network/ndisuio/protocol.c index 9fb5116153c..4b8fe31413c 100644 --- a/drivers/network/ndisuio/protocol.c +++ b/drivers/network/ndisuio/protocol.c @@ -116,13 +116,15 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext, 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,27 +139,38 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext, } /* Transfer the packet data into our data buffer */ - NdisTransferData(&Status, - AdapterContext->BindingHandle, - MacReceiveContext, - 0, - PacketSize, - Packet, - &BytesTransferred); - if (Status == NDIS_STATUS_PENDING) + if (LookaheadBufferSize == PacketSize) { - KeWaitForSingleObject(&AdapterContext->AsyncEvent, - Executive, - KernelMode, - FALSE, - NULL); - Status = AdapterContext->AsyncStatus; + NdisCopyLookaheadData((PVOID)((PUCHAR)PacketBuffer + HeaderBufferSize), + LookAheadBuffer, + PacketSize, + AdapterContext->MacOptions); + BytesTransferred = PacketSize; } - if (Status != NDIS_STATUS_SUCCESS) + else { - DPRINT1("Failed to transfer data with status 0x%x\n", Status); - CleanupAndFreePacket(Packet, TRUE); - return NDIS_STATUS_NOT_ACCEPTED; + 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 */ @@ -177,7 +190,7 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext, /* Initialize the packet entry and copy in packet data */ PacketEntry->PacketLength = BytesTransferred + HeaderBufferSize; - RtlCopyMemory(&PacketEntry->PacketData[0], PacketBuffer, PacketEntry->PacketLength); + RtlCopyMemory(PacketEntry->PacketData, PacketBuffer, PacketEntry->PacketLength); /* Free the old buffer */ ExFreePool(PacketBuffer); @@ -312,6 +325,7 @@ BindAdapterByName(PNDIS_STRING DeviceName) 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 @@ BindAdapterByName(PNDIS_STRING DeviceName) 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,