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];
|
char txt[50];
|
||||||
|
|
||||||
os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
|
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;
|
buflen = sizeof(*o) + len;
|
||||||
reallen = buflen - sizeof(o->Data);
|
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 = {
|
const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||||
"ndis",
|
"ndis",
|
||||||
"Windows NDIS driver",
|
"Windows NDIS driver",
|
||||||
|
@ -2888,5 +3122,5 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||||
NULL /* global_init */,
|
NULL /* global_init */,
|
||||||
NULL /* global_deinit */,
|
NULL /* global_deinit */,
|
||||||
NULL /* init2 */,
|
NULL /* init2 */,
|
||||||
NULL /* get_interfaces */
|
wpa_driver_ndis_get_interfaces
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue