Added get_interfaces() handler to list all NDIS adapters

This commit is contained in:
Jouni Malinen 2008-12-24 21:31:14 +02:00
parent f44b6b8c04
commit af7837feff

View file

@ -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
};