Added get_interfaces() handler to list all NDIS adapters
This commit is contained in:
parent
f44b6b8c04
commit
af7837feff
1 changed files with 236 additions and 2 deletions
|
@ -493,7 +493,7 @@ static int ndis_set_oid(struct wpa_driver_ndis_data *drv, unsigned int oid,
|
|||
char txt[50];
|
||||
|
||||
os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
|
||||
wpa_hexdump_key(MSG_MSGDUMP, txt, data, len);
|
||||
wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len);
|
||||
|
||||
buflen = sizeof(*o) + len;
|
||||
reallen = buflen - sizeof(o->Data);
|
||||
|
@ -2844,6 +2844,240 @@ static void wpa_driver_ndis_deinit(void *priv)
|
|||
}
|
||||
|
||||
|
||||
static struct wpa_interface_info *
|
||||
wpa_driver_ndis_get_interfaces(void *global_priv)
|
||||
{
|
||||
struct wpa_interface_info *iface = NULL, *niface;
|
||||
|
||||
#ifdef CONFIG_USE_NDISUIO
|
||||
NDISUIO_QUERY_BINDING *b;
|
||||
size_t blen = sizeof(*b) + 1024;
|
||||
int i, error;
|
||||
DWORD written;
|
||||
char name[256], desc[256];
|
||||
WCHAR *pos;
|
||||
size_t j, len;
|
||||
HANDLE ndisuio;
|
||||
|
||||
ndisuio = CreateFile(NDISUIO_DEVICE_NAME,
|
||||
GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||||
INVALID_HANDLE_VALUE);
|
||||
if (ndisuio == INVALID_HANDLE_VALUE) {
|
||||
wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to "
|
||||
"NDISUIO: %d", (int) GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0,
|
||||
NULL, 0, &written, NULL)) {
|
||||
wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: "
|
||||
"%d", (int) GetLastError());
|
||||
CloseHandle(ndisuio);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
b = os_malloc(blen);
|
||||
if (b == NULL) {
|
||||
CloseHandle(ndisuio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
os_memset(b, 0, blen);
|
||||
b->BindingIndex = i;
|
||||
if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
|
||||
b, sizeof(NDISUIO_QUERY_BINDING), b, blen,
|
||||
&written, NULL)) {
|
||||
error = (int) GetLastError();
|
||||
if (error == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING "
|
||||
"failed: %d", error);
|
||||
break;
|
||||
}
|
||||
|
||||
pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
|
||||
len = b->DeviceNameLength;
|
||||
if (len >= sizeof(name))
|
||||
len = sizeof(name) - 1;
|
||||
for (j = 0; j < len; j++)
|
||||
name[j] = (char) pos[j];
|
||||
name[len] = '\0';
|
||||
|
||||
pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
|
||||
len = b->DeviceDescrLength;
|
||||
if (len >= sizeof(desc))
|
||||
len = sizeof(desc) - 1;
|
||||
for (j = 0; j < len; j++)
|
||||
desc[j] = (char) pos[j];
|
||||
desc[len] = '\0';
|
||||
|
||||
wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc);
|
||||
|
||||
niface = os_zalloc(sizeof(*niface));
|
||||
if (niface == NULL)
|
||||
break;
|
||||
niface->drv_name = "ndis";
|
||||
if (os_strncmp(name, "\\DEVICE\\", 8) == 0)
|
||||
niface->ifname = os_strdup(name + 8);
|
||||
else
|
||||
niface->ifname = os_strdup(name);
|
||||
if (niface->ifname == NULL) {
|
||||
os_free(niface);
|
||||
break;
|
||||
}
|
||||
niface->desc = os_strdup(desc);
|
||||
niface->next = iface;
|
||||
iface = niface;
|
||||
}
|
||||
|
||||
os_free(b);
|
||||
CloseHandle(ndisuio);
|
||||
#else /* CONFIG_USE_NDISUIO */
|
||||
PTSTR _names;
|
||||
char *names, *pos, *pos2;
|
||||
ULONG len;
|
||||
BOOLEAN res;
|
||||
char *name[MAX_ADAPTERS];
|
||||
char *desc[MAX_ADAPTERS];
|
||||
int num_name, num_desc, i;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s",
|
||||
PacketGetVersion());
|
||||
|
||||
len = 8192;
|
||||
_names = os_zalloc(len);
|
||||
if (_names == NULL)
|
||||
return NULL;
|
||||
|
||||
res = PacketGetAdapterNames(_names, &len);
|
||||
if (!res && len > 8192) {
|
||||
os_free(_names);
|
||||
_names = os_zalloc(len);
|
||||
if (_names == NULL)
|
||||
return NULL;
|
||||
res = PacketGetAdapterNames(_names, &len);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list "
|
||||
"(PacketGetAdapterNames)");
|
||||
os_free(_names);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
names = (char *) _names;
|
||||
if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in "
|
||||
"UNICODE");
|
||||
/* Convert to ASCII */
|
||||
pos2 = pos = names;
|
||||
while (pos2 < names + len) {
|
||||
if (pos2[0] == '\0' && pos2[1] == '\0' &&
|
||||
pos2[2] == '\0' && pos2[3] == '\0') {
|
||||
pos2 += 4;
|
||||
break;
|
||||
}
|
||||
*pos++ = pos2[0];
|
||||
pos2 += 2;
|
||||
}
|
||||
os_memcpy(pos + 2, names, pos - names);
|
||||
pos += 2;
|
||||
} else
|
||||
pos = names;
|
||||
|
||||
num_name = 0;
|
||||
while (pos < names + len) {
|
||||
name[num_name] = pos;
|
||||
while (*pos && pos < names + len)
|
||||
pos++;
|
||||
if (pos + 1 >= names + len) {
|
||||
os_free(names);
|
||||
return NULL;
|
||||
}
|
||||
pos++;
|
||||
num_name++;
|
||||
if (num_name >= MAX_ADAPTERS) {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Too many adapters");
|
||||
os_free(names);
|
||||
return NULL;
|
||||
}
|
||||
if (*pos == '\0') {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found",
|
||||
num_name);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
num_desc = 0;
|
||||
while (pos < names + len) {
|
||||
desc[num_desc] = pos;
|
||||
while (*pos && pos < names + len)
|
||||
pos++;
|
||||
if (pos + 1 >= names + len) {
|
||||
os_free(names);
|
||||
return NULL;
|
||||
}
|
||||
pos++;
|
||||
num_desc++;
|
||||
if (num_desc >= MAX_ADAPTERS) {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Too many adapter "
|
||||
"descriptions");
|
||||
os_free(names);
|
||||
return NULL;
|
||||
}
|
||||
if (*pos == '\0') {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions "
|
||||
"found", num_name);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
|
||||
* descriptions. Fill in dummy descriptors to work around this.
|
||||
*/
|
||||
while (num_desc < num_name)
|
||||
desc[num_desc++] = "dummy description";
|
||||
|
||||
if (num_name != num_desc) {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
|
||||
"description counts (%d != %d)",
|
||||
num_name, num_desc);
|
||||
os_free(names);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_name; i++) {
|
||||
niface = os_zalloc(sizeof(*niface));
|
||||
if (niface == NULL)
|
||||
break;
|
||||
niface->drv_name = "ndis";
|
||||
if (os_strncmp(name[i], "\\Device\\NPF_", 12) == 0)
|
||||
niface->ifname = os_strdup(name[i] + 12);
|
||||
else
|
||||
niface->ifname = os_strdup(name[i]);
|
||||
if (niface->ifname == NULL) {
|
||||
os_free(niface);
|
||||
break;
|
||||
}
|
||||
niface->desc = os_strdup(desc[i]);
|
||||
niface->next = iface;
|
||||
iface = niface;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USE_NDISUIO */
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||
"ndis",
|
||||
"Windows NDIS driver",
|
||||
|
@ -2888,5 +3122,5 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
|||
NULL /* global_init */,
|
||||
NULL /* global_deinit */,
|
||||
NULL /* init2 */,
|
||||
NULL /* get_interfaces */
|
||||
wpa_driver_ndis_get_interfaces
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue