18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TAP-Win32 -- A kernel driver to provide virtual tap device functionality 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * on Windows. Originally derived from the CIPE-Win32 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * project by Damion K. Wilson, with extensive modifications by 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * James Yonan. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * All source code which derives from the CIPE-Win32 project is 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (C) Damion K. Wilson, 2003, and is released under the 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * GPL version 2 (see below). 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * All other source code is Copyright (C) James Yonan, 2003-2004, 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and is released under the GPL version 2 (see below). 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This program is free software; you can redistribute it and/or modify 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it under the terms of the GNU General Public License as published by 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the Free Software Foundation; either version 2 of the License, or 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (at your option) any later version. 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This program is distributed in the hope that it will be useful, 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * GNU General Public License for more details. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You should have received a copy of the GNU General Public License 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * along with this program (see the file COPYING included with this 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * distribution); if not, write to the Free Software Foundation, Inc., 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 30cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "net/net.h" 3134c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h" 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <windows.h> 347f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh#include <winioctl.h> 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//============= 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// TAP IOCTLs 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//============= 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_CONTROL_CODE(request,method) \ 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//================= 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Registry keys 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//================= 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//====================== 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Filesystem prefixes 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//====================== 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USERMODEDEVICEDIR "\\\\.\\Global\\" 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TAPSUFFIX ".tap" 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//====================== 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Compile time configuration 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//====================== 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_TAP_WIN32 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TUN_ASYNCHRONOUS_WRITES 1 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TUN_BUFFER_SIZE 1560 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TUN_MAX_BUFFER_COUNT 32 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The data member "buffer" must be the first element in the tun_buffer 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * structure. See the function, tap_win32_free_buffer. 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct tun_buffer_s { 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char buffer [TUN_BUFFER_SIZE]; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long read_size; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tun_buffer_s* next; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} tun_buffer_t; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct tap_win32_overlapped { 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE handle; 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE read_event; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE write_event; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE output_queue_semaphore; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE free_list_semaphore; 965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner HANDLE tap_semaphore; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CRITICAL_SECTION output_queue_cs; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CRITICAL_SECTION free_list_cs; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OVERLAPPED read_overlapped; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OVERLAPPED write_overlapped; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t buffers[TUN_MAX_BUFFER_COUNT]; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* free_list; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* output_queue_front; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* output_queue_back; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} tap_win32_overlapped_t; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic tap_win32_overlapped_t tap_overlapped; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped) 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* buffer = NULL; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WaitForSingleObject(overlapped->free_list_semaphore, INFINITE); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EnterCriticalSection(&overlapped->free_list_cs); 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer = overlapped->free_list; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// assert(buffer != NULL); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->free_list = buffer->next; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LeaveCriticalSection(&overlapped->free_list_cs); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer->next = NULL; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buffer; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void put_buffer_on_free_list(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer) 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EnterCriticalSection(&overlapped->free_list_cs); 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer->next = overlapped->free_list; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->free_list = buffer; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LeaveCriticalSection(&overlapped->free_list_cs); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL); 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block) 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* buffer = NULL; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD result, timeout = block ? INFINITE : 0L; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // Non-blocking call 1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (result) 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // The semaphore object was signaled. 1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case WAIT_OBJECT_0: 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EnterCriticalSection(&overlapped->output_queue_cs); 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer = overlapped->output_queue_front; 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->output_queue_front = buffer->next; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(overlapped->output_queue_front == NULL) { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->output_queue_back = NULL; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LeaveCriticalSection(&overlapped->output_queue_cs); 1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // Semaphore was nonsignaled, so a time-out occurred. 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case WAIT_TIMEOUT: 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // Cannot open another window. 1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buffer; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped) 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_buffer_from_output_queue(overlapped, 0); 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void put_buffer_on_output_queue(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer) 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EnterCriticalSection(&overlapped->output_queue_cs); 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(overlapped->output_queue_front == NULL && overlapped->output_queue_back == NULL) { 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->output_queue_front = overlapped->output_queue_back = buffer; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer->next = NULL; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->output_queue_back->next = buffer; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->output_queue_back = buffer; 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LeaveCriticalSection(&overlapped->output_queue_cs); 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ReleaseSemaphore(overlapped->output_queue_semaphore, 1, NULL); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int is_tap_win32_dev(const char *guid) 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY netcard_key; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LONG status; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD len; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i = 0; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegOpenKeyEx( 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY_LOCAL_MACHINE, 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ADAPTER_KEY, 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project KEY_READ, 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &netcard_key); 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status != ERROR_SUCCESS) { 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return FALSE; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char enum_name[256]; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char unit_string[256]; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY unit_key; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char component_id_string[] = "ComponentId"; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char component_id[256]; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char net_cfg_instance_id_string[] = "NetCfgInstanceId"; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char net_cfg_instance_id[256]; 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD data_type; 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof (enum_name); 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegEnumKeyEx( 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project netcard_key, 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i, 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enum_name, 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &len, 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL); 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status == ERROR_NO_MORE_ITEMS) 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (status != ERROR_SUCCESS) { 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return FALSE; 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf (unit_string, sizeof(unit_string), "%s\\%s", 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ADAPTER_KEY, enum_name); 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegOpenKeyEx( 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY_LOCAL_MACHINE, 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unit_string, 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project KEY_READ, 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &unit_key); 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status != ERROR_SUCCESS) { 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return FALSE; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof (component_id); 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegQueryValueEx( 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unit_key, 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project component_id_string, 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &data_type, 2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (LPBYTE)component_id, 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &len); 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) { 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof (net_cfg_instance_id); 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegQueryValueEx( 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unit_key, 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project net_cfg_instance_id_string, 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &data_type, 2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (LPBYTE)net_cfg_instance_id, 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &len); 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status == ERROR_SUCCESS && data_type == REG_SZ) { 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (/* !strcmp (component_id, TAP_COMPONENT_ID) &&*/ 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !strcmp (net_cfg_instance_id, guid)) { 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (unit_key); 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (netcard_key); 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return TRUE; 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (unit_key); 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ++i; 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (netcard_key); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return FALSE; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_device_guid( 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *name, 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int name_size, 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *actual_name, 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int actual_name_size) 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LONG status; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY control_net_key; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD len; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i = 0; 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int stop = 0; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegOpenKeyEx( 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY_LOCAL_MACHINE, 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NETWORK_CONNECTIONS_KEY, 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project KEY_READ, 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &control_net_key); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status != ERROR_SUCCESS) { 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (!stop) 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char enum_name[256]; 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char connection_string[256]; 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY connection_key; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char name_data[256]; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD name_type; 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char name_string[] = "Name"; 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof (enum_name); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegEnumKeyEx( 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project control_net_key, 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i, 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enum_name, 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &len, 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status == ERROR_NO_MORE_ITEMS) 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (status != ERROR_SUCCESS) { 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner snprintf(connection_string, 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(connection_string), 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%s\\%s\\Connection", 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NETWORK_CONNECTIONS_KEY, enum_name); 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegOpenKeyEx( 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HKEY_LOCAL_MACHINE, 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project connection_string, 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project KEY_READ, 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &connection_key); 3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status == ERROR_SUCCESS) { 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof (name_data); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project status = RegQueryValueEx( 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project connection_key, 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project name_string, 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &name_type, 3505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (LPBYTE)name_data, 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &len); 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (status != ERROR_SUCCESS || name_type != REG_SZ) { 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_tap_win32_dev(enum_name)) { 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(name, name_size, "%s", enum_name); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (actual_name) { 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strcmp(actual_name, "") != 0) { 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strcmp(name_data, actual_name) != 0) { 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (connection_key); 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ++i; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(actual_name, actual_name_size, "%s", name_data); 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stop = 1; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (connection_key); 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ++i; 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RegCloseKey (control_net_key); 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (stop == 0) 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tap_win32_set_status(HANDLE handle, int status) 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long len = 0; 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS, 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &status, sizeof (status), 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &status, sizeof (status), &len, NULL); 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, const HANDLE handle) 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->handle = handle; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->read_event = CreateEvent(NULL, FALSE, FALSE, NULL); 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->write_event = CreateEvent(NULL, FALSE, FALSE, NULL); 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->read_overlapped.Offset = 0; 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->read_overlapped.OffsetHigh = 0; 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->read_overlapped.hEvent = overlapped->read_event; 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->write_overlapped.Offset = 0; 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->write_overlapped.OffsetHigh = 0; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->write_overlapped.hEvent = overlapped->write_event; 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project InitializeCriticalSection(&overlapped->output_queue_cs); 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project InitializeCriticalSection(&overlapped->free_list_cs); 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner overlapped->output_queue_semaphore = CreateSemaphore( 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, // default security attributes 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, // initial count 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TUN_MAX_BUFFER_COUNT, // maximum count 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL); // unnamed semaphore 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(!overlapped->output_queue_semaphore) { 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "error creating output queue semaphore!\n"); 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner overlapped->free_list_semaphore = CreateSemaphore( 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, // default security attributes 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TUN_MAX_BUFFER_COUNT, // initial count 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TUN_MAX_BUFFER_COUNT, // maximum count 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL); // unnamed semaphore 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(!overlapped->free_list_semaphore) { 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "error creating free list semaphore!\n"); 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->free_list = overlapped->output_queue_front = overlapped->output_queue_back = NULL; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned index; 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(index = 0; index < TUN_MAX_BUFFER_COUNT; index++) { 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* element = &overlapped->buffers[index]; 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project element->next = overlapped->free_list; 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overlapped->free_list = element; 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* To count buffers, initially no-signal. */ 4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner overlapped->tap_semaphore = CreateSemaphore(NULL, 0, TUN_MAX_BUFFER_COUNT, NULL); 4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if(!overlapped->tap_semaphore) 4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(stderr, "error creating tap_semaphore.\n"); 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tap_win32_write(tap_win32_overlapped_t *overlapped, 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const void *buffer, unsigned long size) 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long write_size; 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BOOL result; 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD error; 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = GetOverlappedResult( overlapped->handle, &overlapped->write_overlapped, 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &write_size, FALSE); 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result && GetLastError() == ERROR_IO_INCOMPLETE) 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WaitForSingleObject(overlapped->write_event, INFINITE); 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = WriteFile(overlapped->handle, buffer, size, 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &write_size, &overlapped->write_overlapped); 4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!result) { 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (error = GetLastError()) 4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case ERROR_IO_PENDING: 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef TUN_ASYNCHRONOUS_WRITES 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WaitForSingleObject(overlapped->write_event, INFINITE); 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic DWORD WINAPI tap_win32_thread_entry(LPVOID param) 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tap_win32_overlapped_t *overlapped = (tap_win32_overlapped_t*)param; 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long read_size; 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BOOL result; 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD dwError; 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* buffer = get_buffer_from_free_list(overlapped); 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = ReadFile(overlapped->handle, 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer->buffer, 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(buffer->buffer), 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &read_size, 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &overlapped->read_overlapped); 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result) { 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dwError = GetLastError(); 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dwError == ERROR_IO_PENDING) { 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WaitForSingleObject(overlapped->read_event, INFINITE); 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = GetOverlappedResult( overlapped->handle, &overlapped->read_overlapped, 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &read_size, FALSE); 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!result) { 5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_TAP_WIN32 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LPVOID lpBuffer; 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dwError = GetLastError(); 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (LPTSTR) & lpBuffer, 0, NULL ); 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "Tap-Win32: Error GetOverlappedResult %d - %s\n", dwError, lpBuffer); 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LocalFree( lpBuffer ); 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_TAP_WIN32 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LPVOID lpBuffer; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (LPTSTR) & lpBuffer, 0, NULL ); 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "Tap-Win32: Error ReadFile %d - %s\n", dwError, lpBuffer); 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LocalFree( lpBuffer ); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(read_size > 0) { 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer->read_size = read_size; 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put_buffer_on_output_queue(overlapped, buffer); 5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ReleaseSemaphore(overlapped->tap_semaphore, 1, NULL); 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buffer = get_buffer_from_free_list(overlapped); 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tap_win32_read(tap_win32_overlapped_t *overlapped, 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t **pbuf, int max_size) 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int size = 0; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* buffer = get_buffer_from_output_queue_immediate(overlapped); 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(buffer != NULL) { 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbuf = buffer->buffer; 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = (int)buffer->read_size; 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(size > max_size) { 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = max_size; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return size; 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped, 5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *pbuf) 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tun_buffer_t* buffer = (tun_buffer_t*)pbuf; 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put_buffer_on_free_list(overlapped, buffer); 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tap_win32_open(tap_win32_overlapped_t **phandle, 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *prefered_name) 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char device_path[256]; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char device_guid[0x100]; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int rc; 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HANDLE handle; 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BOOL bret; 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char name_buffer[0x100] = {0, }; 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct { 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long major; 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long minor; 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long debug; 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } version; 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DWORD version_len; 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD idThread; 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (prefered_name != NULL) 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(name_buffer, sizeof(name_buffer), "%s", prefered_name); 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer)); 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rc) 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf (device_path, sizeof(device_path), "%s%s%s", 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project USERMODEDEVICEDIR, 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project device_guid, 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TAPSUFFIX); 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project handle = CreateFile ( 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project device_path, 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GENERIC_READ | GENERIC_WRITE, 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0, 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OPEN_EXISTING, 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0 ); 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (handle == INVALID_HANDLE_VALUE) { 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bret = DeviceIoControl(handle, TAP_IOCTL_GET_VERSION, 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &version, sizeof (version), 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &version, sizeof (version), &version_len, NULL); 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bret == FALSE) { 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CloseHandle(handle); 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tap_win32_set_status(handle, TRUE)) { 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tap_win32_overlapped_init(&tap_overlapped, handle); 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *phandle = &tap_overlapped; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6227891dd35fa2439a70f43ab8572778a398365bf24David 'Digit' Turner (void) CreateThread(NULL, 0, tap_win32_thread_entry, 6237891dd35fa2439a70f43ab8572778a398365bf24David 'Digit' Turner (LPVOID)&tap_overlapped, 0, &idThread); 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************/ 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project typedef struct TAPState { 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project VLANClientState *vc; 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tap_win32_overlapped_t *handle; 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } TAPState; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tap_cleanup(VLANClientState *vc) 6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TAPState *s = vc->opaque; 6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_del_wait_object(s->handle->tap_semaphore, NULL, NULL); 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* FIXME: need to kill thread and close file handle: 6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tap_win32_close(s); 6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 643aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(s); 6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size) 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TAPState *s = vc->opaque; 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return tap_win32_write(s->handle, buf, size); 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tap_win32_send(void *opaque) 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TAPState *s = opaque; 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf; 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int max_size = 4096; 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int size; 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = tap_win32_read(s->handle, &buf, max_size); 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size > 0) { 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_send_packet(s->vc, buf, size); 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tap_win32_free_buffer(s->handle, buf); 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tap_win32_init(VLANState *vlan, const char *model, 6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *name, const char *ifname) 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TAPState *s; 6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 672aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner s = g_malloc0(sizeof(TAPState)); 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s) 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tap_win32_open(&s->handle, ifname) < 0) { 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("tap: Could not open '%s'\n", ifname); 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->vc = qemu_new_vlan_client(vlan, model, name, NULL, tap_receive, 6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner NULL, tap_cleanup, s); 6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(s->vc->info_str, sizeof(s->vc->info_str), 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "tap: ifname=%s", ifname); 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_add_wait_object(s->handle->tap_semaphore, tap_win32_send, s); 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 689