6fbf66fa |
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
* |
49979459 |
* Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> |
6fbf66fa |
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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.
* |
caa54ac3 |
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
6fbf66fa |
*/
|
445b192a |
#ifdef _WIN32 |
6fbf66fa |
#ifndef OPENVPN_WIN32_H
#define OPENVPN_WIN32_H
#include "mtu.h" |
717c1930 |
#include "openvpn-msg.h" |
253f0155 |
#include "argv.h" |
6fbf66fa |
|
5a2e9a25 |
/* location of executables */
#define SYS_PATH_ENV_VAR_NAME "SystemRoot" /* environmental variable name that normally contains the system path */
#define NETSH_PATH_SUFFIX "\\system32\\netsh.exe"
#define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe" |
b90c6f17 |
#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe" |
75dfe3d7 |
#define WIN_NET_PATH_SUFFIX "\\system32\\net.exe" |
5a2e9a25 |
|
6fbf66fa |
/*
* Win32-specific OpenVPN code, targetted at the mingw
* development environment.
*/
|
82167eb2 |
/* MSVC headers do not define this macro, so do it here */
#ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL(a,b) \ |
81d882d5 |
(memcmp((const void *)(a), (const void *)(b), sizeof(struct in6_addr)) == 0) |
82167eb2 |
#endif
|
81d882d5 |
void init_win32(void); |
6fbf66fa |
|
81d882d5 |
void uninit_win32(void);
void set_pause_exit_win32(void); |
6fbf66fa |
struct security_attributes
{ |
81d882d5 |
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd; |
6fbf66fa |
};
#define HANDLE_DEFINED(h) ((h) != NULL && (h) != INVALID_HANDLE_VALUE)
/*
* Save old window title.
*/
struct window_title
{ |
81d882d5 |
bool saved;
char old_window_title [256]; |
6fbf66fa |
};
struct rw_handle { |
81d882d5 |
HANDLE read;
HANDLE write; |
6fbf66fa |
};
/*
* Event-based notification of incoming TCP connections
*/
#define NE32_PERSIST_EVENT (1<<0)
#define NE32_WRITE_EVENT (1<<1)
static inline bool |
81d882d5 |
defined_net_event_win32(const struct rw_handle *event) |
6fbf66fa |
{ |
81d882d5 |
return event->read != NULL; |
6fbf66fa |
}
|
81d882d5 |
void init_net_event_win32(struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags);
long reset_net_event_win32(struct rw_handle *event, socket_descriptor_t sd);
void close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags); |
6fbf66fa |
/*
* A stateful variant of the net_event_win32 functions above
*/
struct net_event_win32
{ |
81d882d5 |
struct rw_handle handle;
socket_descriptor_t sd;
long event_mask; |
6fbf66fa |
};
|
81d882d5 |
void net_event_win32_init(struct net_event_win32 *ne);
void net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd);
void net_event_win32_reset(struct net_event_win32 *ne);
void net_event_win32_reset_write(struct net_event_win32 *ne);
void net_event_win32_stop(struct net_event_win32 *ne);
void net_event_win32_close(struct net_event_win32 *ne); |
6fbf66fa |
|
b110c9c4 |
static inline bool |
81d882d5 |
net_event_win32_defined(const struct net_event_win32 *ne) |
6fbf66fa |
{ |
81d882d5 |
return defined_net_event_win32(&ne->handle); |
6fbf66fa |
}
static inline struct rw_handle * |
81d882d5 |
net_event_win32_get_event(struct net_event_win32 *ne) |
6fbf66fa |
{ |
81d882d5 |
return &ne->handle; |
6fbf66fa |
}
static inline long |
81d882d5 |
net_event_win32_get_event_mask(const struct net_event_win32 *ne) |
6fbf66fa |
{ |
81d882d5 |
return ne->event_mask; |
6fbf66fa |
}
static inline void |
81d882d5 |
net_event_win32_clear_selected_events(struct net_event_win32 *ne, long selected_events) |
6fbf66fa |
{ |
81d882d5 |
ne->event_mask &= ~selected_events; |
6fbf66fa |
}
/*
* Signal handling
*/
struct win32_signal { |
81d882d5 |
#define WSO_MODE_UNDEF 0
#define WSO_MODE_SERVICE 1
#define WSO_MODE_CONSOLE 2
int mode;
struct rw_handle in;
DWORD console_mode_save;
bool console_mode_save_defined; |
6fbf66fa |
};
extern struct win32_signal win32_signal; /* static/global */
extern struct window_title window_title; /* static/global */
|
81d882d5 |
void win32_signal_clear(struct win32_signal *ws); |
6fbf66fa |
/* win32_signal_open startup type */
#define WSO_NOFORCE 0
#define WSO_FORCE_SERVICE 1
#define WSO_FORCE_CONSOLE 2
|
81d882d5 |
void win32_signal_open(struct win32_signal *ws,
int force, /* set to WSO force parm */
const char *exit_event_name,
bool exit_event_initial_state); |
6fbf66fa |
|
81d882d5 |
void win32_signal_close(struct win32_signal *ws); |
6fbf66fa |
|
81d882d5 |
int win32_signal_get(struct win32_signal *ws); |
6fbf66fa |
|
81d882d5 |
void win32_pause(struct win32_signal *ws); |
6fbf66fa |
|
81d882d5 |
bool win32_service_interrupt(struct win32_signal *ws); |
72c7b12c |
|
6fbf66fa |
/*
* Set the text on the window title bar
*/
|
81d882d5 |
void window_title_clear(struct window_title *wt);
void window_title_save(struct window_title *wt);
void window_title_restore(const struct window_title *wt); |
6fbf66fa |
|
81d882d5 |
void window_title_generate(const char *title);
/* |
6fbf66fa |
* We try to do all Win32 I/O using overlapped
* (i.e. asynchronous) I/O for a performance win.
*/
struct overlapped_io { |
81d882d5 |
#define IOSTATE_INITIAL 0
#define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */
#define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately without queueing */
int iostate;
OVERLAPPED overlapped;
DWORD size;
DWORD flags;
int status;
bool addr_defined;
union {
struct sockaddr_in addr;
struct sockaddr_in6 addr6;
};
int addrlen;
struct buffer buf_init;
struct buffer buf; |
6fbf66fa |
};
|
81d882d5 |
void overlapped_io_init(struct overlapped_io *o,
const struct frame *frame,
BOOL event_state,
bool tuntap_buffer); |
6fbf66fa |
|
81d882d5 |
void overlapped_io_close(struct overlapped_io *o); |
6fbf66fa |
static inline bool |
81d882d5 |
overlapped_io_active(struct overlapped_io *o) |
6fbf66fa |
{ |
81d882d5 |
return o->iostate == IOSTATE_QUEUED || o->iostate == IOSTATE_IMMEDIATE_RETURN; |
6fbf66fa |
}
|
81d882d5 |
char *overlapped_io_state_ascii(const struct overlapped_io *o); |
6fbf66fa |
/*
* Use to control access to resources that only one
* OpenVPN process on a given machine can access at
* a given time.
*/
struct semaphore
{ |
81d882d5 |
const char *name;
bool locked;
HANDLE hand; |
6fbf66fa |
};
|
81d882d5 |
void semaphore_clear(struct semaphore *s);
void semaphore_open(struct semaphore *s, const char *name);
bool semaphore_lock(struct semaphore *s, int timeout_milliseconds);
void semaphore_release(struct semaphore *s);
void semaphore_close(struct semaphore *s); |
6fbf66fa |
/*
* Special global semaphore used to protect network
* shell commands from simultaneous instantiation.
*
* It seems you can't run more than one instance
* of netsh on the same machine at the same time.
*/
extern struct semaphore netcmd_semaphore; |
81d882d5 |
void netcmd_semaphore_init(void);
void netcmd_semaphore_close(void);
void netcmd_semaphore_lock(void);
void netcmd_semaphore_release(void); |
6fbf66fa |
/* Set Win32 security attributes structure to allow all access */ |
81d882d5 |
bool init_security_attributes_allow_all(struct security_attributes *obj); |
6fbf66fa |
|
73b7e698 |
/* return true if filename is safe to be used on Windows */ |
81d882d5 |
bool win_safe_filename(const char *fn); |
73b7e698 |
|
5a2e9a25 |
/* add constant environmental variables needed by Windows */
struct env_set;
/* get and set the current windows system path */ |
81d882d5 |
void set_win_sys_path(const char *newpath, struct env_set *es);
void set_win_sys_path_via_env(struct env_set *es);
char *get_win_sys_path(void); |
5a2e9a25 |
|
5c30df12 |
/* call self in a subprocess */ |
81d882d5 |
void fork_to_self(const char *cmdline); |
53fb2c5c |
|
ca4c6d61 |
/* Find temporary directory */ |
e2a0cad4 |
const char *win_get_tempdir(void); |
ca4c6d61 |
|
71bbbd76 |
/* Convert a string from UTF-8 to UCS-2 */ |
81d882d5 |
WCHAR *wide_string(const char *utf8, struct gc_arena *gc); |
71bbbd76 |
|
2282b1be |
bool win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel); |
81d882d5 |
|
27aa8728 |
bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel); |
38c85658 |
|
cdc65ea0 |
#define WIN_XP 0
#define WIN_VISTA 1
#define WIN_7 2
#define WIN_8 3
|
e2a0cad4 |
int win32_version_info(void); |
cdc65ea0 |
/* |
81d882d5 |
* String representation of Windows version number and name, see
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx
*/
const char *win32_version_string(struct gc_arena *gc, bool add_name); |
cdc65ea0 |
|
717c1930 |
/*
* Send the |size| bytes in buffer |data| to the interactive service |pipe|
* and read the result in |ack|. Returns false on communication error.
* The string in |context| is used to prefix error messages.
*/
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size,
ack_message_t *ack, const char *context);
|
253f0155 |
/*
* Attempt to simulate fork/execve on Windows
*/
int
openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags);
|
81d882d5 |
#endif /* ifndef OPENVPN_WIN32_H */
#endif /* ifdef _WIN32 */ |