// Is the SU supported bool Win32EthIsSuSupported() { bool ret = false; SU *su = SuInit(); if (su != NULL) { ret = true; } SuFree(su); return ret; }
// Close adapter void CloseEth(ETH *e) { BLOCK *b; // Validate arguments if (e == NULL) { return; } ReleaseCancel(e->Cancel); if (e->SuAdapter != NULL) { // Close SeLow adapter SuCloseAdapter(e->SuAdapter); SuFree(e->Su); } else { // Close SEE adapter wp->PacketCloseAdapter(e->Adapter); wp->PacketFreePacket(e->Packet); wp->PacketFreePacket(e->PutPacket); } while (b = GetNext(e->PacketQueue)) { FreeBlock(b); } ReleaseQueue(e->PacketQueue); Free(e->Name); Free(e->Title); Free(e->Buffer); Free(e); }
bool SuInstallDriverInner(bool force) { wchar_t sys_fullpath[MAX_PATH]; UINT current_sl_ver = 0; bool ret = false; wchar_t src_cat[MAX_PATH]; wchar_t src_inf[MAX_PATH]; wchar_t src_sys[MAX_PATH]; wchar_t dst_cat[MAX_PATH]; wchar_t dst_inf[MAX_PATH]; wchar_t dst_sys[MAX_PATH]; wchar_t tmp_dir[MAX_PATH]; char *cpu_type = MsIsX64() ? "x64" : "x86"; if (SuIsSupportedOs(true) == false) { // Unsupported OS return false; } CombinePathW(tmp_dir, sizeof(tmp_dir), MsGetWindowsDirW(), L"Temp"); MakeDirExW(tmp_dir); UniStrCat(tmp_dir, sizeof(tmp_dir), L"\\selowtmp"); MakeDirExW(tmp_dir); // Confirm whether the driver is currently installed CombinePathW(sys_fullpath, sizeof(sys_fullpath), MsGetSystem32DirW(), L"drivers\\SeLow_%S.sys"); UniFormat(sys_fullpath, sizeof(sys_fullpath), sys_fullpath, cpu_type); if (IsFileExistsW(sys_fullpath)) { char *path; // Read the current version from the registry current_sl_ver = MsRegReadIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, (MsIsWindows10() ? SL_REG_VER_VALUE_WIN10 : SL_REG_VER_VALUE), false, true); path = MsRegReadStrEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "ImagePath", false, true); if (IsEmptyStr(path) || IsFileExists(path) == false || MsIsServiceInstalled(SL_PROTOCOL_NAME) == false) { current_sl_ver = 0; } Free(path); } if (force == false && current_sl_ver >= SL_VER) { // Newer version has already been installed Debug("Newer SeLow is Installed. %u >= %u\n", current_sl_ver, SL_VER); return true; } // Copy necessary files to a temporary directory UniFormat(src_sys, sizeof(src_sys), L"|DriverPackages\\%S\\%S\\SeLow_%S.sys", (MsIsWindows10() ? "SeLow_Win10" : "SeLow_Win8"), cpu_type, cpu_type); if (MsIsWindows8() == false) { // Windows Vista and Windows 7 uses SHA-1 catalog files UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win8\\%S\\inf.cat", cpu_type); } else { // Windows 8 or above uses SHA-256 catalog files UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win8\\%S\\inf2.cat", cpu_type); if (MsIsWindows10()) { // Windows 10 uses WHQL catalog files UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win10\\%S\\SeLow_Win10_%S.cat", cpu_type, cpu_type); } } UniFormat(src_inf, sizeof(src_inf), L"|DriverPackages\\%S\\%S\\SeLow_%S.inf", (MsIsWindows10() ? "SeLow_Win10" : "SeLow_Win8"), cpu_type, cpu_type); UniFormat(dst_sys, sizeof(dst_cat), L"%s\\SeLow_%S.sys", tmp_dir, cpu_type); UniFormat(dst_cat, sizeof(dst_cat), L"%s\\SeLow_%S_%S.cat", tmp_dir, (MsIsWindows10() ? "Win10" : "Win8"), cpu_type); UniFormat(dst_inf, sizeof(dst_inf), L"%s\\SeLow_%S.inf", tmp_dir, cpu_type); if (FileCopyW(src_sys, dst_sys) && FileCopyW(src_cat, dst_cat) && FileCopyW(src_inf, dst_inf)) { NO_WARNING *nw; nw = MsInitNoWarningEx(SL_USER_AUTO_PUSH_TIMER); if (MsIsWindows10()) { if (MsIsServiceInstalled(SL_PROTOCOL_NAME) == false && MsIsServiceRunning(SL_PROTOCOL_NAME) == false) { // On Windows 10, if there are no SwLow service installed, then uinstall the protocol driver first. // TODO: currently do nothing. On some versions of Windows 10 beta builds it is necessary to do something... } } if (MsIsWindows10()) { // Delete garbage INFs SuDeleteGarbageInfs(); } // Call the installer if (InstallNdisProtocolDriver(dst_inf, L"SeLow", SL_USER_INSTALL_LOCK_TIMEOUT) == false) { Debug("InstallNdisProtocolDriver Error.\n"); } else { Debug("InstallNdisProtocolDriver Ok.\n"); // Copy manually because there are cases where .sys file is not copied successfully for some reason FileCopyW(src_sys, sys_fullpath); ret = true; // Write the version number into the registry MsRegWriteIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, (MsIsWindows10() ? SL_REG_VER_VALUE_WIN10 : SL_REG_VER_VALUE), SL_VER, false, true); // Set to automatic startup MsRegWriteIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "Start", SERVICE_SYSTEM_START, false, true); } MsFreeNoWarning(nw); } else { Debug("Fail Copying Files.\n"); } if (ret) { // If the service is installed this time, start and wait until the enumeration is completed SuFree(SuInitEx(180 * 1000)); } return ret; }
LIST *GetEthAdapterListInternal() { LIST *o; LIST *ret; UINT size; char *buf; UINT i, j; char *qos_tag = " (Microsoft's Packet Scheduler)"; SU *su = NULL; LIST *su_adapter_list = NULL; // Try to use SeLow if (enable_selow) { su = SuInit(); } o = NewListFast(CompareWpAdapter); size = 200000; buf = ZeroMalloc(size); // Try to enumerate with SeLow if (su != NULL) { su_adapter_list = SuGetAdapterList(su); if (su_adapter_list == NULL) { // Fail to enumerate SuFree(su); su = NULL; //WHERE; is_using_selow = false; } else { //WHERE; is_using_selow = true; } } else { is_using_selow = false; } if (su_adapter_list != NULL) { // If 1 or more adapters are enumerated by SeLow, create adapter list object UINT i; for (i = 0;i < LIST_NUM(su_adapter_list);i++) { SU_ADAPTER_LIST *t = LIST_DATA(su_adapter_list, i); WP_ADAPTER *a = ZeroMalloc(sizeof(WP_ADAPTER)); StrCpy(a->Name, sizeof(a->Name), t->Name); StrCpy(a->Guid, sizeof(a->Guid), t->Guid); StrCpy(a->Title, sizeof(a->Title), t->Info.FriendlyName); TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); if (EndWith(a->Title, qos_tag)) { a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0; TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); } Add(o, a); } } else { // When SeLow is not used, create adapter list with SEE or WinPcap if (wp->PacketGetAdapterNames(buf, &size) == false) { Free(buf); return o; } i = 0; if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType)) { // Windows NT if (size >= 2 && buf[0] != 0 && buf[1] != 0) { goto ANSI_STR; } while (true) { wchar_t tmp[MAX_SIZE]; WP_ADAPTER *a; UniStrCpy(tmp, sizeof(tmp), L""); if (*((wchar_t *)(&buf[i])) == 0) { i += sizeof(wchar_t); break; } for (;*((wchar_t *)(&buf[i])) != 0;i += sizeof(wchar_t)) { wchar_t str[2]; str[0] = *((wchar_t *)(&buf[i])); str[1] = 0; UniStrCat(tmp, sizeof(tmp), str); } i += sizeof(wchar_t); a = ZeroMalloc(sizeof(WP_ADAPTER)); UniToStr(a->Name, sizeof(a->Name), tmp); Add(o, a); } } else { // Windows 9x ANSI_STR: while (true) { char tmp[MAX_SIZE]; WP_ADAPTER *a; StrCpy(tmp, sizeof(tmp), ""); if (*((char *)(&buf[i])) == 0) { i += sizeof(char); break; } for (;*((char *)(&buf[i])) != 0;i += sizeof(char)) { char str[2]; str[0] = *((char *)(&buf[i])); str[1] = 0; StrCat(tmp, sizeof(tmp), str); } i += sizeof(char); a = ZeroMalloc(sizeof(WP_ADAPTER)); StrCpy(a->Name, sizeof(a->Name), tmp); Add(o, a); } } for (j = 0;j < LIST_NUM(o);j++) { WP_ADAPTER *a = LIST_DATA(o, j); StrCpy(a->Title, sizeof(a->Title), &buf[i]); i += StrSize(a->Title); // If device description is "Unknown" in Win9x, skip 1 byte if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType)) { if (StrCmp(a->Title, "Unknown") == 0) { if (buf[i] == 0) { i+=sizeof(char); } } } TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); if (EndWith(a->Title, qos_tag)) { a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0; TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); } } } for (j = 0;j < LIST_NUM(o);j++) { // Extract GUID WP_ADAPTER *a = LIST_DATA(o, j); if (IsEmptyStr(a->Guid)) { StrCpy(a->Guid, sizeof(a->Guid), a->Name); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\SEE_", ""); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\NPF_", ""); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\PCD_", ""); } } // Sort if (su_adapter_list != NULL) { // Since adapter list made by SeLow is already sorted, don't sort here Sort(o); } ret = NewListFast(CompareWpAdapter); for (i = 0;i < LIST_NUM(o);i++) { WP_ADAPTER *a = LIST_DATA(o, i); ADAPTER *ad; bool is_ethernet = false; bool ok = false; if (SearchStrEx(a->Title, "ppp", 0, false) != INFINITE || SearchStrEx(a->Title, "wan", 0, false) != INFINITE || SearchStrEx(a->Title, "dialup", 0, false) != INFINITE || SearchStrEx(a->Title, "pptp", 0, false) != INFINITE || SearchStrEx(a->Title, "telepho", 0, false) != INFINITE || SearchStrEx(a->Title, "modem", 0, false) != INFINITE || SearchStrEx(a->Title, "ras", 0, false) != INFINITE) { Free(a); continue; } // Determine whether the adapter type is Ethernet if (su == NULL) { // Determine with See ad = wp->PacketOpenAdapter(a->Name); if (ad != NULL) { NetType type; if (wp->PacketGetNetType(ad, &type)) { if (type.LinkType == 0) { is_ethernet = true; } } wp->PacketCloseAdapter(ad); } } else { // In using SeLow, all devices should be Ethernet device is_ethernet = true; } if (is_ethernet) { // Add only Ethernet device char tmp[MAX_SIZE]; UINT k; StrCpy(tmp, sizeof(tmp), a->Title); for (k = 0;;k++) { if (k == 0) { StrCpy(tmp, sizeof(tmp), a->Title); } else { Format(tmp, sizeof(tmp), "%s (%u)", a->Title, k + 1); } ok = true; for (j = 0;j < LIST_NUM(ret);j++) { WP_ADAPTER *aa = LIST_DATA(ret, j); if (StrCmpi(aa->Title, tmp) == 0) { ok = false; } } if (ok) { break; } } StrCpy(a->Title, sizeof(a->Title), tmp); a->Id = Win32EthGenIdFromGuid(a->Guid); Add(ret, a); } if (ok == false) { Free(a); } } Free(buf); Sort(ret); ReleaseList(o); if (su != NULL) { SuFreeAdapterList(su_adapter_list); SuFree(su); } return ret; }
ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr) { WP_ADAPTER *t; ETH *e; ADAPTER *a = NULL; HANDLE h; CANCEL *c; MS_ADAPTER *ms; char name_with_id[MAX_SIZE]; SU *su = NULL; SU_ADAPTER *su_adapter = NULL; // Validate arguments if (name == NULL || IsEthSupported() == false) { return NULL; } if (tapmode) { // Tap is not supported in Windows return NULL; } Lock(eth_list_lock); InitEthAdaptersList(); t = Win32EthSearch(name); if (t == NULL) { Unlock(eth_list_lock); return NULL; } Debug("OpenEthInternal: %s\n", t->Name); if (StartWith(t->Name, SL_ADAPTER_ID_PREFIX)) { // Open with SU su = SuInit(); if (su == NULL) { // Fail to initialize SU Unlock(eth_list_lock); return NULL; } su_adapter = SuOpenAdapter(su, t->Name); if (su_adapter == NULL) { // Fail to get adapter SuFree(su); Unlock(eth_list_lock); return NULL; } is_using_selow = true; } else { // Open with SEE a = wp->PacketOpenAdapter(t->Name); if (a == NULL) { Unlock(eth_list_lock); return NULL; } if (IsWin32BridgeWithSee() == false) { MsSetThreadSingleCpu(); } is_using_selow = false; } e = ZeroMalloc(sizeof(ETH)); e->Name = CopyStr(t->Name); Win32EthMakeCombinedName(name_with_id, sizeof(name_with_id), t->Title, t->Guid); e->Title = CopyStr(name_with_id); if (su_adapter != NULL) { // SU e->SuAdapter = su_adapter; e->Su = su; // Get event object h = e->SuAdapter->hEvent; c = NewCancelSpecial(h); e->Cancel = c; } else { // SEE e->Adapter = a; wp->PacketSetBuff(e->Adapter, BRIDGE_WIN32_ETH_BUFFER); wp->PacketSetHwFilter(e->Adapter, local ? 0x0080 : 0x0020); wp->PacketSetMode(e->Adapter, PACKET_MODE_CAPT); wp->PacketSetReadTimeout(e->Adapter, -1); wp->PacketSetNumWrites(e->Adapter, 1); if (wp->PacketSetLoopbackBehavior != NULL) { // Filter loopback packet in kernel if (GET_KETA(GetOsType(), 100) >= 3) { if (MsIsWindows8() == false) { // Enable for Windows XP, Server 2003 or later // But disable for Windows 8 or later bool ret = wp->PacketSetLoopbackBehavior(e->Adapter, 1); Debug("*** PacketSetLoopbackBehavior: %u\n", ret); e->LoopbackBlock = ret; } } } // Get event object h = wp->PacketGetReadEvent(e->Adapter); c = NewCancelSpecial(h); e->Cancel = c; e->Packet = wp->PacketAllocatePacket(); e->PutPacket = wp->PacketAllocatePacket(); } e->Buffer = Malloc(BRIDGE_WIN32_ETH_BUFFER); e->BufferSize = BRIDGE_WIN32_ETH_BUFFER; e->PacketQueue = NewQueue(); // Get MAC address by GUID ms = MsGetAdapterByGuid(t->Guid); if (ms != NULL) { if (ms->AddressSize == 6) { Copy(e->MacAddress, ms->Address, 6); } MsFreeAdapter(ms); } Unlock(eth_list_lock); return e; }