⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tap-win32.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  TAP-Win32 -- A kernel driver to provide virtual tap device functionality *               on Windows.  Originally derived from the CIPE-Win32 *               project by Damion K. Wilson, with extensive modifications by *               James Yonan. * *  All source code which derives from the CIPE-Win32 project is *  Copyright (C) Damion K. Wilson, 2003, and is released under the *  GPL version 2 (see below). * *  All other source code is Copyright (C) James Yonan, 2003-2004, *  and is released under the GPL version 2 (see below). * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program (see the file COPYING included with this *  distribution); if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "vl.h"#include <stdio.h>#include <windows.h>/* NOTE: PCIBus is redefined in winddk.h */#define PCIBus _PCIBus#include <ddk/ntapi.h>#include <ddk/winddk.h>#include <ddk/ntddk.h>#undef PCIBus//=============// TAP IOCTLs//=============#define TAP_CONTROL_CODE(request,method) \  CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)#define TAP_IOCTL_GET_MAC               TAP_CONTROL_CODE (1, METHOD_BUFFERED)#define TAP_IOCTL_GET_VERSION           TAP_CONTROL_CODE (2, METHOD_BUFFERED)#define TAP_IOCTL_GET_MTU               TAP_CONTROL_CODE (3, METHOD_BUFFERED)#define TAP_IOCTL_GET_INFO              TAP_CONTROL_CODE (4, METHOD_BUFFERED)#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED)#define TAP_IOCTL_SET_MEDIA_STATUS      TAP_CONTROL_CODE (6, METHOD_BUFFERED)#define TAP_IOCTL_CONFIG_DHCP_MASQ      TAP_CONTROL_CODE (7, METHOD_BUFFERED)#define TAP_IOCTL_GET_LOG_LINE          TAP_CONTROL_CODE (8, METHOD_BUFFERED)#define TAP_IOCTL_CONFIG_DHCP_SET_OPT   TAP_CONTROL_CODE (9, METHOD_BUFFERED)//=================// Registry keys//=================#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"//======================// Filesystem prefixes//======================#define USERMODEDEVICEDIR "\\\\.\\Global\\"#define TAPSUFFIX         ".tap"//======================// Compile time configuration//======================//#define DEBUG_TAP_WIN32 1#define TUN_ASYNCHRONOUS_WRITES 1#define TUN_BUFFER_SIZE 1560#define TUN_MAX_BUFFER_COUNT 32/* * The data member "buffer" must be the first element in the tun_buffer * structure. See the function, tap_win32_free_buffer. */typedef struct tun_buffer_s {    unsigned char buffer [TUN_BUFFER_SIZE];    unsigned long read_size;    struct tun_buffer_s* next;} tun_buffer_t;typedef struct tap_win32_overlapped {    HANDLE handle;    HANDLE read_event;    HANDLE write_event;    HANDLE output_queue_semaphore;    HANDLE free_list_semaphore;    CRITICAL_SECTION output_queue_cs;    CRITICAL_SECTION free_list_cs;    OVERLAPPED read_overlapped;    OVERLAPPED write_overlapped;    tun_buffer_t buffers[TUN_MAX_BUFFER_COUNT];    tun_buffer_t* free_list;    tun_buffer_t* output_queue_front;    tun_buffer_t* output_queue_back;} tap_win32_overlapped_t;static tap_win32_overlapped_t tap_overlapped;static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped) {    tun_buffer_t* buffer = NULL;    WaitForSingleObject(overlapped->free_list_semaphore, INFINITE);    EnterCriticalSection(&overlapped->free_list_cs);    buffer = overlapped->free_list;//    assert(buffer != NULL);    overlapped->free_list = buffer->next;    LeaveCriticalSection(&overlapped->free_list_cs);    buffer->next = NULL;    return buffer;}static void put_buffer_on_free_list(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer){    EnterCriticalSection(&overlapped->free_list_cs);    buffer->next = overlapped->free_list;    overlapped->free_list = buffer;    LeaveCriticalSection(&overlapped->free_list_cs);    ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL);}static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block) {    tun_buffer_t* buffer = NULL;    DWORD result, timeout = block ? INFINITE : 0L;    // Non-blocking call    result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout);     switch (result)     {         // The semaphore object was signaled.        case WAIT_OBJECT_0:             EnterCriticalSection(&overlapped->output_queue_cs);            buffer = overlapped->output_queue_front;            overlapped->output_queue_front = buffer->next;            if(overlapped->output_queue_front == NULL) {                overlapped->output_queue_back = NULL;            }            LeaveCriticalSection(&overlapped->output_queue_cs);            break;         // Semaphore was nonsignaled, so a time-out occurred.        case WAIT_TIMEOUT:             // Cannot open another window.            break;     }    return buffer;}static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped) {    return get_buffer_from_output_queue(overlapped, 0);}static void put_buffer_on_output_queue(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer){    EnterCriticalSection(&overlapped->output_queue_cs);    if(overlapped->output_queue_front == NULL && overlapped->output_queue_back == NULL) {        overlapped->output_queue_front = overlapped->output_queue_back = buffer;    } else {        buffer->next = NULL;        overlapped->output_queue_back->next = buffer;        overlapped->output_queue_back = buffer;    }    LeaveCriticalSection(&overlapped->output_queue_cs);    ReleaseSemaphore(overlapped->output_queue_semaphore, 1, NULL);}static int is_tap_win32_dev(const char *guid){    HKEY netcard_key;    LONG status;    DWORD len;    int i = 0;    status = RegOpenKeyEx(        HKEY_LOCAL_MACHINE,        ADAPTER_KEY,        0,        KEY_READ,        &netcard_key);    if (status != ERROR_SUCCESS) {        return FALSE;    }    for (;;) {        char enum_name[256];        char unit_string[256];        HKEY unit_key;        char component_id_string[] = "ComponentId";        char component_id[256];        char net_cfg_instance_id_string[] = "NetCfgInstanceId";        char net_cfg_instance_id[256];        DWORD data_type;        len = sizeof (enum_name);        status = RegEnumKeyEx(            netcard_key,            i,            enum_name,            &len,            NULL,            NULL,            NULL,            NULL);        if (status == ERROR_NO_MORE_ITEMS)            break;        else if (status != ERROR_SUCCESS) {            return FALSE;        }        snprintf (unit_string, sizeof(unit_string), "%s\\%s",                  ADAPTER_KEY, enum_name);        status = RegOpenKeyEx(            HKEY_LOCAL_MACHINE,            unit_string,            0,            KEY_READ,            &unit_key);        if (status != ERROR_SUCCESS) {            return FALSE;        } else {            len = sizeof (component_id);            status = RegQueryValueEx(                unit_key,                component_id_string,                NULL,                &data_type,                component_id,                &len);            if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) {                len = sizeof (net_cfg_instance_id);                status = RegQueryValueEx(                    unit_key,                    net_cfg_instance_id_string,                    NULL,                    &data_type,                    net_cfg_instance_id,                    &len);                if (status == ERROR_SUCCESS && data_type == REG_SZ) {                    if (/* !strcmp (component_id, TAP_COMPONENT_ID) &&*/                        !strcmp (net_cfg_instance_id, guid)) {                        RegCloseKey (unit_key);                        RegCloseKey (netcard_key);                        return TRUE;                    }                }            }            RegCloseKey (unit_key);        }        ++i;    }    RegCloseKey (netcard_key);    return FALSE;}static int get_device_guid(    char *name,    int name_size,    char *actual_name,    int actual_name_size){    LONG status;    HKEY control_net_key;    DWORD len;    int i = 0;    int stop = 0;    status = RegOpenKeyEx(        HKEY_LOCAL_MACHINE,        NETWORK_CONNECTIONS_KEY,        0,        KEY_READ,        &control_net_key);    if (status != ERROR_SUCCESS) {        return -1;    }    while (!stop)    {        char enum_name[256];        char connection_string[256];        HKEY connection_key;        char name_data[256];        DWORD name_type;        const char name_string[] = "Name";        len = sizeof (enum_name);        status = RegEnumKeyEx(            control_net_key,            i,            enum_name,            &len,            NULL,            NULL,            NULL,            NULL);        if (status == ERROR_NO_MORE_ITEMS)            break;        else if (status != ERROR_SUCCESS) {            return -1;        }        snprintf(connection_string,              sizeof(connection_string),             "%s\\%s\\Connection",             NETWORK_CONNECTIONS_KEY, enum_name);        status = RegOpenKeyEx(            HKEY_LOCAL_MACHINE,            connection_string,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -