📄 driver_ndis.c
字号:
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); if (os_strstr(name, drv->ifname)) { wpa_printf(MSG_DEBUG, "NDIS: Interface name match"); found = 1; break; } if (os_strncmp(desc, drv->ifname, os_strlen(drv->ifname)) == 0) { wpa_printf(MSG_DEBUG, "NDIS: Interface description " "match"); found = 1; break; } } if (!found) { wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", drv->ifname); os_free(b); return -1; } os_strlcpy(drv->ifname, os_strncmp(name, "\\DEVICE\\", 8) == 0 ? name + 8 : name, sizeof(drv->ifname));#ifdef _WIN32_WCE drv->adapter_name = wpa_strdup_tchar(drv->ifname); if (drv->adapter_name == NULL) { wpa_printf(MSG_ERROR, "NDIS: Failed to allocate memory for " "adapter name"); os_free(b); return -1; }#endif /* _WIN32_WCE */ dpos = os_strstr(desc, " - "); if (dpos) dlen = dpos - desc; else dlen = os_strlen(desc); drv->adapter_desc = os_malloc(dlen + 1); if (drv->adapter_desc) { os_memcpy(drv->adapter_desc, desc, dlen); drv->adapter_desc[dlen] = '\0'; } os_free(b); if (drv->adapter_desc == NULL) return -1; wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", drv->adapter_desc); return 0;#else /* CONFIG_USE_NDISUIO */ PTSTR _names; char *names, *pos, *pos2; ULONG len; BOOLEAN res;#define MAX_ADAPTERS 32 char *name[MAX_ADAPTERS]; char *desc[MAX_ADAPTERS]; int num_name, num_desc, i, found_name, found_desc; size_t dlen; wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", PacketGetVersion()); len = 8192; _names = os_zalloc(len); if (_names == NULL) return -1; res = PacketGetAdapterNames(_names, &len); if (!res && len > 8192) { os_free(_names); _names = os_zalloc(len); if (_names == NULL) return -1; res = PacketGetAdapterNames(_names, &len); } if (!res) { wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " "(PacketGetAdapterNames)"); os_free(_names); return -1; } 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 -1; } pos++; num_name++; if (num_name >= MAX_ADAPTERS) { wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); os_free(names); return -1; } 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 -1; } pos++; num_desc++; if (num_desc >= MAX_ADAPTERS) { wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " "descriptions"); os_free(names); return -1; } 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 -1; } found_name = found_desc = -1; for (i = 0; i < num_name; i++) { wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name[i], desc[i]); if (found_name == -1 && os_strstr(name[i], drv->ifname)) found_name = i; if (found_desc == -1 && os_strncmp(desc[i], drv->ifname, os_strlen(drv->ifname)) == 0) found_desc = i; } if (found_name < 0 && found_desc >= 0) { wpa_printf(MSG_DEBUG, "NDIS: Matched interface '%s' based on " "description '%s'", name[found_desc], desc[found_desc]); found_name = found_desc; os_strlcpy(drv->ifname, os_strncmp(name[found_desc], "\\Device\\NPF_", 12) == 0 ? name[found_desc] + 12 : name[found_desc], sizeof(drv->ifname)); } if (found_name < 0) { wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", drv->ifname); os_free(names); return -1; } i = found_name; pos = os_strrchr(desc[i], '('); if (pos) { dlen = pos - desc[i]; pos--; if (pos > desc[i] && *pos == ' ') dlen--; } else { dlen = os_strlen(desc[i]); } drv->adapter_desc = os_malloc(dlen + 1); if (drv->adapter_desc) { os_memcpy(drv->adapter_desc, desc[i], dlen); drv->adapter_desc[dlen] = '\0'; } os_free(names); if (drv->adapter_desc == NULL) return -1; wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", drv->adapter_desc); return 0;#endif /* CONFIG_USE_NDISUIO */}#if defined(CONFIG_NATIVE_WINDOWS) || defined(__CYGWIN__)#ifndef _WIN32_WCE/* * These structures are undocumented for WinXP; only WinCE version is * documented. These would be included wzcsapi.h if it were available. Some * changes here have been needed to make the structures match with WinXP SP2. * It is unclear whether these work with any other version. */typedef struct { LPWSTR wszGuid;} INTF_KEY_ENTRY, *PINTF_KEY_ENTRY;typedef struct { DWORD dwNumIntfs; PINTF_KEY_ENTRY pIntfs;} INTFS_KEY_TABLE, *PINTFS_KEY_TABLE;typedef struct { DWORD dwDataLen; LPBYTE pData;} RAW_DATA, *PRAW_DATA;typedef struct { LPWSTR wszGuid; LPWSTR wszDescr; ULONG ulMediaState; ULONG ulMediaType; ULONG ulPhysicalMediaType; INT nInfraMode; INT nAuthMode; INT nWepStatus;#ifndef _WIN32_WCE u8 pad[2]; /* why is this needed? */#endif /* _WIN32_WCE */ DWORD dwCtlFlags; DWORD dwCapabilities; /* something added for WinXP SP2(?) */ RAW_DATA rdSSID; RAW_DATA rdBSSID; RAW_DATA rdBSSIDList; RAW_DATA rdStSSIDList; RAW_DATA rdCtrlData;#ifdef UNDER_CE BOOL bInitialized;#endif DWORD nWPAMCastCipher; /* add some extra buffer for later additions since this interface is * far from stable */ u8 later_additions[100];} INTF_ENTRY, *PINTF_ENTRY;#define INTF_ALL 0xffffffff#define INTF_ALL_FLAGS 0x0000ffff#define INTF_CTLFLAGS 0x00000010#define INTFCTL_ENABLED 0x8000#endif /* _WIN32_WCE */#ifdef _WIN32_WCEstatic int wpa_driver_ndis_rebind_adapter(struct wpa_driver_ndis_data *drv){ HANDLE ndis; TCHAR multi[100]; int len; len = _tcslen(drv->adapter_name); if (len > 80) return -1; ndis = CreateFile(DD_NDIS_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (ndis == INVALID_HANDLE_VALUE) { wpa_printf(MSG_DEBUG, "NDIS: Failed to open file to NDIS " "device: %d", (int) GetLastError()); return -1; } len++; memcpy(multi, drv->adapter_name, len * sizeof(TCHAR)); memcpy(&multi[len], TEXT("NDISUIO\0"), 9 * sizeof(TCHAR)); len += 9; if (!DeviceIoControl(ndis, IOCTL_NDIS_REBIND_ADAPTER, multi, len * sizeof(TCHAR), NULL, 0, NULL, NULL)) { wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDIS_REBIND_ADAPTER " "failed: 0x%x", (int) GetLastError()); wpa_hexdump_ascii(MSG_DEBUG, "NDIS: rebind multi_sz", (u8 *) multi, len * sizeof(TCHAR)); CloseHandle(ndis); return -1; } CloseHandle(ndis); wpa_printf(MSG_DEBUG, "NDIS: Requested NDIS rebind of NDISUIO " "protocol"); return 0;}#endif /* _WIN32_WCE */static int wpa_driver_ndis_set_wzc(struct wpa_driver_ndis_data *drv, int enable){#ifdef _WIN32_WCE HKEY hk, hk2; LONG ret; DWORD i, hnd, len; TCHAR keyname[256], devname[256];#define WZC_DRIVER TEXT("Drivers\\BuiltIn\\ZeroConfig") if (enable) { HANDLE h; h = ActivateDeviceEx(WZC_DRIVER, NULL, 0, NULL); if (h == INVALID_HANDLE_VALUE || h == 0) { wpa_printf(MSG_DEBUG, "NDIS: Failed to re-enable WZC " "- ActivateDeviceEx failed: %d", (int) GetLastError()); return -1; } wpa_printf(MSG_DEBUG, "NDIS: WZC re-enabled"); return wpa_driver_ndis_rebind_adapter(drv); } /* * Unfortunately, just disabling the WZC for an interface is not enough * to free NDISUIO for us, so need to disable and unload WZC completely * for now when using WinCE with NDISUIO. In addition, must request * NDISUIO protocol to be rebound to the adapter in order to free the * NDISUIO binding that WZC hold before us. */ /* Enumerate HKLM\Drivers\Active\* to find a handle to WZC. */ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, DEVLOAD_ACTIVE_KEY, 0, 0, &hk); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(DEVLOAD_ACTIVE_KEY) " "failed: %d %d", (int) ret, (int) GetLastError()); return -1; } for (i = 0; ; i++) { len = sizeof(keyname); ret = RegEnumKeyEx(hk, i, keyname, &len, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "NDIS: Could not find active " "WZC - assuming it is not running."); RegCloseKey(hk); return -1; } ret = RegOpenKeyEx(hk, keyname, 0, 0, &hk2); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(active dev) " "failed: %d %d", (int) ret, (int) GetLastError()); continue; } len = sizeof(devname); ret = RegQueryValueEx(hk2, DEVLOAD_DEVKEY_VALNAME, NULL, NULL, (LPBYTE) devname, &len); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(" "DEVKEY_VALNAME) failed: %d %d", (int) ret, (int) GetLastError()); RegCloseKey(hk2); continue; } if (_tcscmp(devname, WZC_DRIVER) == 0) break; RegCloseKey(hk2); } RegCloseKey(hk); /* Found WZC - get handle to it. */ len = sizeof(hnd); ret = RegQueryValueEx(hk2, DEVLOAD_HANDLE_VALNAME, NULL, NULL, (PUCHAR) &hnd, &len); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(HANDLE_VALNAME) " "failed: %d %d", (int) ret, (int) GetLastError()); RegCloseKey(hk2); return -1; } RegCloseKey(hk2); /* Deactivate WZC */ if (!DeactivateDevice((HANDLE) hnd)) { wpa_printf(MSG_DEBUG, "NDIS: DeactivateDevice failed: %d", (int) GetLastError()); return -1; } wpa_printf(MSG_DEBUG, "NDIS: Disabled WZC temporarily"); drv->wzc_disabled = 1; return wpa_driver_ndis_rebind_adapter(drv);#else /* _WIN32_WCE */ HMODULE hm; DWORD (WINAPI *wzc_enum_interf)(LPWSTR pSrvAddr, PINTFS_KEY_TABLE pIntfs); DWORD (WINAPI *wzc_query_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, PINTF_ENTRY pIntf, LPDWORD pdwOutFlags); DWORD (WINAPI *wzc_set_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, PINTF_ENTRY pIntf, LPDWORD pdwOutFlags); int ret = -1, j; DWORD res; INTFS_KEY_TABLE guids; INTF_ENTRY intf; char guid[128]; WCHAR *pos; DWORD flags, i; hm = LoadLibrary(TEXT("wzcsapi.dll")); if (hm == NULL) { wpa_printf(MSG_DEBUG, "NDIS: Failed to load wzcsapi.dll (%u) " "- WZC probably not running", (unsigned int) GetLastError()); return -1; }#ifdef _WIN32_WCE wzc_enum_interf = (void *) GetProcAddressA(hm, "WZCEnumInterfaces"); wzc_query_interf = (void *) GetProcAddressA(hm, "WZCQueryInterface"); wzc_set_interf = (void *) GetProcAddressA(hm, "WZCSetInterface");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -