diff --git a/compat/msvc/stdint.h b/compat/msvc/stdint.h new file mode 100644 index 0000000..e236bb0 --- /dev/null +++ b/compat/msvc/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef char int8_t; + typedef short int16_t; + typedef int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/compat/msvc/sys/time.h b/compat/msvc/sys/time.h new file mode 100644 index 0000000..c4964d6 --- /dev/null +++ b/compat/msvc/sys/time.h @@ -0,0 +1,62 @@ +#pragma once + +//http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/430449b3-f6dd-4e18-84de-eebd26a8d668 +#include < time.h > +#include //I've ommited this line. +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +struct timespec { + +time_t tv_sec; /* Seconds since 00:00:00 GMT, */ + +/* 1 January 1970 */ + +long tv_nsec; /* Additional nanoseconds since */ + +/* tv_sec */ + +}; + +struct timezone +{ + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +static __inline int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag; + + if (NULL != tv) + { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + /*converting file time to unix epoch*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) + { + if (!tzflag) + { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} \ No newline at end of file diff --git a/compat/msvc/unistd.h b/compat/msvc/unistd.h new file mode 100644 index 0000000..a91b423 --- /dev/null +++ b/compat/msvc/unistd.h @@ -0,0 +1,3 @@ +#pragma once + +#include diff --git a/libvncclient/listen.c b/libvncclient/listen.c index c91ad6e..6d4ad54 100644 --- a/libvncclient/listen.c +++ b/libvncclient/listen.c @@ -27,11 +27,13 @@ #endif #include #include -#ifdef __MINGW32__ +#ifdef WIN32 #define close closesocket #include +#ifdef _MINGW32 #undef max -#else +#endif // #ifdef _MINGW32 +#else // #ifdef WIN32 #include #include #endif @@ -46,7 +48,7 @@ void listenForIncomingConnections(rfbClient* client) { -#ifdef __MINGW32__ +#ifdef WIN32 /* FIXME */ rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n"); return; diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 9d48b16..0afa3dc 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -64,6 +64,10 @@ #include "minilzo.h" #include "tls.h" +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + /* * rfbClientLog prints a time-stamped message to the log file (stderr). */ diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c index c97a90f..e50ef0e 100644 --- a/libvncclient/sockets.c +++ b/libvncclient/sockets.c @@ -38,7 +38,9 @@ #ifdef WIN32 #undef SOCKET #include +#ifdef MINGW32 #define EWOULDBLOCK WSAEWOULDBLOCK +#endif #define close closesocket #define read(sock,buf,len) recv(sock,buf,len,0) #define write(sock,buf,len) send(sock,buf,len,0) @@ -57,6 +59,10 @@ #endif #include "tls.h" +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + void PrintInHex(char *buf, int len); rfbBool errorMessageOnReadFailure = TRUE; @@ -105,7 +111,7 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) diff.tv_sec--; diff.tv_usec+=1000000; } -#ifndef __MINGW32__ +#ifndef WIN32 sleep (diff.tv_sec); usleep (diff.tv_usec); #else diff --git a/libvncclient/tls_openssl.c b/libvncclient/tls_openssl.c index 529d476..669913d 100644 --- a/libvncclient/tls_openssl.c +++ b/libvncclient/tls_openssl.c @@ -27,28 +27,57 @@ #include #include +#ifdef _MSC_VER +typedef CRITICAL_SECTION MUTEX_TYPE; +#define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex) +#define MUTEX_FREE(mutex) DeleteCriticalSection(&mutex) +#define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex) +#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex) +#define CURRENT_THREAD_ID GetCurrentThreadId() +#else +typedef pthread_mutex_t MUTEX_TYPE; +#define MUTEX_INIT(mutex) {\ + pthread_mutexattr_t mutexAttr;\ + pthread_mutexattr_init(&mutexAttr);\ + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\ + pthread_mutex_init(&mutex, &mutexAttr);\ +} +#define MUTEX_FREE(mutex) pthread_mutex_destroy(&mutex) +#define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex) +#define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex) +#define CURRENT_THREAD_ID pthread_self() +#endif + +#ifndef _MSC_VER #include +#endif #include "tls.h" +#ifdef _MSC_VER +#include // That's for SSIZE_T +typedef SSIZE_T ssize_t; +#define snprintf _snprintf +#endif + static rfbBool rfbTLSInitialized = FALSE; -static pthread_mutex_t *mutex_buf = NULL; +static MUTEX_TYPE *mutex_buf = NULL; struct CRYPTO_dynlock_value { - pthread_mutex_t mutex; + MUTEX_TYPE mutex; }; static void locking_function(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&mutex_buf[n]); + MUTEX_LOCK(mutex_buf[n]); else - pthread_mutex_unlock(&mutex_buf[n]); + MUTEX_UNLOCK(mutex_buf[n]); } static unsigned long id_function(void) { - return ((unsigned long) pthread_self()); + return ((unsigned long) CURRENT_THREAD_ID); } static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line) @@ -59,7 +88,7 @@ static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int li malloc(sizeof(struct CRYPTO_dynlock_value)); if (!value) goto err; - pthread_mutex_init(&value->mutex, NULL); + MUTEX_INIT(value->mutex); return value; @@ -70,16 +99,16 @@ err: static void dyn_lock_function (int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) { if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&l->mutex); + MUTEX_LOCK(l->mutex); else - pthread_mutex_unlock(&l->mutex); + MUTEX_UNLOCK(l->mutex); } static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) { - pthread_mutex_destroy(&l->mutex); + MUTEX_FREE(l->mutex); free(l); } @@ -117,14 +146,14 @@ InitializeTLS(void) if (rfbTLSInitialized) return TRUE; - mutex_buf = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); if (mutex_buf == NULL) { rfbClientLog("Failed to initialized OpenSSL: memory.\n"); return (-1); } for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_init(&mutex_buf[i], NULL); + MUTEX_INIT(mutex_buf[i]); CRYPTO_set_locking_callback(locking_function); CRYPTO_set_id_callback(id_function); @@ -145,7 +174,6 @@ ssl_verify (int ok, X509_STORE_CTX *ctx) { unsigned char md5sum[16], fingerprint[40], *f; rfbClient *client; - char *prompt, *cert_str; int err, i; unsigned int md5len; //char buf[257]; @@ -194,7 +222,7 @@ static int sock_read_ready(SSL *ssl, uint32_t ms) FD_SET(SSL_get_fd(ssl), &fds); tv.tv_sec = ms / 1000; - tv.tv_usec = (ms % 1000) * 1000; + tv.tv_usec = (ms % 1000) * ms; r = select (SSL_get_fd(ssl) + 1, &fds, NULL, NULL, &tv); @@ -203,8 +231,6 @@ static int sock_read_ready(SSL *ssl, uint32_t ms) static int wait_for_data(SSL *ssl, int ret, int timeout) { - struct timeval tv; - fd_set fds; int err; int retval = 1; @@ -237,7 +263,6 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS) SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; int n, finished = 0; - BIO *sbio; ssl_ctx = SSL_CTX_new (SSLv23_client_method ()); SSL_CTX_set_default_verify_paths (ssl_ctx); @@ -276,8 +301,6 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS) static rfbBool InitializeTLSSession(rfbClient* client, rfbBool anonTLS) { - int ret; - if (client->tlsSession) return TRUE; client->tlsSession = open_ssl_connection (client, client->sock, anonTLS); @@ -310,7 +333,11 @@ return TRUE; if (ret != -1) { rfbClientLog("TLS handshake blocking.\n"); - sleep(1); +#ifdef WIN32 + Sleep(1000); +#else + sleep(1); +#endif timeout--; continue; } @@ -415,7 +442,6 @@ HandleVeNCryptAuth(rfbClient* client) uint32_t authScheme; rfbBool anonTLS; // gnutls_certificate_credentials_t x509_cred = NULL; - int ret; if (!InitializeTLS()) return FALSE; @@ -577,7 +603,7 @@ void FreeTLS(rfbClient* client) CRYPTO_set_id_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_destroy(&mutex_buf[i]); + MUTEX_FREE(mutex_buf[i]); free(mutex_buf); mutex_buf = NULL; } diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 8237254..9d657ed 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -21,6 +21,11 @@ * vncviewer.c - the Xt-based VNC viewer. */ +#ifdef WIN32 +#undef SOCKET +#include +#endif + #ifdef __STRICT_ANSI__ #define _BSD_SOURCE #define _POSIX_SOURCE @@ -40,12 +45,10 @@ static rfbBool DummyPoint(rfbClient* client, int x, int y) { static void DummyRect(rfbClient* client, int x, int y, int w, int h) { } -#ifdef __MINGW32__ +#ifdef WIN32 static char* NoPassword(rfbClient* client) { return strdup(""); } -#undef SOCKET -#include #define close closesocket #else #include @@ -53,9 +56,9 @@ static char* NoPassword(rfbClient* client) { #endif static char* ReadPassword(rfbClient* client) { -#ifdef __MINGW32__ +#ifdef WIN32 /* FIXME */ - rfbClientErr("ReadPassword on MinGW32 NOT IMPLEMENTED\n"); + rfbClientErr("ReadPassword on Windows NOT IMPLEMENTED\n"); return NoPassword(client); #else int i; diff --git a/libvncclient/zrle.c b/libvncclient/zrle.c index a14ad44..7f488b5 100644 --- a/libvncclient/zrle.c +++ b/libvncclient/zrle.c @@ -189,7 +189,7 @@ HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) } /* while ( remaining > 0 ) */ if ( inflateResult == Z_OK ) { - void* buf=client->raw_buffer; + char* buf=client->raw_buffer; int i,j; remaining = client->raw_buffer_size-client->decompStream.avail_out; diff --git a/rfb/rfbproto.h b/rfb/rfbproto.h index fe46c3e..4169fd6 100644 --- a/rfb/rfbproto.h +++ b/rfb/rfbproto.h @@ -65,7 +65,7 @@ #define LIBVNCSERVER_WORDS_BIGENDIAN #define rfbBool int #include -#include +#include #undef SOCKET #define SOCKET int #else @@ -108,6 +108,10 @@ typedef int8_t rfbBool; #define TRUE -1 #endif +#ifdef _MSC_VER +#include +#endif + typedef uint32_t rfbKeySym; typedef uint32_t rfbPixel;