- Merge the remaining portion of the wlan-bringup branch

- ReactOS now supports open and WEP encrypted networks (both ad-hoc and infrastructure) (WPA(2) will be supported later)
- Use the wlanconf tool to configure the WLAN adapter (after installing the XP driver for your WLAN adapter)
- "wlanconf -c <SSID>" connects to an infrastructure network. Adding the "-a" option connects to (or creates) an ad-hoc network. Adding "-w <WEP>" will enable WEP encryption using the supplied key. 
- "wlanconf -s" will scan and display a list of the surrounding networks and various attributes like signal strength, SSID, BSSID, network mode, and supported rates
- "wlanconf" will display the current WLAN configuration details if the adapter is connected
- The DHCP service will detect network changes and refresh its state accordingly when associating with a new wireless network

svn path=/trunk/; revision=55000
This commit is contained in:
Cameron Gutman 2012-01-17 23:11:28 +00:00
commit cd00d99985
22 changed files with 2961 additions and 3 deletions

View file

@ -14,3 +14,5 @@ if(NOT MSVC)
endif() endif()
add_subdirectory(tracert) add_subdirectory(tracert)
add_subdirectory(whois) add_subdirectory(whois)
add_subdirectory(wlanconf)

View file

@ -40,4 +40,7 @@
<directory name="whois"> <directory name="whois">
<xi:include href="whois/whois.rbuild" /> <xi:include href="whois/whois.rbuild" />
</directory> </directory>
<directory name="wlanconf">
<xi:include href="wlanconf/wlanconf.rbuild" />
</directory>
</group> </group>

View file

