}
}
- /* Get available network interfaces. */
+ /* Get all available network interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
if (dwResult == ERROR_SUCCESS)
{
/* Does interface exist? */
}
}
- /* Get available network interfaces. */
+ /* Get available TUN/TAP interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
if (dwResult == ERROR_SUCCESS)
{
/* Does interface exist? */
}
}
- /* Get available network interfaces. */
+ /* Get all available interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
if (dwResult == ERROR_SUCCESS)
{
/* Does interface exist? */
}
}
- /* Get available network interfaces. */
+ /* Get all available network interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
if (dwResult == ERROR_SUCCESS)
{
/* Does interface exist? */
OPENVPNMSICA_SAVE_MSI_SESSION(hInstall);
- /* Get available network interfaces. */
+ /* Get all TUN/TAP network interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- uiResult = tap_list_interfaces(NULL, &pInterfaceList);
+ uiResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
if (uiResult != ERROR_SUCCESS)
{
goto cleanup_CoInitialize;
}
}
- /* Enumerate interfaces. */
- struct interface_node
+ if (pInterfaceList != NULL)
{
- const struct tap_interface_node *iface;
- struct interface_node *next;
- } *interfaces_head = NULL, *interfaces_tail = NULL;
- size_t interface_count = 0;
- MSIHANDLE hRecord = MsiCreateRecord(1);
- for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
- {
- for (LPCTSTR hwid = pInterface->szzHardwareIDs; hwid[0]; hwid += _tcslen(hwid) + 1)
+ /* Count interfaces. */
+ size_t interface_count = 0;
+ for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
{
- if (_tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0
- || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0)
- {
- /* TAP interface found. */
-
- /* Report the GUID of the interface to installer. */
- LPOLESTR szInterfaceId = NULL;
- StringFromIID((REFIID)&pInterface->guid, &szInterfaceId);
- MsiRecordSetString(hRecord, 1, szInterfaceId);
- MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
- CoTaskMemFree(szInterfaceId);
-
- /* Append interface to the list. */
- struct interface_node *node = (struct interface_node *)malloc(sizeof(struct interface_node));
- if (node == NULL)
- {
- MsiCloseHandle(hRecord);
- msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct interface_node));
- uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses;
- }
-
- node->iface = pInterface;
- node->next = NULL;
- if (interfaces_head)
- {
- interfaces_tail = interfaces_tail->next = node;
- }
- else
- {
- interfaces_head = interfaces_tail = node;
- }
- interface_count++;
- break;
- }
+ interface_count++;
}
- }
- MsiCloseHandle(hRecord);
- if (interface_count)
- {
/* Prepare semicolon delimited list of TAP interface ID(s) and active TAP interface ID(s). */
LPTSTR
szTAPInterfaces = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)),
uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPInterfaces;
}
- while (interfaces_head)
+ for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
{
/* Convert interface GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */
LPOLESTR szInterfaceId = NULL;
- StringFromIID((REFIID)&interfaces_head->iface->guid, &szInterfaceId);
+ StringFromIID((REFIID)&pInterface->guid, &szInterfaceId);
/* Append to the list of TAP interface ID(s). */
if (szTAPInterfaces < szTAPInterfacesTail)
/* If this interface is active (connected), add it to the list of active TAP interface ID(s). */
for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next)
{
- OLECHAR szId[38 + 1];
+ OLECHAR szId[38 /*GUID*/ + 1 /*terminator*/];
GUID guid;
if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0
&& SUCCEEDED(IIDFromString(szId, &guid))
- && memcmp(&guid, &interfaces_head->iface->guid, sizeof(GUID)) == 0)
+ && memcmp(&guid, &pInterface->guid, sizeof(GUID)) == 0)
{
if (p->OperStatus == IfOperStatusUp)
{
}
}
CoTaskMemFree(szInterfaceId);
-
- struct interface_node *p = interfaces_head;
- interfaces_head = interfaces_head->next;
- free(p);
}
szTAPInterfacesTail [0] = 0;
szTAPInterfacesActiveTail[0] = 0;
TEXT("Commands:\n")
TEXT("\n")
TEXT("create Create a new TUN/TAP interface\n")
- TEXT("list List network interfaces\n")
+ TEXT("list List TUN/TAP interfaces\n")
TEXT("delete Delete specified network interface\n")
TEXT("help Display this text\n")
TEXT("\n")
static const TCHAR usage_message_list[] =
TEXT("%s\n")
TEXT("\n")
- TEXT("Lists network interfaces\n")
+ TEXT("Lists TUN/TAP interfaces\n")
TEXT("\n")
TEXT("Usage:\n")
TEXT("\n")
TEXT("\n")
TEXT("Output:\n")
TEXT("\n")
- TEXT("This command prints all network interfaces to stdout. \n")
+ TEXT("This command prints all TUN/TAP interfaces to stdout. \n")
;
static const TCHAR usage_message_delete[] =
if (szName)
{
- /* Get the list of available interfaces. */
+ /* Get the list of all available interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
if (dwResult != ERROR_SUCCESS)
{
_ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
}
else if (_tcsicmp(argv[1], TEXT("list")) == 0)
{
- /* Output list of network interfaces. */
+ /* Output list of TUN/TAP interfaces. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
if (dwResult != ERROR_SUCCESS)
{
- _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
+ _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult);
iResult = 1; goto quit;
}
{
/* The argument failed to covert to GUID. Treat it as the interface name. */
struct tap_interface_node *pInterfaceList = NULL;
- DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
+ DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
if (dwResult != ERROR_SUCCESS)
{
- _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
+ _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult);
iResult = 1; goto quit;
}
DWORD
tap_list_interfaces(
_In_opt_ HWND hwndParent,
- _Out_ struct tap_interface_node **ppInterface)
+ _Out_ struct tap_interface_node **ppInterface,
+ _In_ BOOL bAll)
{
DWORD dwResult;
}
}
- /* Get interface GUID. */
- GUID guidInterface;
- dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface);
- if (dwResult != ERROR_SUCCESS)
- {
- /* Something is wrong with this device. Skip it. */
- continue;
- }
-
- /* Get the interface GUID as string. */
- LPOLESTR szInterfaceId = NULL;
- StringFromIID((REFIID)&guidInterface, &szInterfaceId);
-
/* Get device hardware ID(s). */
DWORD dwDataType = REG_NONE;
LPTSTR szzDeviceHardwareIDs = NULL;
(LPVOID)&szzDeviceHardwareIDs);
if (dwResult != ERROR_SUCCESS)
{
- goto cleanup_szInterfaceId;
+ /* Something is wrong with this device. Skip it. */
+ continue;
}
+ /* Check that hardware ID is REG_SZ/REG_MULTI_SZ, and optionally if it matches ours. */
+ if (dwDataType == REG_SZ)
+ {
+ if (!bAll && _tcsicmp(szzDeviceHardwareIDs, szzHardwareIDs) != 0)
+ {
+ /* This is not our device. Skip it. */
+ goto cleanup_szzDeviceHardwareIDs;
+ }
+ }
+ else if (dwDataType == REG_MULTI_SZ)
+ {
+ if (!bAll)
+ {
+ for (LPTSTR szHwdID = szzDeviceHardwareIDs;; szHwdID += _tcslen(szHwdID) + 1)
+ {
+ if (szHwdID[0] == 0)
+ {
+ /* This is not our device. Skip it. */
+ goto cleanup_szzDeviceHardwareIDs;
+ }
+ else if (_tcsicmp(szHwdID, szzHardwareIDs) == 0)
+ {
+ /* This is our device. */
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Unexpected hardware ID format. Skip device. */
+ goto cleanup_szzDeviceHardwareIDs;
+ }
+
+ /* Get interface GUID. */
+ GUID guidInterface;
+ dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface);
+ if (dwResult != ERROR_SUCCESS)
+ {
+ /* Something is wrong with this device. Skip it. */
+ goto cleanup_szzDeviceHardwareIDs;
+ }
+
+ /* Get the interface GUID as string. */
+ LPOLESTR szInterfaceId = NULL;
+ StringFromIID((REFIID)&guidInterface, &szInterfaceId);
+
/* Render registry key path. */
TCHAR szRegKey[INTERFACE_REGKEY_PATH_MAX];
_stprintf_s(
{
SetLastError(dwResult); /* MSDN does not mention RegOpenKeyEx() to set GetLastError(). But we do have an error code. Set last error manually. */
msg(M_WARN | M_ERRNO, "%s: RegOpenKeyEx(HKLM, \"%" PRIsLPTSTR "\") failed", __FUNCTION__, szRegKey);
- goto cleanup_szzDeviceHardwareIDs;
+ goto cleanup_szInterfaceId;
}
/* Read interface name. */
free(szName);
cleanup_hKey:
RegCloseKey(hKey);
-cleanup_szzDeviceHardwareIDs:
- free(szzDeviceHardwareIDs);
cleanup_szInterfaceId:
CoTaskMemFree(szInterfaceId);
+cleanup_szzDeviceHardwareIDs:
+ free(szzDeviceHardwareIDs);
}
dwResult = ERROR_SUCCESS;
/**
- * Deletes a TUN/TAP interface.
+ * Deletes an interface.
*
* @param hwndParent A handle to the top-level window to use for any user interface that is
* related to non-device-specific actions (such as a select-device dialog
* the list. After the list is no longer required, free it using
* tap_free_interface_list().
*
+ * @param bAll When TRUE, all network interfaces found are added to the list. When
+ * FALSE, only TUN/TAP interfaces found are added.
+ *
* @return ERROR_SUCCESS on success; Win32 error code otherwise
*/
DWORD
tap_list_interfaces(
_In_opt_ HWND hwndParent,
- _Out_ struct tap_interface_node **ppInterfaceList);
+ _Out_ struct tap_interface_node **ppInterfaceList,
+ _In_ BOOL bAll);
/**