35 #pragma comment(lib, "ole32.lib")
36 #pragma comment(lib, "setupapi.lib")
53 TEXT("create Create a new TUN/TAP adapter\n")
54 TEXT("list List TUN/TAP adapters\n")
55 TEXT("delete Delete specified network adapter\n")
56 TEXT("help Display this text\n")
58 TEXT("Hint: Use \"tapctl help <
command>\" to display help for particular
command.\n")
64 TEXT("Creates a new TUN/TAP adapter\n")
68 TEXT("tapctl create [<
options>]\n")
72 TEXT("--name <name> Set TUN/TAP adapter name. Should the adapter with given name \n")
73 TEXT(" already exist, an error is returned. If this option is not \n")
74 TEXT(" specified, a default adapter name is chosen by Windows. \n")
75 TEXT(" Note: This name can also be specified as OpenVPN's --dev-node \n")
77 TEXT("--hwid <hwid> Adapter hardware ID. Default value is root\\tap0901, which \n")
78 TEXT(" describes tap-windows6 driver. To work with wintun or ovpn-dco \n")
79 TEXT(" driver, specify 'wintun' or 'ovpn-dco'. \n")
83 TEXT("This
command prints newly created TUN/TAP adapter's GUID to stdout. \n")
89 TEXT("Lists TUN/TAP adapters\n")
97 TEXT("--hwid <hwid> Adapter hardware ID. By default, root\\tap0901, tap0901, wintun and \n")
98 TEXT(" ovpn-dco adapters are listed. Use this switch to limit the list.\n")
102 TEXT("This
command prints all TUN/TAP adapters to stdout. \n")
108 TEXT("Deletes the specified network adapter\n")
112 TEXT("tapctl delete <adapter GUID | adapter name>\n")
135 if (_tcsicmp(name, a->szName) == 0)
139 LPOLESTR adapter_id = NULL;
140 StringFromIID((REFIID)&a->guid, &adapter_id);
141 _ftprintf(stderr, TEXT(
"Adapter \"%") TEXT(
PRIsLPTSTR) TEXT(
"\" already exists (GUID %")
142 TEXT(
PRIsLPOLESTR) TEXT(
").\n"), a->szName, adapter_id);
143 CoTaskMemFree(adapter_id);
166 if (_tcsicmp(hwid, TEXT(
"ovpn-dco")) == 0)
168 base_name = TEXT(
"OpenVPN Data Channel Offload");
170 else if (_tcsicmp(hwid, TEXT(
"wintun")) == 0)
172 base_name = TEXT(
"OpenVPN Wintun");
176 base_name = TEXT(
"OpenVPN TAP-Windows6");
185 return _tcsdup(base_name);
188 size_t name_len = _tcslen(base_name) + 10;
189 LPTSTR name = malloc(name_len *
sizeof(TCHAR));
194 for (
int i = 1; i < 100; ++i)
196 _stprintf_s(name, name_len, TEXT(
"%ls #%d"), base_name, i);
214 BOOL bRebootRequired = FALSE;
217 SetupSetNonInteractiveMode(TRUE);
224 else if (_tcsicmp(
argv[1], TEXT(
"help")) == 0)
231 else if (_tcsicmp(
argv[2], TEXT(
"create")) == 0)
235 else if (_tcsicmp(
argv[2], TEXT(
"list")) == 0)
239 else if (_tcsicmp(
argv[2], TEXT(
"delete")) == 0)
245 _ftprintf(stderr, TEXT(
"Unknown command \"%") TEXT(
PRIsLPTSTR)
246 TEXT(
"\". Please, use \"tapctl help\" to list supported commands.\n"),
argv[2]);
251 else if (_tcsicmp(
argv[1], TEXT(
"create")) == 0)
253 LPCTSTR szName = NULL;
257 for (
int i = 2; i < argc; i++)
259 if (_tcsicmp(
argv[i], TEXT(
"--name")) == 0)
263 else if (_tcsicmp(
argv[i], TEXT(
"--hwid")) == 0)
269 _ftprintf(stderr, TEXT(
"Unknown option \"%") TEXT(
PRIsLPTSTR)
270 TEXT(
"\". Please, use \"tapctl help create\" to list supported options. Ignored.\n"),
277 LPOLESTR szAdapterId = NULL;
280 TEXT(
"Virtual Ethernet"),
284 if (dwResult != ERROR_SUCCESS)
286 _ftprintf(stderr, TEXT(
"Creating TUN/TAP adapter failed (error 0x%x).\n"), dwResult);
287 iResult = 1;
goto quit;
293 if (dwResult != ERROR_SUCCESS)
295 _ftprintf(stderr, TEXT(
"Enumerating adapters failed (error 0x%x).\n"), dwResult);
297 goto create_delete_adapter;
308 goto create_cleanup_pAdapterList;
313 if (dwResult != ERROR_SUCCESS)
315 StringFromIID((REFIID)&guidAdapter, &szAdapterId);
316 _ftprintf(stderr, TEXT(
"Renaming TUN/TAP adapter %") TEXT(
PRIsLPOLESTR)
317 TEXT(
" to \"%") TEXT(
PRIsLPTSTR) TEXT(
"\" failed (error 0x%x).\n"),
318 szAdapterId, adapter_name, dwResult);
319 CoTaskMemFree(szAdapterId);
320 iResult = 1;
goto quit;
326 create_cleanup_pAdapterList:
332 goto create_delete_adapter;
336 StringFromIID((REFIID)&guidAdapter, &szAdapterId);
337 _ftprintf(stdout, TEXT(
"%") TEXT(
PRIsLPOLESTR) TEXT(
"\n"), szAdapterId);
338 CoTaskMemFree(szAdapterId);
340 iResult = 0;
goto quit;
342 create_delete_adapter:
347 iResult = 1;
goto quit;
349 else if (_tcsicmp(
argv[1], TEXT(
"list")) == 0)
351 TCHAR szzHwId[0x100] =
358 for (
int i = 2; i < argc; i++)
360 if (_tcsicmp(
argv[i], TEXT(
"--hwid")) == 0)
362 memset(szzHwId, 0,
sizeof(szzHwId));
364 memcpy_s(szzHwId,
sizeof(szzHwId) - 2*
sizeof(TCHAR) ,
argv[i], _tcslen(
argv[i])*
sizeof(TCHAR));
368 _ftprintf(stderr, TEXT(
"Unknown option \"%") TEXT(
PRIsLPTSTR)
369 TEXT(
"\". Please, use \"tapctl help list\" to list supported options. Ignored.\n"),
377 if (dwResult != ERROR_SUCCESS)
379 _ftprintf(stderr, TEXT(
"Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult);
380 iResult = 1;
goto quit;
385 LPOLESTR szAdapterId = NULL;
386 StringFromIID((REFIID)&pAdapter->guid, &szAdapterId);
387 _ftprintf(stdout, TEXT(
"%") TEXT(
PRIsLPOLESTR) TEXT(
"\t%")
388 TEXT(
PRIsLPTSTR) TEXT(
"\n"), szAdapterId, pAdapter->szName);
389 CoTaskMemFree(szAdapterId);
395 else if (_tcsicmp(
argv[1], TEXT(
"delete")) == 0)
399 _ftprintf(stderr, TEXT(
"Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n"));
404 if (FAILED(IIDFromString(
argv[2], (LPIID)&guidAdapter)))
409 if (dwResult != ERROR_SUCCESS)
411 _ftprintf(stderr, TEXT(
"Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult);
412 iResult = 1;
goto quit;
417 if (pAdapter == NULL)
419 _ftprintf(stderr, TEXT(
"\"%") TEXT(
PRIsLPTSTR) TEXT(
"\" adapter not found.\n"),
argv[2]);
420 iResult = 1;
goto delete_cleanup_pAdapterList;
422 else if (_tcsicmp(
argv[2], pAdapter->szName) == 0)
424 memcpy(&guidAdapter, &pAdapter->guid,
sizeof(GUID));
431 delete_cleanup_pAdapterList:
444 if (dwResult != ERROR_SUCCESS)
446 _ftprintf(stderr, TEXT(
"Deleting adapter \"%") TEXT(
PRIsLPTSTR)
447 TEXT(
"\" failed (error 0x%x).\n"),
argv[2], dwResult);
448 iResult = 1;
goto quit;
451 iResult = 0;
goto quit;
455 _ftprintf(stderr, TEXT(
"Unknown command \"%") TEXT(
PRIsLPTSTR)
456 TEXT(
"\". Please, use \"tapctl help\" to list supported commands.\n"),
argv[1]);
463 _ftprintf(stderr, TEXT(
"A system reboot is required.\n"));
473 UNREFERENCED_PARAMETER(flags);
480 x_msg_va(
const unsigned int flags,
const char *format, va_list arglist)
483 vfprintf(stderr, format, arglist);
484 _ftprintf(stderr, TEXT(
"\n"));
489 DWORD dwResult = GetLastError();
490 LPTSTR szErrMessage = NULL;
492 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
496 (LPTSTR)&szErrMessage,
498 NULL) && szErrMessage)
501 for (
size_t i = 0, i_last = 0;; i++)
505 if (!_istspace(szErrMessage[i]))
512 szErrMessage[i_last] = 0;
518 _ftprintf(stderr, TEXT(
"Error 0x%x: %") TEXT(
PRIsLPTSTR) TEXT(
"\n"), dwResult, szErrMessage);
520 LocalFree(szErrMessage);
524 _ftprintf(stderr, TEXT(
"Error 0x%x\n"), dwResult);