src/openvpn/win32.h
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 */