@ -0,0 +1,8 @@
include_directories(
BEFORE include
${REACTOS_SOURCE_DIR}/include/reactos/drivers/ndisuio)
add_executable(wlanconf wlanconf.c wlanconf.rc)
set_module_type(wlanconf win32cui)
add_importlibs(wlanconf msvcrt iphlpapi kernel32)
add_cd_file(TARGET wlanconf DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,969 @@
/*
* PROJECT: ReactOS WLAN command-line configuration utility
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/network/wlanconf/wlanconf.c
* PURPOSE: Allows WLAN configuration via the command prompt
* COPYRIGHT: Copyright 2012 Cameron Gutman (cameron.gutman@reactos.org)
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <ntddndis.h>
#include <nuiouser.h>
#include <iphlpapi.h>
BOOL bScan = FALSE;
BOOL bConnect = FALSE;
char* sSsid = NULL;
char* sWepKey = NULL;
BOOL bAdhoc = FALSE;
BOOL bDisconnect = FALSE;
DWORD DoFormatMessage(DWORD ErrorCode)
{
LPVOID lpMsgBuf;
DWORD RetVal;
if ((RetVal = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL )))
{
_tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
/* return number of TCHAR's stored in output buffer
* excluding '\0' - as FormatMessage does*/
return RetVal;
}
else
return 0;
}
HANDLE
OpenDriverHandle(VOID)
{
HANDLE hDriver;
DWORD dwBytesReturned;
BOOL bSuccess;
/* Open a handle to the NDISUIO driver */
hDriver = CreateFileW(NDISUIO_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDriver == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
/* Wait for binds */
bSuccess = DeviceIoControl(hDriver,
IOCTL_NDISUIO_BIND_WAIT,
NULL,
0,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
CloseHandle(hDriver);
return INVALID_HANDLE_VALUE;
}
return hDriver;
}
BOOL
IsWlanAdapter(HANDLE hAdapter)
{
BOOL bSuccess;
DWORD dwBytesReturned;
NDISUIO_QUERY_OID QueryOid;
/* WLAN drivers must support this OID */
QueryOid.Oid = OID_GEN_PHYSICAL_MEDIUM;
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_QUERY_OID_VALUE,
&QueryOid,
sizeof(QueryOid),
&QueryOid,
sizeof(QueryOid),
&dwBytesReturned,
NULL);
if (!bSuccess || *(PULONG)QueryOid.Data != NdisPhysicalMediumWirelessLan)
return FALSE;
return TRUE;
}
BOOL
OpenAdapterHandle(DWORD Index, HANDLE *hAdapter, IP_ADAPTER_INDEX_MAP *IpInfo)
{
HANDLE hDriver;
BOOL bSuccess;
DWORD dwBytesReturned;
DWORD QueryBindingSize = sizeof(NDISUIO_QUERY_BINDING) + (1024 * sizeof(WCHAR));
PNDISUIO_QUERY_BINDING QueryBinding;
DWORD dwStatus, dwSize, i;
PIP_INTERFACE_INFO InterfaceInfo = NULL;
/* Open the driver handle */
hDriver = OpenDriverHandle();
if (hDriver == INVALID_HANDLE_VALUE)
return FALSE;
/* Allocate the binding struct */
QueryBinding = HeapAlloc(GetProcessHeap(), 0, QueryBindingSize);
if (!QueryBinding)
{
CloseHandle(hDriver);
return FALSE;
}
/* Query the adapter binding information */
QueryBinding->BindingIndex = Index;
bSuccess = DeviceIoControl(hDriver,
IOCTL_NDISUIO_QUERY_BINDING,
QueryBinding,
QueryBindingSize,
QueryBinding,
QueryBindingSize,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, QueryBinding);
CloseHandle(hDriver);
return FALSE;
}
/* Bind to the adapter */
bSuccess = DeviceIoControl(hDriver,
IOCTL_NDISUIO_OPEN_DEVICE,
(PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset,
QueryBinding->DeviceNameLength,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, QueryBinding);
CloseHandle(hDriver);
return FALSE;
}
/* Get interface info from the IP helper */
dwSize = sizeof(IP_INTERFACE_INFO);
do {
if (InterfaceInfo) HeapFree(GetProcessHeap(), 0, InterfaceInfo);
InterfaceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(IP_INTERFACE_INFO));
if (!InterfaceInfo)
{
HeapFree(GetProcessHeap(), 0, QueryBinding);
CloseHandle(hDriver);
return FALSE;
}
dwStatus = GetInterfaceInfo(InterfaceInfo, &dwSize);
} while (dwStatus == ERROR_INSUFFICIENT_BUFFER);
if (dwStatus != NO_ERROR)
{
HeapFree(GetProcessHeap(), 0, QueryBinding);
HeapFree(GetProcessHeap(), 0, InterfaceInfo);
return FALSE;
}
for (i = 0; i < InterfaceInfo->NumAdapters; i++)
{
if (wcsstr((PWCHAR)((PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset),
InterfaceInfo->Adapter[i].Name))
{
*IpInfo = InterfaceInfo->Adapter[i];
*hAdapter = hDriver;
HeapFree(GetProcessHeap(), 0, QueryBinding);
HeapFree(GetProcessHeap(), 0, InterfaceInfo);
return TRUE;
}
}
HeapFree(GetProcessHeap(), 0, QueryBinding);
HeapFree(GetProcessHeap(), 0, InterfaceInfo);
CloseHandle(hDriver);
return FALSE;
}
/* Only works with the first adapter for now */
BOOL
OpenWlanAdapter(HANDLE *hAdapter, IP_ADAPTER_INDEX_MAP *IpInfo)
{
DWORD dwCurrentIndex;
for (dwCurrentIndex = 0; ; dwCurrentIndex++)
{
if (!OpenAdapterHandle(dwCurrentIndex, hAdapter, IpInfo))
break;
if (IsWlanAdapter(*hAdapter))
return TRUE;
else
CloseHandle(*hAdapter);
}
return FALSE;
}
BOOL
WlanDisconnect(HANDLE hAdapter, PIP_ADAPTER_INDEX_MAP IpInfo)
{
BOOL bSuccess;
DWORD dwBytesReturned;
NDISUIO_SET_OID SetOid;
/* Release this IP address */
IpReleaseAddress(IpInfo);
/* Disassociate from the AP */
SetOid.Oid = OID_802_11_DISASSOCIATE;
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
&SetOid,
sizeof(SetOid),
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
return FALSE;
_tprintf(_T("The operation completed successfully.\n"));
return TRUE;
}
static
UCHAR
CharToHex(CHAR Char)
{
Char = toupper(Char);
switch (Char)
{
case '0':
return 0x0;
case '1':
return 0x1;
case '2':
return 0x2;
case '3':
return 0x3;
case '4':
return 0x4;
case '5':
return 0x5;
case '6':
return 0x6;
case '7':
return 0x7;
case '8':
return 0x8;
case '9':
return 0x9;
case 'A':
return 0xA;
case 'B':
return 0xB;
case 'C':
return 0xC;
case 'D':
return 0xD;
case 'E':
return 0xE;
case 'F':
return 0xF;
default:
return 0;
}
}
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;
}
/* Copy the SSID to our internal buffer and terminate it */
RtlCopyMemory(SsidBuffer, SsidInfo->Ssid, SsidInfo->SsidLength);
SsidBuffer[SsidInfo->SsidLength] = 0;
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 (SsidInfo->SsidLength == 0 || !bSuccess)
{
_tprintf(_T("\nWLAN disconnected\n"));
HeapFree(GetProcessHeap(), 0, QueryOid);
return TRUE;
}
else
{
_tprintf(_T("\nCurrent wireless configuration information:\n\n"));
}
_tprintf(_T("SSID: %s\n"), SsidBuffer);
_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;
DWORD dwBytesReturned, SetOidSize;
PNDISUIO_SET_OID SetOid;
PNDIS_802_11_SSID Ssid;
DWORD i;
SetOidSize = sizeof(NDISUIO_SET_OID);
SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
if (!SetOid)
return FALSE;
/* Set the network mode */
SetOid->Oid = OID_802_11_INFRASTRUCTURE_MODE;
*(PULONG)SetOid->Data = bAdhoc ? Ndis802_11IBSS : Ndis802_11Infrastructure;
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, SetOid);
return FALSE;
}
/* Set the authentication mode */
SetOid->Oid = OID_802_11_AUTHENTICATION_MODE;
*(PULONG)SetOid->Data = sWepKey ? Ndis802_11AuthModeShared : Ndis802_11AuthModeOpen;
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, SetOid);
return FALSE;
}
if (sWepKey)
{
PNDIS_802_11_WEP WepData;
HeapFree(GetProcessHeap(), 0, SetOid);
SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) +
FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) +
(strlen(sWepKey) >> 1);
SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
if (!SetOid)
return FALSE;
/* Add the WEP key */
SetOid->Oid = OID_802_11_ADD_WEP;
WepData = (PNDIS_802_11_WEP)SetOid->Data;
WepData->KeyIndex = 0x80000000;
WepData->KeyLength = strlen(sWepKey) >> 1;
WepData->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + WepData->KeyLength;
/* Assemble the hex key */
i = 0;
while (sWepKey[i << 1] != '\0')
{
WepData->KeyMaterial[i] = CharToHex(sWepKey[i << 1]) << 4;
WepData->KeyMaterial[i] |= CharToHex(sWepKey[(i << 1) + 1]);
i++;
}
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, SetOid);
return FALSE;
}
}
/* Set the encryption status */
SetOid->Oid = OID_802_11_WEP_STATUS;
*(PULONG)SetOid->Data = sWepKey ? Ndis802_11WEPEnabled : Ndis802_11WEPDisabled;
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, SetOid);
return FALSE;
}
HeapFree(GetProcessHeap(), 0, SetOid);
SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS);
SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
if (!SetOid)
return FALSE;
/* Set the BSSID */
SetOid->Oid = OID_802_11_BSSID;
RtlFillMemory(SetOid->Data, sizeof(NDIS_802_11_MAC_ADDRESS), 0xFF);
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
{
HeapFree(GetProcessHeap(), 0, SetOid);
return FALSE;
}
HeapFree(GetProcessHeap(), 0, SetOid);
SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_SSID);
SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
if (!SetOid)
return FALSE;
/* Finally, set the SSID */
SetOid->Oid = OID_802_11_SSID;
Ssid = (PNDIS_802_11_SSID)SetOid->Data;
RtlCopyMemory(Ssid->Ssid, sSsid, strlen(sSsid));
Ssid->SsidLength = strlen(sSsid);
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
SetOid,
SetOidSize,
NULL,
0,
&dwBytesReturned,
NULL);
HeapFree(GetProcessHeap(), 0, SetOid);
if (!bSuccess)
return FALSE;
_tprintf(_T("The operation completed successfully.\n"));
return TRUE;
}
BOOL
WlanScan(HANDLE hAdapter)
{
BOOL bSuccess;
DWORD dwBytesReturned;
NDISUIO_SET_OID SetOid;
PNDISUIO_QUERY_OID QueryOid;
DWORD QueryOidSize;
PNDIS_802_11_BSSID_LIST BssidList;
DWORD i, j;
SetOid.Oid = OID_802_11_BSSID_LIST_SCAN;
/* Send the scan OID */
bSuccess = DeviceIoControl(hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
&SetOid,
sizeof(SetOid),
NULL,
0,
&dwBytesReturned,
NULL);
if (!bSuccess)
return FALSE;
/* Allocate space for 15 networks to be returned */
QueryOidSize = sizeof(NDISUIO_QUERY_OID) + (sizeof(NDIS_WLAN_BSSID) * 15);
QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
if (!QueryOid)
return FALSE;
QueryOid->Oid = OID_802_11_BSSID_LIST;
BssidList = (PNDIS_802_11_BSSID_LIST)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 (BssidList->NumberOfItems == 0)
{
_tprintf(_T("No networks found in range\n"));
}
else
{
PNDIS_WLAN_BSSID BssidInfo = BssidList->Bssid;
for (i = 0; i < BssidList->NumberOfItems; i++)
{
PNDIS_802_11_SSID Ssid = &BssidInfo->Ssid;
NDIS_802_11_RSSI Rssi = BssidInfo->Rssi;
NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType = BssidInfo->InfrastructureMode;
CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1];
UINT Rate;
/* SSID member is a non-null terminated ASCII string */
RtlCopyMemory(SsidBuffer, Ssid->Ssid, Ssid->SsidLength);
SsidBuffer[Ssid->SsidLength] = 0;
_tprintf(_T("\n"));
_tprintf(_T("SSID: %s\n"), SsidBuffer);
_tprintf(_T("BSSID: "));
for (j = 0; j < sizeof(NDIS_802_11_MAC_ADDRESS); j++)
{
UINT BssidData = BssidInfo->MacAddress[j];
_tprintf(_T("%.2x"), BssidData);
if (j != sizeof(NDIS_802_11_MAC_ADDRESS) - 1)
_tprintf(_T(":"));
}
_tprintf(_T("\n"));
_tprintf(_T("Encrypted: %s\n"
"Network Type: %s\n"
"RSSI: %i dBm\n"
"Supported Rates (Mbps): "),
BssidInfo->Privacy == 0 ? "No" : "Yes",
NetworkType == Ndis802_11IBSS ? "Adhoc" : "Infrastructure",
(int)Rssi);
for (j = 0; j < NDIS_802_11_LENGTH_RATES; j++)
{
Rate = BssidInfo->SupportedRates[j];
if (Rate != 0)
{
/* Bit 7 is the basic rates bit */
Rate = Rate & 0x7F;
/* SupportedRates are in units of .5 */
if (Rate & 0x01)
{
/* Bit 0 is set so we need to add 0.5 */
_tprintf(_T("%u.5 "), (Rate >> 1));
}
else
{
/* Bit 0 is clear so just print the conversion */
_tprintf(_T("%u "), (Rate >> 1));
}
}
}
_tprintf(_T("\n"));
/* Move to the next entry */
BssidInfo = (PNDIS_WLAN_BSSID)((PUCHAR)BssidInfo + BssidInfo->Length);
}
}
HeapFree(GetProcessHeap(), 0, QueryOid);
return bSuccess;
}
VOID Usage()
{
_tprintf(_T("\nConfigures a WLAN adapter.\n\n"
"WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n"
" -c SSID Connects to a supplied SSID.\n"
" -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\n"
" Passing no parameters will print information about the current WLAN connection\n"));
}
BOOL ParseCmdline(int argc, char* argv[])
{
INT i;
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 's':
bScan = TRUE;
break;
case 'd':
bDisconnect = TRUE;
break;
case 'c':
if (i == argc - 1)
{
Usage();
return FALSE;
}
bConnect = TRUE;
sSsid = argv[++i];
break;
case 'w':
if (i == argc - 1)
{
Usage();
return FALSE;
}
sWepKey = argv[++i];
break;
case 'a':
bAdhoc = TRUE;
break;
default :
Usage();
return FALSE;
}
}
else
{
Usage();
return FALSE;
}
}
return TRUE;
}
int main(int argc, char* argv[])
{
HANDLE hAdapter;
IP_ADAPTER_INDEX_MAP IpInfo;
if (!ParseCmdline(argc, argv))
return -1;
if (!OpenWlanAdapter(&hAdapter, &IpInfo))
{
_tprintf(_T("Unable to find a WLAN adapter on the system\n"));
return -1;
}
if (bScan)
{
if (!WlanScan(hAdapter))
{
DoFormatMessage(GetLastError());
CloseHandle(hAdapter);
return -1;
}
}
else if (bDisconnect)
{
if (!WlanDisconnect(hAdapter, &IpInfo))
{
DoFormatMessage(GetLastError());
CloseHandle(hAdapter);
return -1;
}
}
else if (bConnect)
{
if (!WlanConnect(hAdapter))
{
DoFormatMessage(GetLastError());
CloseHandle(hAdapter);
return -1;
}
}
else
{
if (!WlanPrintCurrentStatus(hAdapter))
{
DoFormatMessage(GetLastError());
CloseHandle(hAdapter);
return -1;
}
}
CloseHandle(hAdapter);
return 0;
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="wlanconf" type="win32cui" installbase="system32" installname="wlanconf.exe">
<include base="wlanconf">.</include>
<include base="ReactOS">include/reactos/drivers/ndisuio</include>
<library>iphlpapi</library>
<file>wlanconf.c</file>
<file>wlanconf.rc</file>
</module>

View file

@ -0,0 +1,7 @@
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS WLAN Configuration Tool\0"
#define REACTOS_STR_INTERNAL_NAME "wlanconf\0"
#define REACTOS_STR_ORIGINAL_FILENAME "wlanconf.exe\0"
#define REACTOS_STR_ORIGINAL_COPYRIGHT "Cameron Gutman (cameron.gutman@reactos.org)\0"
#include <reactos/version.rc>

View file

@ -1399,6 +1399,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ImagePath",0x00020000,"system
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001
; NDIS User I/O driver (FIXME: Should be installed via INF and started on demand)
HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Group",0x00000000,"NDIS"
HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","ImagePath",0x00020000,"system32\drivers\ndisuio.sys"
HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Start",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Type",0x00010001,0x00000001
; Packet driver ; Packet driver
HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Group",0x00000000,"PNP_TDI" HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Group",0x00000000,"PNP_TDI"
@ -1629,7 +1636,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ErrorControl",0x00010001,0x000
HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Group",0x00000000,"TDI" HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Group",0x00000000,"TDI"
HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ImagePath",0x00020000,"%SystemRoot%\system32\wlansvc.exe" HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ImagePath",0x00020000,"%SystemRoot%\system32\wlansvc.exe"
HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ObjectName",0x00000000,"LocalSystem" HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","ObjectName",0x00000000,"LocalSystem"
HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Start",0x00010001,0x00000003 HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Start",0x00010001,0x00000002
HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Type",0x00010001,0x00000110 HKLM,"SYSTEM\CurrentControlSet\Services\WlanSvc","Type",0x00010001,0x00000110
; Simple TCP services ; Simple TCP services

View file

@ -76,6 +76,7 @@ base\applications\network\route\route.exe 1
base\applications\network\telnet\telnet.exe 1 base\applications\network\telnet\telnet.exe 1
base\applications\network\tracert\tracert.exe 1 base\applications\network\tracert\tracert.exe 1
base\applications\network\whois\whois.exe 1 base\applications\network\whois\whois.exe 1
base\applications\network\wlanconf\wlanconf.exe 1
base\applications\notepad\notepad.exe 1 base\applications\notepad\notepad.exe 1
base\applications\rapps\rapps.exe 1 base\applications\rapps\rapps.exe 1
base\applications\regedit\regedit.exe 4 base\applications\regedit\regedit.exe 4
@ -532,6 +533,7 @@ drivers\network\tcpip\tcpip.sys 2
drivers\network\tdi\tdi.sys 2 drivers\network\tdi\tdi.sys 2
drivers\network\dd\ne2000\ne2000.sys 2 drivers\network\dd\ne2000\ne2000.sys 2
drivers\network\dd\pcnet\pcnet.sys 2 drivers\network\dd\pcnet\pcnet.sys 2
drivers\network\ndisuio\ndisuio.sys 2
drivers\serial\serenum\serenum.sys 2 drivers\serial\serenum\serenum.sys 2
drivers\serial\serial\serial.sys 2 drivers\serial\serial\serial.sys 2

View file

@ -2,5 +2,6 @@
add_subdirectory(afd) add_subdirectory(afd)
add_subdirectory(dd) add_subdirectory(dd)
add_subdirectory(ndis) add_subdirectory(ndis)
add_subdirectory(ndisuio)
add_subdirectory(tcpip) add_subdirectory(tcpip)
add_subdirectory(tdi) add_subdirectory(tdi)

View file

@ -10,6 +10,9 @@
<directory name="ndis"> <directory name="ndis">
<xi:include href="ndis/ndis.rbuild" /> <xi:include href="ndis/ndis.rbuild" />
</directory> </directory>
<directory name="ndisuio">
<xi:include href="ndisuio/ndisuio.rbuild" />
</directory>
<directory name="tcpip"> <directory name="tcpip">
<xi:include href="tcpip/tcpip.rbuild" /> <xi:include href="tcpip/tcpip.rbuild" />
</directory> </directory>

View file

@ -0,0 +1,25 @@
add_definitions(
-DNDIS50
-D_NTDRIVER_)
include_directories(
BEFORE include
${REACTOS_SOURCE_DIR}/include/reactos/drivers/ndisuio)
list(APPEND SOURCE
createclose.c
ioctl.c
main.c
misc.c
protocol.c
readwrite.c
ndisuio.rc)
add_library(ndisuio SHARED ${SOURCE})
set_module_type(ndisuio kernelmodedriver)
add_importlibs(ndisuio ndis ntoskrnl hal)
add_pch(ndisuio ndisuio.h)
add_cd_file(TARGET ndisuio DESTINATION reactos/system32/drivers FOR all)

View file

@ -0,0 +1,69 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: createclose.c
* PURPOSE: IRP_MJ_CREATE and IRP_MJ_CLOSE handling
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
//#define NDEBUG
#include <debug.h>
NTSTATUS
NTAPI
NduDispatchCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ASSERT(DeviceObject == GlobalDeviceObject);
DPRINT("Created file object 0x%x\n", IrpSp->FileObject);
/* This is associated with an adapter during IOCTL_NDISUIO_OPEN_(WRITE_)DEVICE */
IrpSp->FileObject->FsContext = NULL;
IrpSp->FileObject->FsContext2 = NULL;
/* Completed successfully */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Return success */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
NduDispatchClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
ASSERT(DeviceObject == GlobalDeviceObject);
DPRINT("Closing file object 0x%x\n", IrpSp->FileObject);
/* Check if this handle was ever associated with an adapter */
if (AdapterContext != NULL)
{
ASSERT(OpenEntry != NULL);
DPRINT("Removing binding to adapter %wZ\n", &AdapterContext->DeviceName);
/* Call the our helper */
DereferenceAdapterContextWithOpenEntry(AdapterContext, OpenEntry);
}
/* Completed */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Return success */
return STATUS_SUCCESS;
}

View file

@ -0,0 +1,525 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: ioctl.c
* PURPOSE: IOCTL handling
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
//#define NDEBUG
#include <debug.h>
static
NTSTATUS
WaitForBind(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
/* I've seen several code samples that use this IOCTL but there's
* no official documentation on it. I'm just implementing it as a no-op
* right now because I don't see any reason we need it. We handle an open
* and bind just fine with IRP_MJ_CREATE and IOCTL_NDISUIO_OPEN_DEVICE */
DPRINT("Wait for bind complete\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static
NTSTATUS
QueryBinding(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = NULL;
PNDISUIO_QUERY_BINDING QueryBinding = Irp->AssociatedIrp.SystemBuffer;
ULONG BindingLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
NTSTATUS Status;
PLIST_ENTRY CurrentEntry;
KIRQL OldIrql;
ULONG i;
ULONG BytesCopied = 0;
if (QueryBinding && BindingLength >= sizeof(NDISUIO_QUERY_BINDING))
{
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
i = 0;
CurrentEntry = GlobalAdapterList.Flink;
while (CurrentEntry != &GlobalAdapterList)
{
if (i == QueryBinding->BindingIndex)
{
AdapterContext = CONTAINING_RECORD(CurrentEntry, NDISUIO_ADAPTER_CONTEXT, ListEntry);
break;
}
i++;
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
if (AdapterContext)
{
DPRINT("Query binding for index %d is adapter %wZ\n", i, &AdapterContext->DeviceName);
BytesCopied = sizeof(NDISUIO_QUERY_BINDING);
if (AdapterContext->DeviceName.Length <= BindingLength - BytesCopied)
{
QueryBinding->DeviceNameOffset = BytesCopied;
QueryBinding->DeviceNameLength = AdapterContext->DeviceName.Length;
RtlCopyMemory((PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset,
AdapterContext->DeviceName.Buffer,
QueryBinding->DeviceNameLength);
BytesCopied += AdapterContext->DeviceName.Length;
/* FIXME: Copy description too */
QueryBinding->DeviceDescrOffset = BytesCopied;
QueryBinding->DeviceDescrLength = 0;
/* Successful */
Status = STATUS_SUCCESS;
}
else
{
/* Not enough buffer space */
Status = STATUS_BUFFER_TOO_SMALL;
}
}
else
{
/* Invalid index */
Status = STATUS_NO_MORE_ENTRIES;
}
}
else
{
/* Invalid parameters */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesCopied;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
#if 0
static
NTSTATUS
CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_PACKET_ENTRY PacketEntry;
NTSTATUS Status;
/* Indicate a 0-byte packet on the queue so one read returns 0 */
PacketEntry = ExAllocatePool(PagedPool, sizeof(NDISUIO_PACKET_ENTRY));
if (PacketEntry)
{
PacketEntry->PacketLength = 0;
ExInterlockedInsertHeadList(&AdapterContext->PacketList,
&PacketEntry->ListEntry,
&AdapterContext->Spinlock);
KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_NO_MEMORY;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
#endif
static
NTSTATUS
SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_SET_OID SetOidRequest;
NDIS_REQUEST Request;
ULONG RequestLength;
NDIS_STATUS Status;
Irp->IoStatus.Information = 0;
SetOidRequest = Irp->AssociatedIrp.SystemBuffer;
RequestLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (SetOidRequest && RequestLength >= sizeof(NDIS_OID))
{
/* Setup the NDIS request */
Request.RequestType = NdisRequestSetInformation;
Request.DATA.SET_INFORMATION.Oid = SetOidRequest->Oid;
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);
/* Dispatch the request */
NdisRequest(&Status,
AdapterContext->BindingHandle,
&Request);
/* Wait for the request */
if (Status == NDIS_STATUS_PENDING)
{
KeWaitForSingleObject(&AdapterContext->AsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
Status = AdapterContext->AsyncStatus;
}
/* Return the bytes read */
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
{
/* Bad parameters */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
static
NTSTATUS
QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_QUERY_OID QueryOidRequest;
NDIS_REQUEST Request;
ULONG RequestLength;
NDIS_STATUS Status;
Irp->IoStatus.Information = 0;
QueryOidRequest = Irp->AssociatedIrp.SystemBuffer;
RequestLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (QueryOidRequest && RequestLength >= sizeof(NDIS_OID))
{
/* Setup the NDIS request */
Request.RequestType = NdisRequestQueryInformation;
Request.DATA.QUERY_INFORMATION.Oid = QueryOidRequest->Oid;
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 */
NdisRequest(&Status,
AdapterContext->BindingHandle,
&Request);
/* Wait for the request */
if (Status == NDIS_STATUS_PENDING)
{
KeWaitForSingleObject(&AdapterContext->AsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
Status = AdapterContext->AsyncStatus;
}
/* Return the bytes written */
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
{
/* Bad parameters */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
static
NTSTATUS
OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
UNICODE_STRING DeviceName;
ULONG NameLength;
NTSTATUS Status;
PNDISUIO_ADAPTER_CONTEXT AdapterContext;
PNDISUIO_OPEN_ENTRY OpenEntry;
KIRQL OldIrql;
NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (NameLength != 0)
{
DeviceName.MaximumLength = DeviceName.Length = NameLength;
DeviceName.Buffer = Irp->AssociatedIrp.SystemBuffer;
/* Check if this already has a context */
AdapterContext = FindAdapterContextByName(&DeviceName);
if (AdapterContext != NULL)
{
DPRINT("Binding file object 0x%x to device %wZ\n", FileObject, &AdapterContext->DeviceName);
/* Reference the adapter context */
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
if (AdapterContext->OpenCount != 0)
{
/* An open for read-write is exclusive,
* so we can't have any other open handles */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Add a reference */
ReferenceAdapterContext(AdapterContext);
Status = STATUS_SUCCESS;
}
}
else
{
/* Invalid device name */
Status = STATUS_INVALID_PARAMETER;
}
/* Check that the bind succeeded */
if (NT_SUCCESS(Status))
{
OpenEntry = ExAllocatePool(NonPagedPool, sizeof(*OpenEntry));
if (OpenEntry)
{
/* Set the file object pointer */
OpenEntry->FileObject = FileObject;
/* Set the permissions */
OpenEntry->WriteOnly = FALSE;
/* Associate this FO with the adapter */
FileObject->FsContext = AdapterContext;
FileObject->FsContext2 = OpenEntry;
/* Add it to the adapter's list */
InsertTailList(&AdapterContext->OpenEntryList,
&OpenEntry->ListEntry);
/* Success */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
Status = STATUS_SUCCESS;
}
else
{
/* Remove the reference we added */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
DereferenceAdapterContextWithOpenEntry(AdapterContext, NULL);
Status = STATUS_NO_MEMORY;
}
}
}
else
{
/* Invalid device name */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
#if 0
static
NTSTATUS
OpenDeviceWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
UNICODE_STRING DeviceName;
ULONG NameLength;
NTSTATUS Status;
PNDISUIO_ADAPTER_CONTEXT AdapterContext;
PNDISUIO_OPEN_ENTRY OpenEntry;
KIRQL OldIrql;
NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (NameLength != 0)
{
DeviceName.MaximumLength = DeviceName.Length = NameLength;
DeviceName.Buffer = Irp->AssociatedIrp.SystemBuffer;
/* Check if this already has a context */
AdapterContext = FindAdapterContextByName(&DeviceName);
if (AdapterContext != NULL)
{
/* Reference the adapter context */
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
ReferenceAdapterContext(AdapterContext);
Status = STATUS_SUCCESS;
}
else
{
/* Invalid device name */
Status = STATUS_INVALID_PARAMETER;
}
/* Check that the bind succeeded */
if (NT_SUCCESS(Status))
{
OpenEntry = ExAllocatePool(NonPagedPool, sizeof(*OpenEntry));
if (OpenEntry)
{
/* Set the file object pointer */
OpenEntry->FileObject = FileObject;
/* Associate this FO with the adapter */
FileObject->FsContext = AdapterContext;
FileObject->FsContext2 = OpenEntry;
/* Set permissions */
OpenEntry->WriteOnly = TRUE;
/* Add it to the adapter's list */
InsertTailList(&AdapterContext->OpenEntryList,
&OpenEntry->ListEntry);
/* Success */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
Status = STATUS_SUCCESS;
}
else
{
/* Remove the reference we added */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
DereferenceAdapterContext(AdapterContext, NULL);
Status = STATUS_NO_MEMORY;
}
}
}
else
{
/* Invalid device name */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
#endif
NTSTATUS
NTAPI
NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_OPEN_ENTRY OpenEntry;
ASSERT(DeviceObject == GlobalDeviceObject);
/* Handle open IOCTLs first */
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_NDISUIO_OPEN_DEVICE:
return OpenDeviceReadWrite(Irp, IrpSp);
#if 0
case IOCTL_NDISUIO_OPEN_WRITE_DEVICE:
return OpenDeviceWrite(Irp, IrpSp);
#endif
case IOCTL_NDISUIO_BIND_WAIT:
return WaitForBind(Irp, IrpSp);
case IOCTL_NDISUIO_QUERY_BINDING:
return QueryBinding(Irp, IrpSp);
default:
/* Fail if this file object has no adapter associated */
if (IrpSp->FileObject->FsContext == NULL)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
/* Now handle write IOCTLs */
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_NDISUIO_SET_OID_VALUE:
return SetAdapterOid(Irp, IrpSp);
default:
/* Check that we have read permissions */
OpenEntry = IrpSp->FileObject->FsContext2;
if (OpenEntry->WriteOnly)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
#if 0
case IOCTL_CANCEL_READ:
return CancelPacketRead(Irp, IrpSp);
#endif
case IOCTL_NDISUIO_QUERY_OID_VALUE:
return QueryAdapterOid(Irp, IrpSp);
default:
DPRINT1("Unimplemented\n");
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
}
}
break;
}
}

View file

@ -0,0 +1,104 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: main.c
* PURPOSE: Driver entry point and protocol initialization
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
//#define NDEBUG
#include <debug.h>
PDEVICE_OBJECT GlobalDeviceObject;
NDIS_HANDLE GlobalProtocolHandle;
KSPIN_LOCK GlobalAdapterListLock;
LIST_ENTRY GlobalAdapterList;
NDIS_STRING ProtocolName = RTL_CONSTANT_STRING(L"NDISUIO");
VOID NTAPI NduUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT("NDISUIO: Unloaded\n");
}
NTSTATUS
NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
NDIS_STATUS Status;
NDIS_PROTOCOL_CHARACTERISTICS Chars;
UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_NT);
UNICODE_STRING DosDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_DOS);
/* Setup dispatch functions */
DriverObject->MajorFunction[IRP_MJ_CREATE] = NduDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NduDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NduDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_READ] = NduDispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NduDispatchWrite;
DriverObject->DriverUnload = NduUnload;
/* Setup global state */
InitializeListHead(&GlobalAdapterList);
KeInitializeSpinLock(&GlobalAdapterListLock);
/* Create the NDISUIO device object */
Status = IoCreateDevice(DriverObject,
0,
&NtDeviceName,
FILE_DEVICE_SECURE_OPEN,
0,
FALSE,
&GlobalDeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create device object with status 0x%x\n", Status);
return Status;
}
/* Create a symbolic link into the DOS devices namespace */
Status = IoCreateSymbolicLink(&DosDeviceName, &NtDeviceName);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create symbolic link with status 0x%x\n", Status);
IoDeleteDevice(GlobalDeviceObject);
return Status;
}
/* Register the protocol with NDIS */
RtlZeroMemory(&Chars, sizeof(Chars));
Chars.MajorNdisVersion = NDIS_MAJOR_VERSION;
Chars.MinorNdisVersion = NDIS_MINOR_VERSION;
Chars.OpenAdapterCompleteHandler = NduOpenAdapterComplete;
Chars.CloseAdapterCompleteHandler = NduCloseAdapterComplete;
Chars.SendCompleteHandler = NduSendComplete;
Chars.TransferDataCompleteHandler = NduTransferDataComplete;
Chars.ResetCompleteHandler = NduResetComplete;
Chars.RequestCompleteHandler = NduRequestComplete;
Chars.ReceiveHandler = NduReceive;
Chars.ReceiveCompleteHandler = NduReceiveComplete;
Chars.StatusHandler = NduStatus;
Chars.StatusCompleteHandler = NduStatusComplete;
Chars.Name = ProtocolName;
Chars.BindAdapterHandler = NduBindAdapter;
Chars.UnbindAdapterHandler = NduUnbindAdapter;
NdisRegisterProtocol(&Status,
&GlobalProtocolHandle,
&Chars,
sizeof(Chars));
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to register protocol with status 0x%x\n", Status);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(GlobalDeviceObject);
return Status;
}
DPRINT("NDISUIO: Loaded\n");
return STATUS_SUCCESS;
}

View file

@ -0,0 +1,176 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: misc.c
* PURPOSE: Helper functions
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
#define NDEBUG
#include <debug.h>
NDIS_STATUS
AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDIS_PACKET Packet,
PVOID Buffer,
ULONG BufferSize,
BOOLEAN Front)
{
NDIS_STATUS Status;
PNDIS_BUFFER NdisBuffer;
/* Allocate the NDIS buffer mapping the pool */
NdisAllocateBuffer(&Status,
&NdisBuffer,
AdapterContext->BufferPoolHandle,
Buffer,
BufferSize);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("No free buffer descriptors\n");
return Status;
}
if (Front)
{
/* Chain the buffer to front */
NdisChainBufferAtFront(Packet, NdisBuffer);
}
else
{
/* Chain the buffer to back */
NdisChainBufferAtBack(Packet, NdisBuffer);
}
/* Return success */
return NDIS_STATUS_SUCCESS;
}
PNDIS_PACKET
CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PVOID Buffer,
ULONG BufferSize)
{
PNDIS_PACKET Packet;
NDIS_STATUS Status;
/* Allocate a packet descriptor */
NdisAllocatePacket(&Status,
&Packet,
AdapterContext->PacketPoolHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("No free packet descriptors\n");
return NULL;
}
/* Use the helper to chain the buffer */
Status = AllocateAndChainBuffer(AdapterContext, Packet,
Buffer, BufferSize, TRUE);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreePacket(Packet);
return NULL;
}
/* Return the packet */
return Packet;
}
VOID
CleanupAndFreePacket(PNDIS_PACKET Packet, BOOLEAN FreePool)
{
PNDIS_BUFFER Buffer;
PVOID Data;
ULONG Length;
/* Free each buffer and its backing pool memory */
while (TRUE)
{
/* Unchain each buffer */
NdisUnchainBufferAtFront(Packet, &Buffer);
if (!Buffer)
break;
/* Get the backing memory */
NdisQueryBuffer(Buffer, &Data, &Length);
/* Free the buffer */
NdisFreeBuffer(Buffer);
if (FreePool)
{
/* Free the backing memory */
ExFreePool(Data);
}
}
/* Free the packet descriptor */
NdisFreePacket(Packet);
}
PNDISUIO_ADAPTER_CONTEXT
FindAdapterContextByName(PNDIS_STRING DeviceName)
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PNDISUIO_ADAPTER_CONTEXT AdapterContext;
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
CurrentEntry = GlobalAdapterList.Flink;
while (CurrentEntry != &GlobalAdapterList)
{
AdapterContext = CONTAINING_RECORD(CurrentEntry, NDISUIO_ADAPTER_CONTEXT, ListEntry);
/* Check if the device name matches */
if (RtlEqualUnicodeString(&AdapterContext->DeviceName, DeviceName, TRUE))
{
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
return AdapterContext;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
return NULL;
}
VOID
ReferenceAdapterContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
{
/* Increment the open count */
AdapterContext->OpenCount++;
}
VOID
DereferenceAdapterContextWithOpenEntry(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDISUIO_OPEN_ENTRY OpenEntry)
{
KIRQL OldIrql;
/* Lock the adapter context */
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
/* Decrement the open count */
AdapterContext->OpenCount--;
/* Cleanup the open entry if we were given one */
if (OpenEntry != NULL)
{
/* Remove the open entry */
RemoveEntryList(&OpenEntry->ListEntry);
/* Invalidate the FO */
OpenEntry->FileObject->FsContext = NULL;
OpenEntry->FileObject->FsContext2 = NULL;
/* Free the open entry */
ExFreePool(OpenEntry);
}
/* Release the adapter context lock */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
}

View file

@ -0,0 +1,210 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: ndisuio.h
* PURPOSE: NDISUIO definitions
*/
#ifndef __NDISUIO_H
#define __NDISUIO_H
#include <wdm.h>
#include <ndis.h>
#include <nuiouser.h>
extern PDEVICE_OBJECT GlobalDeviceObject;
extern NDIS_HANDLE GlobalProtocolHandle;
extern LIST_ENTRY GlobalAdapterList;
extern KSPIN_LOCK GlobalAdapterListLock;
typedef struct _NDISUIO_ADAPTER_CONTEXT
{
/* Asynchronous completion */
NDIS_STATUS AsyncStatus;
KEVENT AsyncEvent;
/* NDIS binding information */
NDIS_HANDLE BindingHandle;
/* Reference count information */
ULONG OpenCount;
LIST_ENTRY OpenEntryList;
/* NDIS pools */
NDIS_HANDLE PacketPoolHandle;
NDIS_HANDLE BufferPoolHandle;
/* Receive packet list */
LIST_ENTRY PacketList;
KEVENT PacketReadEvent;
/* Mac options */
ULONG MacOptions;
/* Device name */
UNICODE_STRING DeviceName;
/* Global list entry */
LIST_ENTRY ListEntry;
/* Spin lock */
KSPIN_LOCK Spinlock;
} NDISUIO_ADAPTER_CONTEXT, *PNDISUIO_ADAPTER_CONTEXT;
typedef struct _NDISUIO_OPEN_ENTRY
{
/* File object */
PFILE_OBJECT FileObject;
/* Tracks how this adapter was opened (write-only or read-write) */
BOOLEAN WriteOnly;
/* List entry */
LIST_ENTRY ListEntry;
} NDISUIO_OPEN_ENTRY, *PNDISUIO_OPEN_ENTRY;
typedef struct _NDISUIO_PACKET_ENTRY
{
/* Length of data at the end of the struct */
ULONG PacketLength;
/* Entry on the packet list */
LIST_ENTRY ListEntry;
/* Packet data */
UCHAR PacketData[1];
} NDISUIO_PACKET_ENTRY, *PNDISUIO_PACKET_ENTRY;
/* NDIS version info */
#define NDIS_MAJOR_VERSION 5
#define NDIS_MINOR_VERSION 0
/* createclose.c */
NTSTATUS
NTAPI
NduDispatchCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS
NTAPI
NduDispatchClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* ioctl.c */
NTSTATUS
NTAPI
NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* misc.c */
NDIS_STATUS
AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDIS_PACKET Packet,
PVOID Buffer,
ULONG BufferSize,
BOOLEAN Front);
PNDIS_PACKET
CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PVOID Buffer,
ULONG BufferSize);
VOID
CleanupAndFreePacket(PNDIS_PACKET Packet,
BOOLEAN FreePool);
PNDISUIO_ADAPTER_CONTEXT
FindAdapterContextByName(PNDIS_STRING DeviceName);
VOID
ReferenceAdapterContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext);
VOID
DereferenceAdapterContextWithOpenEntry(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDISUIO_OPEN_ENTRY OpenEntry);
/* protocol.c */
VOID
NTAPI
NduOpenAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status,
NDIS_STATUS OpenStatus);
VOID
NTAPI
NduCloseAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status);
VOID
NTAPI
NduSendComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status);
VOID
NTAPI
NduTransferDataComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred);
VOID
NTAPI
NduResetComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status);
VOID
NTAPI
NduRequestComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_REQUEST NdisRequest,
NDIS_STATUS Status);
NDIS_STATUS
NTAPI
NduReceive(NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE MacReceiveContext,
PVOID HeaderBuffer,
UINT HeaderBufferSize,
PVOID LookAheadBuffer,
UINT LookaheadBufferSize,
UINT PacketSize);
VOID
NTAPI
NduReceiveComplete(NDIS_HANDLE ProtocolBindingContext);
VOID
NTAPI
NduStatus(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS GeneralStatus,
PVOID StatusBuffer,
UINT StatusBufferSize);
VOID
NTAPI
NduStatusComplete(NDIS_HANDLE ProtocolBindingContext);
VOID
NTAPI
NduBindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE BindContext,
PNDIS_STRING DeviceName,
PVOID SystemSpecific1,
PVOID SystemSpecific2);
VOID
NTAPI
NduUnbindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE UnbindContext);
/* readwrite.c */
NTSTATUS
NTAPI
NduDispatchRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS
NTAPI
NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
#endif /* __NDISUIO_H */

View file

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="ndisuio" type="kernelmodedriver" installbase="system32/drivers" installname="ndisuio.sys">
<include base="ndisuio">.</include>
<include base="ReactOS">include/reactos/drivers/ndisuio</include>
<define name="NDIS50" />
<define name="_NTDRIVER_" />
<library>ndis</library>
<library>ntoskrnl</library>
<library>hal</library>
<pch>ndisuio.h</pch>
<file>createclose.c</file>
<file>ioctl.c</file>
<file>main.c</file>
<file>misc.c</file>
<file>protocol.c</file>
<file>readwrite.c</file>
<file>ndisuio.rc</file>
</module>

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "NDIS User-Mode I/O Protocol Driver\0"
#define REACTOS_STR_INTERNAL_NAME "ndisuio\0"
#define REACTOS_STR_ORIGINAL_FILENAME "ndisuio.sys\0"
#include <reactos/version.rc>

View file

@ -0,0 +1,496 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: protocol.c
* PURPOSE: Protocol stuff
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
#define NDEBUG
#include <debug.h>
VOID
NTAPI
NduOpenAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status,
NDIS_STATUS OpenStatus)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter open completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
VOID
NTAPI
NduCloseAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter close completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
VOID
NTAPI
NduSendComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter send completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
VOID
NTAPI
NduTransferDataComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter transfer completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
VOID
NTAPI
NduResetComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter reset completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
VOID
NTAPI
NduRequestComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_REQUEST NdisRequest,
NDIS_STATUS Status)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
DPRINT("Asynchronous adapter request completed\n");
/* Store the final status and signal the event */
AdapterContext->AsyncStatus = Status;
KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
}
NDIS_STATUS
NTAPI
NduReceive(NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE MacReceiveContext,
PVOID HeaderBuffer,
UINT HeaderBufferSize,
PVOID LookAheadBuffer,
UINT LookaheadBufferSize,
UINT PacketSize)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
PNDISUIO_PACKET_ENTRY PacketEntry;
PVOID PacketBuffer;
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 + HeaderBufferSize);
if (!PacketBuffer)
return NDIS_STATUS_NOT_ACCEPTED;
/* Allocate the packet descriptor and buffer */
Packet = CreatePacketFromPoolBuffer(AdapterContext,
(PUCHAR)PacketBuffer + HeaderBufferSize,
PacketSize);
if (!Packet)
{
ExFreePool(PacketBuffer);
return NDIS_STATUS_NOT_ACCEPTED;
}
/* Transfer the packet data into our data buffer */
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,
Executive,
KernelMode,
FALSE,
NULL);
Status = AdapterContext->AsyncStatus;
}
/* Free the context */
ExFreePool(AdapterContext);
return Status;
}
static
NDIS_STATUS
BindAdapterByName(PNDIS_STRING DeviceName)
{
NDIS_STATUS OpenErrorStatus;
PNDISUIO_ADAPTER_CONTEXT AdapterContext;
NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3};
UINT SelectedMedium;
NDIS_STATUS Status;
NDIS_REQUEST Request;
/* Allocate the adapter context */
AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
if (!AdapterContext)
{
return NDIS_STATUS_RESOURCES;
}
/* Set up the adapter context */
RtlZeroMemory(AdapterContext, sizeof(*AdapterContext));
KeInitializeEvent(&AdapterContext->AsyncEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&AdapterContext->PacketReadEvent, SynchronizationEvent, FALSE);
KeInitializeSpinLock(&AdapterContext->Spinlock);
InitializeListHead(&AdapterContext->PacketList);
InitializeListHead(&AdapterContext->OpenEntryList);
AdapterContext->OpenCount = 0;
AdapterContext->DeviceName.Length =
AdapterContext->DeviceName.MaximumLength = DeviceName->Length;
AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length);
if (!AdapterContext->DeviceName.Buffer)
{
ExFreePool(AdapterContext);
return NDIS_STATUS_RESOURCES;
}
/* Copy the device name into the adapter context */
RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName);
/* Create the buffer pool */
NdisAllocateBufferPool(&Status,
&AdapterContext->BufferPoolHandle,
50);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
return Status;
}
/* Create the packet pool */
NdisAllocatePacketPool(&Status,
&AdapterContext->PacketPoolHandle,
25,
PROTOCOL_RESERVED_SIZE_IN_PACKET);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
return Status;
}
/* Send the open request */
NdisOpenAdapter(&Status,
&OpenErrorStatus,
&AdapterContext->BindingHandle,
&SelectedMedium,
SupportedMedia,
1,
GlobalProtocolHandle,
AdapterContext,
DeviceName,
0,
NULL);
/* Wait for a pending open */
if (Status == NDIS_STATUS_PENDING)
{
KeWaitForSingleObject(&AdapterContext->AsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
Status = AdapterContext->AsyncStatus;
}
/* Check the final status */
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
NdisFreePacketPool(AdapterContext->PacketPoolHandle);
NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
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,
&GlobalAdapterListLock);
return STATUS_SUCCESS;
}
VOID
NTAPI
NduBindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE BindContext,
PNDIS_STRING DeviceName,
PVOID SystemSpecific1,
PVOID SystemSpecific2)
{
/* Use our helper function to create a context for this adapter */
*Status = BindAdapterByName(DeviceName);
}
VOID
NTAPI
NduUnbindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE UnbindContext)
{
/* This is forced unbind. UnbindAdapterByContext() will take care of
* invalidating file handles pointer to this adapter for us */
*Status = UnbindAdapterByContext(ProtocolBindingContext);
}

View file

@ -0,0 +1,209 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS User I/O driver
* FILE: readwrite.c
* PURPOSE: Handles IRP_MJ_READ and IRP_MJ_WRITE
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
*/
#include "ndisuio.h"
#define NDEBUG
#include <debug.h>
static
VOID
NTAPI
ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_PACKET_ENTRY PacketEntry;
/* Release the cancel spin lock */
IoReleaseCancelSpinLock(Irp->CancelIrql);
/* Indicate a 0-byte packet on the queue to cancel the read */
PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY));
if (PacketEntry)
{
PacketEntry->PacketLength = 0;
ExInterlockedInsertHeadList(&AdapterContext->PacketList,
&PacketEntry->ListEntry,
&AdapterContext->Spinlock);
KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE);
}
}
NTSTATUS
NTAPI
NduDispatchRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
KIRQL OldIrql, OldCancelIrql;
NTSTATUS Status;
PLIST_ENTRY ListEntry;
PNDISUIO_PACKET_ENTRY PacketEntry = NULL;
ULONG BytesCopied = 0;
ASSERT(DeviceObject == GlobalDeviceObject);
if (OpenEntry->WriteOnly)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
/* Make the read cancellable */
IoAcquireCancelSpinLock(&OldCancelIrql);
IoSetCancelRoutine(Irp, ReadIrpCancel);
if (Irp->Cancel)
{
IoReleaseCancelSpinLock(OldCancelIrql);
/* Indicate a 0 byte read */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
IoReleaseCancelSpinLock(OldCancelIrql);
while (TRUE)
{
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
/* Check if we have a packet */
if (IsListEmpty(&AdapterContext->PacketList))
{
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
/* Wait for a packet (in the context of the calling user thread) */
Status = KeWaitForSingleObject(&AdapterContext->PacketReadEvent,
UserRequest,
UserMode,
TRUE,
NULL);
if (Status != STATUS_SUCCESS)
{
/* Remove the cancel routine */
IoAcquireCancelSpinLock(&OldCancelIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldCancelIrql);
break;
}
}
else
{
/* Remove the cancel routine */
IoAcquireCancelSpinLock(&OldCancelIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldCancelIrql);
/* Remove the first packet in the list */
ListEntry = RemoveHeadList(&AdapterContext->PacketList);
PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);
/* Release the adapter lock */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
/* And we're done with this loop */
Status = STATUS_SUCCESS;
break;
}
}
/* Check if we got a packet */
if (PacketEntry != NULL)
{
/* Find the right amount of bytes to copy */
BytesCopied = PacketEntry->PacketLength;
if (BytesCopied > IrpSp->Parameters.Read.Length)
BytesCopied = IrpSp->Parameters.Read.Length;
/* Copy the packet */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&PacketEntry->PacketData[0],
BytesCopied);
/* Free the packet entry */
ExFreePool(PacketEntry);
}
else
{
/* Something failed */
BytesCopied = 0;
}
/* Complete the IRP */
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesCopied;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDIS_PACKET Packet;
NDIS_STATUS Status;
ULONG BytesCopied = 0;
ASSERT(DeviceObject == GlobalDeviceObject);
/* Create a packet and buffer descriptor for this user buffer */
Packet = CreatePacketFromPoolBuffer(AdapterContext,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.Write.Length);
if (Packet)
{
/* Send it via NDIS */
NdisSend(&Status,
AdapterContext->BindingHandle,
Packet);
/* Wait for the send */
if (Status == NDIS_STATUS_PENDING)
{
KeWaitForSingleObject(&AdapterContext->AsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
Status = AdapterContext->AsyncStatus;
}
/* Check if it succeeded */
if (Status == NDIS_STATUS_SUCCESS)
BytesCopied = IrpSp->Parameters.Write.Length;
CleanupAndFreePacket(Packet, FALSE);
}
else
{
/* No memory */
Status = STATUS_NO_MEMORY;
}
/* Complete the IRP */
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesCopied;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return Status;
}

View file

@ -42,6 +42,22 @@ typedef enum _NDIS_DEVICE_POWER_STATE {
NdisDeviceStateMaximum NdisDeviceStateMaximum
} NDIS_DEVICE_POWER_STATE, *PNDIS_DEVICE_POWER_STATE; } NDIS_DEVICE_POWER_STATE, *PNDIS_DEVICE_POWER_STATE;
typedef enum _NDIS_802_11_WEP_STATUS
{
Ndis802_11WEPEnabled,
Ndis802_11WEPDisabled,
Ndis802_11WEPKeyAbsent,
Ndis802_11WEPNotSupported
} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS;
typedef enum _NDIS_802_11_AUTHENTICATION_MODE
{
Ndis802_11AuthModeOpen,
Ndis802_11AuthModeShared,
Ndis802_11AuthModeAutoSwitch,
Ndis802_11AuthModeMax
} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
{ {
Ndis802_11IBSS, Ndis802_11IBSS,
@ -117,6 +133,14 @@ typedef struct _NDIS_802_11_BSSID_LIST
NDIS_WLAN_BSSID Bssid[1]; NDIS_WLAN_BSSID Bssid[1];
} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST; } NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
typedef struct _NDIS_802_11_WEP
{
ULONG Length;
ULONG KeyIndex;
ULONG KeyLength;
UCHAR KeyMaterial[1];
} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
typedef struct _NDIS_PM_WAKE_UP_CAPABILITIES { typedef struct _NDIS_PM_WAKE_UP_CAPABILITIES {
NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp;
NDIS_DEVICE_POWER_STATE MinPatternWakeUp; NDIS_DEVICE_POWER_STATE MinPatternWakeUp;
@ -265,8 +289,34 @@ typedef ULONG NDIS_OID, *PNDIS_OID;
#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 #define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 #define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
#define OID_802_11_BSSID_LIST 0x0D010217 /* IEEE 802.11 (WLAN) OIDs */
#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A #define OID_802_11_BSSID 0x0D010101
#define OID_802_11_SSID 0x0D010102
#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203
#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204
#define OID_802_11_TX_POWER_LEVEL 0x0D010205
#define OID_802_11_RSSI 0x0D010206
#define OID_802_11_RSSI_TRIGGER 0x0D010207
#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108
#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209
#define OID_802_11_RTS_THRESHOLD 0x0D01020A
#define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B
#define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C
#define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D
#define OID_802_11_SUPPORTED_RATES 0x0D01020E
#define OID_802_11_DESIRED_RATES 0x0D010210
#define OID_802_11_CONFIGURATION 0x0D010211
#define OID_802_11_STATISTICS 0x0D020212
#define OID_802_11_ADD_WEP 0x0D010113
#define OID_802_11_REMOVE_WEP 0x0D010114
#define OID_802_11_DISASSOCIATE 0x0D010115
#define OID_802_11_POWER_MODE 0x0D010216
#define OID_802_11_BSSID_LIST 0x0D010217
#define OID_802_11_AUTHENTICATION_MODE 0x0D010118
#define OID_802_11_PRIVACY_FILTER 0x0D010119
#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A
#define OID_802_11_WEP_STATUS 0x0D01011B
#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C
/* OID_GEN_MINIPORT_INFO constants */ /* OID_GEN_MINIPORT_INFO constants */
#define NDIS_MINIPORT_BUS_MASTER 0x00000001 #define NDIS_MINIPORT_BUS_MASTER 0x00000001

View file

@ -0,0 +1,59 @@
#ifndef __NUIOUSER_H
#define __NUIOUSER_H
/* Device names (NT and DOS style) */
#define NDISUIO_DEVICE_NAME_NT L"\\Device\\Ndisuio"
#define NDISUIO_DEVICE_NAME_DOS L"\\DosDevices\\Ndisuio"
/* Device name for user apps */
#define NDISUIO_DEVICE_NAME L"\\\\.\\\\Ndisuio"
/* Links a file handle with a bound NIC */
#define IOCTL_NDISUIO_OPEN_DEVICE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Queries an OID for the bound NIC */
#define IOCTL_NDISUIO_QUERY_OID_VALUE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x201, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NDISUIO_SET_ETHER_TYPE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x202, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Queries binding information during enumeration */
#define IOCTL_NDISUIO_QUERY_BINDING \
CTL_CODE(FILE_DEVICE_NETWORK, 0x203, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Waits for any pending bindings */
#define IOCTL_NDISUIO_BIND_WAIT \
CTL_CODE(FILE_DEVICE_NETWORK, 0x204, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Sets an OID for a bound NIC */
#define IOCTL_NDISUIO_SET_OID_VALUE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x205, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Passed as a parameter to IOCTL_NDISUIO_QUERY_OID_VALUE */
typedef struct _NDISUIO_QUERY_OID
{
NDIS_OID Oid;
UCHAR Data[sizeof(ULONG)];
} NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID;
/* Passed as a parameter to IOCTL_NDISUIO_SET_OID_VALUE */
typedef struct _NDISUIO_SET_OID
{
NDIS_OID Oid;
UCHAR Data[sizeof(ULONG)];
} NDISUIO_SET_OID, *PNDISUIO_SET_OID;
/* Passed as a parameter to IOCTL_NDISUIO_QUERY_BINDING */
typedef struct _NDISUIO_QUERY_BINDING
{
ULONG BindingIndex;
ULONG DeviceNameOffset;
ULONG DeviceNameLength;
ULONG DeviceDescrOffset;
ULONG DeviceDescrLength;
} NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING;
#endif