text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROPA_COMMANDLINE_H
#define WIN32_INTEROPA_COMMANDLINE_H

#include <map>
#include <vector>
#include <string>

using namespace std;

// A map of arguments encountered to the set of parameters for those arguments, in the order in which they
// were encountered. If 'maxmemory' is encountered 3 times, ArgumentMap["maxmemory"] will return a vector
// of an array of values, with the first being the value od the first 'maxmemory' instance enountered.
// Order of encounter is command line, conf file, nested conf file #1 (via include statement), ...
typedef map<string, vector<vector<string>>> ArgumentMap;
extern ArgumentMap g_argMap;

void ParseConfFile(string confFile, string cwd, ArgumentMap& argMap);
void ParseCommandLineArguments(int argc, char** argv);
vector<string> GetAccessPaths();

const string cQFork = "qfork";
const string cServiceRun = "service-run";
const string cServiceInstall = "service-install";
const string cServiceUninstall = "service-uninstall";
const string cServiceStart = "service-start";
const string cServiceStop = "service-stop";
const string cServiceName = "service-name";
const string cSyslogEnabled = "syslog-enabled";
const string cSyslogIdent= "syslog-ident";
const string cLogfile = "logfile";
const string cInclude = "include";
const string cDir = "dir";
const string cPersistenceAvailable = "persistence-available";
const string cMaxMemory = "maxmemory";
const string cSentinel = "sentinel";

const string cYes = "yes";
const string cNo = "no";
const string cDefaultSyslogIdent = "redis";
const string cDefaultLogfile = "stdout";

/* List of -- command arguments to be passed to redis::main() unaltered */
const vector<string> cRedisArgsForMainC = {"help", "version", "test-memory"};

#endif


text:
/*
* Modified by Henry Rawas (henryr@schakra.com)
*  - make it compatible with Visual Studio builds
*  - added wstrtod to handle INF, NAN
*  - added support for using IOCP with sockets
*/

#ifndef WIN32FIXES_H
#define WIN32FIXES_H

#pragma warning(error: 4005)
#pragma warning(error: 4013)

#ifdef WIN32
#ifndef _WIN32
#define _WIN32
#endif
#endif

#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define __USE_W32_SOCKETS

#include "win32_types.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>      // for _O_BINARY
#include <limits.h>     // for INT_MAX

#include "Win32_APIs.h"
#include "Win32_FDAPI.h"

#define WNOHANG 1

/* file mapping */
#define PROT_READ 1
#define PROT_WRITE 2

#define MAP_FAILED   (void *) -1

#define MAP_SHARED 1
#define MAP_PRIVATE 2

#if _MSC_VER < 1800
#ifndef ECONNRESET
#define ECONNRESET WSAECONNRESET
#endif

#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif

#ifndef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
#endif
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/* strtod does not handle Inf and Nan, we need to do the check before calling strtod */
#undef strtod
#define strtod(nptr, eptr) wstrtod((nptr), (eptr))

double wstrtod(const char *nptr, char **eptr);

#ifdef __cplusplus
}
#endif

// access check for executable uses X_OK. For Windows use READ access.
#ifndef X_OK
#define X_OK 4
#endif

#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif

#endif /* WIN32FIXES_H */

mime_type: text/plain


text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/

#pragma once

#ifdef __cplusplus
#include <string>
using namespace std;

typedef class RedisEventLog {
public:
    ~RedisEventLog() {}

    void InstallEventLogSource(string appPath);
    void UninstallEventLogSource();

    void SetEventLogIdentity(const char* identity);

    void LogMessage(LPCSTR msg, const WORD type);
    void LogError(string msg);

    string GetEventLogIdentity();
    void EnableEventLog(bool enabled);
    bool IsEventLogEnabled();

private:
    const string eventLogName = "redis";
    const string cEventLogPath = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
    const string cEventLogApplicitonPath = cEventLogPath + "Application\\";
    const string cRedis = "redis";
    const string cEventMessageFile = "EventMessageFile";
    const string cRedisServer = "redis-server";
    const string cTypesSupported = "TypesSupported";
    const string cApplication = "Application";
} RedisEventLog;

extern "C" {
#endif

    void setSyslogEnabled(int enabled);
    void setSyslogIdent(char* identity);
    int IsEventLogEnabled();
    void WriteEventLog(const char* msg);

#ifdef __cplusplus
}
#endif


text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROP_TYPES_H
#define WIN32_INTEROP_TYPES_H

#include "win32_types_hiredis.h"

/* The Posix version of Redis defines off_t as 64-bit integers, so we do the same.
 * On Windows, these types are defined as 32-bit in sys/types.h under and #ifndef _OFF_T_DEFINED
 * So we define _OFF_T_DEFINED at the project level, to make sure that that definition is never included.
 * If you get an error about re-definition, make sure to include this file before sys/types.h, or any other
 * file that include it (eg wchar.h).
 * _off_t is also defined #ifndef _OFF_T_DEFINED, so we need to define it here.
 * It is used by the CRT internally (but not by Redis), so we leave it as 32-bit.
 */

typedef __int64     off_t;
typedef long        _off_t;

#ifndef _OFF_T_DEFINED
#define _OFF_T_DEFINED
#endif

#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROP_ASSERT_H
#define WIN32_INTEROP_ASSERT_H

#ifdef _DEBUG
#define ASSERT(condition)  do { if(!(condition)){ fprintf(stderr, "Assertion failed: %s @ %s::%s (%d)\n", #condition , __FILE__, __FUNCTION__, __LINE__); DebugBreak();} } while(0)
#else
#define ASSERT(condition)
#endif

#endif


text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROPA_ANSI_H
#define WIN32_INTEROPA_ANSI_H

#include <Windows.h>

#ifdef __cplusplus
extern "C" {
#endif

    BOOL ParseAndPrintANSIString(HANDLE hDev, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten);
    void ANSI_printf(char *format, ...);

    // include this file after stdio.h in order to redirect printf to the one that supports ANSI escape sequences
#define printf ANSI_printf

#ifdef __cplusplus
}
#endif

#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROP_FDAPI_H
#define WIN32_INTEROP_FDAPI_H

// fcntl flags used in Redis
#define	F_GETFL		3
#define	F_SETFL		4
#define	O_NONBLOCK	0x0004

typedef unsigned long nfds_t;

// Important! Do not include Winsock API definitions to avoid conflicts
// with API entry points defined below.
#define INCL_WINSOCK_API_PROTOTYPES 0
#include "win32_types.h"
#include <WinSock2.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>

// Including a version of this file modified to eliminate prototype
// definitions not removed by INCL_WINSOCK_API_PROTOTYPES
#include "WS2tcpip.h"

// Reintroducing the inline APIs removed by INCL_WINSOCK_API_PROTOTYPES
// that Redis is using
#ifdef UNICODE
#define gai_strerror   gai_strerrorW
#else
#define gai_strerror   gai_strerrorA
#endif /* UNICODE */

#define GAI_STRERROR_BUFFER_SIZE 1024

WS2TCPIP_INLINE char* gai_strerrorA(_In_ int ecode) {
    DWORD dwMsgLen;
    static char buff[GAI_STRERROR_BUFFER_SIZE + 1];

    dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
                             |FORMAT_MESSAGE_IGNORE_INSERTS
                             |FORMAT_MESSAGE_MAX_WIDTH_MASK,
                              NULL,
                              ecode,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPSTR)buff,
                              GAI_STRERROR_BUFFER_SIZE,
                              NULL);

    return buff;
}

WS2TCPIP_INLINE WCHAR* gai_strerrorW(_In_ int ecode) {
    DWORD dwMsgLen;
    static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];

    dwMsgLen = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
                             |FORMAT_MESSAGE_IGNORE_INSERTS
                             |FORMAT_MESSAGE_MAX_WIDTH_MASK,
                              NULL,
                              ecode,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPWSTR)buff,
                              GAI_STRERROR_BUFFER_SIZE,
                              NULL);

    return buff;
}

#if WINVER <= _WIN32_WINNT_WS03
#define POLLRDNORM  0x0100
#define POLLRDBAND  0x0200
#define POLLIN      (POLLRDNORM | POLLRDBAND)
#define POLLPRI     0x0400

#define POLLWRNORM  0x0010
#define POLLOUT     (POLLWRNORM)
#define POLLWRBAND  0x0020

#define POLLERR     0x0001
#define POLLHUP     0x0002
#define POLLNVAL    0x0004

typedef struct pollfd {
    SOCKET  fd;
    SHORT   events;
    SHORT   revents;

} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;
#endif

// API prototypes must match the unix implementation
typedef int (*fdapi_pipe)(int pipefd[2]);
typedef int (*fdapi_socket)(int af,int type,int protocol);
typedef int (*fdapi_open)(const char * _Filename, int _OpenFlag, int flags);
typedef int (*fdapi_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
typedef int (*fdapi_setsockopt)(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
typedef int (*fdapi_fcntl)(int fd, int cmd, int flags);
typedef int (*fdapi_poll)(struct pollfd *fds, nfds_t nfds, int timeout);
typedef int (*fdapi_getsockopt)(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
typedef int (*fdapi_connect)(int sockfd, const struct sockaddr *addr, size_t addrlen);
typedef ssize_t (*fdapi_read)(int fd, void *buf, size_t count);
typedef ssize_t (*fdapi_write)(int fd, const void *buf, size_t count);
typedef int (*fdapi_fsync)(int fd);
typedef int (*fdapi_listen)(int sockfd, int backlog);
typedef int (*fdapi_ftruncate)(int fd, PORT_LONGLONG length);
typedef int (*fdapi_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
typedef u_short (*fdapi_htons)(u_short hostshort);
typedef u_long (*fdapi_htonl)(u_long hostlong);
typedef u_short (*fdapi_ntohs)(u_short netshort);
typedef int (*fdapi_getpeername)(int sockfd, struct sockaddr *addr, socklen_t * addrlen);
typedef int (*fdapi_getsockname)(int sockfd, struct sockaddr* addrsock, int* addrlen );
typedef void (*fdapi_freeaddrinfo)(struct addrinfo *ai);
typedef int (*fdapi_getaddrinfo)(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
typedef const char* (*fdapi_inet_ntop)(int af, const void *src, char *dst, size_t size);
typedef int (*fdapi_inet_pton)(int af, const char * src, void *dst);
typedef int (*fdapi_select)(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
typedef u_int (*fdapi_ntohl)(u_int netlong);
typedef int (*fdapi_isatty)(int fd);
typedef int (*fdapi_access)(const char *pathname, int mode);
typedef u_int64 (*fdapi_lseek64)(int fd, u_int64 offset, int whence);
typedef int (*fdapi_fstat)(int fd, struct __stat64 *buffer);

typedef BOOL fnWSIOCP_CloseSocketStateRFD(int rfd);

// access() mode definitions
#define X_OK    0
#define W_OK    2
#define R_OK    4

#ifdef __cplusplus
extern "C"
{
#endif

// API replacements
extern fdapi_accept         accept;
extern fdapi_access         access;
extern fdapi_bind           bind;
extern fdapi_connect        connect;
extern fdapi_fcntl          fcntl;
extern fdapi_fstat          fdapi_fstat64;
extern fdapi_freeaddrinfo   freeaddrinfo;
extern fdapi_fsync          fsync;
extern fdapi_ftruncate      ftruncate;
extern fdapi_getaddrinfo    getaddrinfo;
extern fdapi_getsockopt     getsockopt;
extern fdapi_getpeername    getpeername;
extern fdapi_getsockname    getsockname;
extern fdapi_htonl          htonl;
extern fdapi_htons          htons;
extern fdapi_isatty         isatty;
extern fdapi_inet_ntop      inet_ntop;
extern fdapi_inet_pton      inet_pton;
extern fdapi_listen         listen;
extern fdapi_lseek64        lseek64;
extern fdapi_ntohl          ntohl;
extern fdapi_ntohs          ntohs;
extern fdapi_open           open;
extern fdapi_pipe           pipe;
extern fdapi_poll           poll;
extern fdapi_read           read;
extern fdapi_select         select;
extern fdapi_setsockopt     setsockopt;
extern fdapi_socket         socket;
extern fdapi_write          write;

// Other FD based APIs
void    FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage);
BOOL    FDAPI_SocketAttachIOCP(int rfd, HANDLE iocph);
BOOL    FDAPI_AcceptEx(int listenFD,int acceptFD,PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPDWORD lpdwBytesReceived,LPOVERLAPPED lpOverlapped);
BOOL    FDAPI_ConnectEx(int fd,const struct sockaddr *name,int namelen,PVOID lpSendBuffer,DWORD dwSendDataLength,LPDWORD lpdwBytesSent,LPOVERLAPPED lpOverlapped);
void    FDAPI_GetAcceptExSockaddrs(int fd, PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPSOCKADDR *LocalSockaddr,LPINT LocalSockaddrLength,LPSOCKADDR *RemoteSockaddr,LPINT RemoteSockaddrLength);
int     FDAPI_UpdateAcceptContext( int fd );
int     FDAPI_PipeSetNonBlock(int rfd, int non_blocking);
void**  FDAPI_GetSocketStatePtr(int rfd);
void    FDAPI_ClearSocketInfo(int fd);

int     FDAPI_WSAIoctl(int rfd, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int     FDAPI_WSASend(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int     FDAPI_WSARecv(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
BOOL    FDAPI_WSAGetOverlappedResult(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags);
BOOL    FDAPI_CloseDuplicatedSocket(int rfd);
int     FDAPI_WSADuplicateSocket(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);
int     FDAPI_WSASocket(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
int     FDAPI_WSAGetLastError(void);

intptr_t FDAPI_get_osfhandle(int fd);
int      FDAPI_open_osfhandle(intptr_t osfhandle, int flags);

// FDAPI helper function
void FDAPI_SetCloseSocketState(fnWSIOCP_CloseSocketStateRFD* func);

// Other networking functions
BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAddr);

extern int FDAPI_close(int rfd);
extern int FDAPI_fclose(FILE *file);
extern int FDAPI_setmode(int fd, int mode);
extern size_t FDAPI_fwrite(const void *buffer, size_t size, size_t count, FILE *file);
extern int FDAPI_fileno(FILE *file);

// Macroize CRT definitions to point to our own
#ifndef FDAPI_NOCRTREDEFS
#define close(fd)                   FDAPI_close(fd)
#define fclose(File)                FDAPI_fclose(File)
#define setmode(fd,mode)            FDAPI_setmode(fd,mode)
#define fwrite(Str,Size,Count,File) FDAPI_fwrite(Str,Size,Count,File)
#define fileno(File)                FDAPI_fileno(File)

#define _INC_STAT_INL
#define fstat(fd,buffer)            fdapi_fstat64(fd,buffer)
#endif

#ifdef __cplusplus
}
#endif
#endif


text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROPA_PORTABILITY_H
#define WIN32_INTEROPA_PORTABILITY_H

#ifdef __cplusplus
extern "C"
{
#endif

/*  Sometimes in the Windows port we make changes from:
        antirez_redis_statement();
    to:
        #ifdef _WIN32
            windows_redis_statement();
        #else
            antirez_redis_statement();
        #endif

    If subsequently antirez changed that code, we might not detect the change during the next merge.
    The INDUCE_MERGE_CONFLICT macro expands to nothing, but it is used to make sure that the original line
    is modified with respect to the antirez version, so that any subsequent modifications will trigger a conflict
    during the next merge.

    Sample usage:
        #ifdef _WIN32
            windows_redis_statement();
        #else
            antirez_redis_statement();          INDUCE_MERGE_CONFLICT
        #endif

    Don't use any parenthesis or semi-colon after INDUCE_MERGE_CONFLICT.
    Use it at the end of a line to preserve the original indentation.
*/
#define INDUCE_MERGE_CONFLICT

/*  Use WIN_PORT_FIX at the end of a line to mark places where we make changes to the code
    without using #ifdefs. Useful to keep the code more legible. Mainly intended for replacing
    the use of long (which is 64-bit on 64-bit Unix and 32-bit on 64-bit Windows) to portable types.
    In order to be eligible for an inline fix (without #ifdef), the change should be portable back to the Posix version.
*/
#define WIN_PORT_FIX

#ifdef _WIN32
#define IF_WIN32(x, y) x
#define WIN32_ONLY(x) x
#define POSIX_ONLY(x)
#define inline __inline
#else
#define IF_WIN32(x, y) y
#define WIN32_ONLY(x)
#define POSIX_ONLY(x) x
#endif

#ifdef __cplusplus
}
#endif

#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROP_WSIOCP_H
#define WIN32_INTEROP_WSIOCP_H

#include "win32_wsiocp2.h"

/* structs and functions for using IOCP with windows sockets */

/* structure used for async write requests.
 * contains overlapped, WSABuf, and callback info
 * NOTE: OVERLAPPED must be first member */
typedef struct asendreq {
    OVERLAPPED ov;
    WSABUF wbuf;
    WSIOCP_Request req;
    aeFileProc *proc;
    aeEventLoop *eventLoop;
} asendreq;

/* structure used for async accept requests.
 * contains overlapped, accept socket, accept buffer
 * NOTE: OVERLAPPED must be first member */
typedef struct aacceptreq {
    OVERLAPPED ov;
    SOCKET accept;
    void *buf;
    struct aacceptreq *next;
} aacceptreq;

/* per socket information */
typedef struct iocpSockState {
    int masks;
    int fd;
    aacceptreq *reqs;
    int wreqs;
    OVERLAPPED ov_read;
    list wreqlist;
    int unknownComplete;
} iocpSockState;

#define READ_QUEUED         0x000100
#define SOCKET_ATTACHED     0x000400
#define ACCEPT_PENDING      0x000800
#define LISTEN_SOCK         0x001000
#define CONNECT_PENDING     0x002000
#define CLOSE_PENDING       0x004000

void           WSIOCP_Init(HANDLE iocp);
void           WSIOCP_Cleanup();
iocpSockState* WSIOCP_GetExistingSocketState(int fd);
iocpSockState* WSIOCP_GetSocketState(int fd);
BOOL           WSIOCP_CloseSocketState(iocpSockState* pSocketState);

void* CallocMemoryNoCOW(size_t size);
void  FreeMemoryNoCOW(void * ptr);

#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */

/*
**  WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols
**
**  This file contains TCP/IP specific information for use
**  by WinSock2 compatible applications.
**
**  Copyright (c) Microsoft Corporation. All rights reserved.
**
**  To provide the backward compatibility, all the TCP/IP
**  specific definitions that were included in the WINSOCK.H
**  file are now included in WINSOCK2.H file. WS2TCPIP.H
**  file includes only the definitions introduced in the
**  "WinSock 2 Protocol-Specific Annex" document.
**
**  Rev 0.3 Nov 13, 1995
**      Rev 0.4 Dec 15, 1996
*/

#ifndef _WS2TCPIP_H_
#define _WS2TCPIP_H_

#if _MSC_VER > 1000
#pragma once
#endif

#if WINVER <= _WIN32_WINNT_WS03
#include "win32_winapifamily.h"
#else
#include <winapifamily.h>
#endif

#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

#include <winsock2.h>
#include <ws2ipdef.h>
#include <limits.h>

/* Option to use with [gs]etsockopt at the IPPROTO_UDP level */

#define UDP_NOCHECKSUM  1
#define UDP_CHECKSUM_COVERAGE   20  /* Set/get UDP-Lite checksum coverage */

#ifdef _MSC_VER
#define WS2TCPIP_INLINE __inline
#else
#define WS2TCPIP_INLINE extern inline /* GNU style */
#endif

/* Error codes from getaddrinfo() */

#define EAI_AGAIN           WSATRY_AGAIN
#define EAI_BADFLAGS        WSAEINVAL
#define EAI_FAIL            WSANO_RECOVERY
#define EAI_FAMILY          WSAEAFNOSUPPORT
#define EAI_MEMORY          WSA_NOT_ENOUGH_MEMORY
#define EAI_NOSECURENAME    WSA_SECURE_HOST_NOT_FOUND
//#define EAI_NODATA        WSANO_DATA
#define EAI_NONAME          WSAHOST_NOT_FOUND
#define EAI_SERVICE         WSATYPE_NOT_FOUND
#define EAI_SOCKTYPE        WSAESOCKTNOSUPPORT
#define EAI_IPSECPOLICY     WSA_IPSEC_NAME_POLICY_ERROR
//
//  DCR_FIX:  EAI_NODATA remove or fix
//
//  EAI_NODATA was removed from rfc2553bis
//  need to find out from the authors why and
//  determine the error for "no records of this type"
//  temporarily, we'll keep #define to avoid changing
//  code that could change back;  use NONAME
//

#define EAI_NODATA      EAI_NONAME

//  Switchable definition for GetAddrInfo()

#ifdef UNICODE
typedef ADDRINFOW       ADDRINFOT, *PADDRINFOT;
#else
typedef ADDRINFOA       ADDRINFOT, *PADDRINFOT;
#endif

//  RFC standard definition for getaddrinfo()

typedef ADDRINFOA       ADDRINFO, FAR * LPADDRINFO;

#if (_WIN32_WINNT >= 0x0600)

#ifdef UNICODE
typedef ADDRINFOEXW     ADDRINFOEX, *PADDRINFOEX;
#else
typedef ADDRINFOEXA     ADDRINFOEX, *PADDRINFOEX;
#endif

#endif

#ifdef __cplusplus
extern "C" {
#endif

#if INCL_WINSOCK_API_TYPEDEFS
WINSOCK_API_LINKAGE
INT
WSAAPI
getaddrinfo(
    _In_opt_        PCSTR               pNodeName,
    _In_opt_        PCSTR               pServiceName,
    _In_opt_        const ADDRINFOA *   pHints,
    _Outptr_     PADDRINFOA *        ppResult
    );

#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502)
WINSOCK_API_LINKAGE
INT
WSAAPI
GetAddrInfoW(
    _In_opt_        PCWSTR              pNodeName,
    _In_opt_        PCWSTR              pServiceName,
    _In_opt_        const ADDRINFOW *   pHints,
    _Outptr_     PADDRINFOW *        ppResult
    );

#define GetAddrInfoA    getaddrinfo

#ifdef UNICODE
#define GetAddrInfo     GetAddrInfoW
#else
#define GetAddrInfo     GetAddrInfoA
#endif
#endif
#endif

#if INCL_WINSOCK_API_TYPEDEFS
typedef
INT
(WSAAPI * LPFN_GETADDRINFO)(
    _In_opt_        PCSTR               pNodeName,
    _In_opt_        PCSTR               pServiceName,
    _In_opt_        const ADDRINFOA *   pHints,
    _Outptr_     PADDRINFOA *        ppResult
    );

typedef
INT
(WSAAPI * LPFN_GETADDRINFOW)(
    _In_opt_        PCWSTR              pNodeName,
    _In_opt_        PCWSTR              pServiceName,
    _In_opt_        const ADDRINFOW *   pHints,
    _Outptr_     PADDRINFOW *        ppResult
    );

#define LPFN_GETADDRINFOA      LPFN_GETADDRINFO

#ifdef UNICODE
#define LPFN_GETADDRINFOT      LPFN_GETADDRINFOW
#else
#define LPFN_GETADDRINFOT      LPFN_GETADDRINFOA
#endif
#endif

#if (_WIN32_WINNT >= 0x0600)

typedef
void
(CALLBACK * LPLOOKUPSERVICE_COMPLETION_ROUTINE)(
    _In_      DWORD    dwError,
    _In_      DWORD    dwBytes,
    _In_      LPWSAOVERLAPPED lpOverlapped
    );

WINSOCK_API_LINKAGE
INT
WSAAPI
GetAddrInfoExA(
    _In_opt_    PCSTR           pName,
    _In_opt_    PCSTR           pServiceName,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    const ADDRINFOEXA *hints,
    _Outptr_ PADDRINFOEXA *  ppResult,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

WINSOCK_API_LINKAGE
INT
WSAAPI
GetAddrInfoExW(
    _In_opt_    PCWSTR          pName,
    _In_opt_    PCWSTR          pServiceName,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    const ADDRINFOEXW *hints,
    _Outptr_ PADDRINFOEXW *  ppResult,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpHandle
    );

WINSOCK_API_LINKAGE
INT
WSAAPI
GetAddrInfoExCancel(
    _In_        LPHANDLE        lpHandle
    );

WINSOCK_API_LINKAGE
INT
WSAAPI
GetAddrInfoExOverlappedResult(
    _In_        LPOVERLAPPED    lpOverlapped
    );

#ifdef UNICODE
#define GetAddrInfoEx       GetAddrInfoExW
#else
#define GetAddrInfoEx       GetAddrInfoExA
#endif

#if INCL_WINSOCK_API_TYPEDEFS

typedef
INT
(WSAAPI *LPFN_GETADDRINFOEXA)(
    _In_        PCSTR           pName,
    _In_opt_    PCSTR           pServiceName,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    const ADDRINFOEXA *hints,
    _Outptr_ PADDRINFOEXA   *ppResult,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

typedef
INT
(WSAAPI *LPFN_GETADDRINFOEXW)(
    _In_        PCWSTR          pName,
    _In_opt_    PCWSTR          pServiceName,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    const ADDRINFOEXW *hints,
    _Outptr_ PADDRINFOEXW   *ppResult,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpHandle
    );

typedef
INT
(WSAAPI *LPFN_GETADDRINFOEXCANCEL)(
    _In_        LPHANDLE        lpHandle
    );

typedef
INT
(WSAAPI *LPFN_GETADDRINFOEXOVERLAPPEDRESULT)(
    _In_        LPOVERLAPPED    lpOverlapped
    );

#ifdef UNICODE
#define LPFN_GETADDRINFOEX      LPFN_GETADDRINFOEXW
#else
#define LPFN_GETADDRINFOEX      LPFN_GETADDRINFOEXA
#endif
#endif

#endif

#if (_WIN32_WINNT >= 0x0600)

WINSOCK_API_LINKAGE
INT
WSAAPI
SetAddrInfoExA(
    _In_        PCSTR           pName,
    _In_opt_    PCSTR           pServiceName,
    _In_opt_    SOCKET_ADDRESS *pAddresses,
    _In_        DWORD           dwAddressCount,
    _In_opt_    LPBLOB          lpBlob,
    _In_        DWORD           dwFlags,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

WINSOCK_API_LINKAGE
INT
WSAAPI
SetAddrInfoExW(
    _In_        PCWSTR          pName,
    _In_opt_    PCWSTR          pServiceName,
    _In_opt_    SOCKET_ADDRESS *pAddresses,
    _In_        DWORD           dwAddressCount,
    _In_opt_    LPBLOB          lpBlob,
    _In_        DWORD           dwFlags,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

#ifdef UNICODE
#define SetAddrInfoEx       SetAddrInfoExW
#else
#define SetAddrInfoEx       SetAddrInfoExA
#endif

#if INCL_WINSOCK_API_TYPEDEFS
typedef
INT
(WSAAPI *LPFN_SETADDRINFOEXA)(
    _In_        PCSTR           pName,
    _In_opt_    PCSTR           pServiceName,
    _In_opt_    SOCKET_ADDRESS *pAddresses,
    _In_        DWORD           dwAddressCount,
    _In_opt_    LPBLOB          lpBlob,
    _In_        DWORD           dwFlags,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

typedef
INT
(WSAAPI *LPFN_SETADDRINFOEXW)(
    _In_        PCWSTR          pName,
    _In_opt_    PCWSTR          pServiceName,
    _In_opt_    SOCKET_ADDRESS *pAddresses,
    _In_        DWORD           dwAddressCount,
    _In_opt_    LPBLOB          lpBlob,
    _In_        DWORD           dwFlags,
    _In_        DWORD           dwNameSpace,
    _In_opt_    LPGUID          lpNspId,
    _In_opt_    struct timeval *timeout,
    _In_opt_    LPOVERLAPPED    lpOverlapped,
    _In_opt_    LPLOOKUPSERVICE_COMPLETION_ROUTINE  lpCompletionRoutine,
    _Out_opt_   LPHANDLE        lpNameHandle
    );

#ifdef UNICODE
#define LPFN_SETADDRINFOEX      LPFN_SETADDRINFOEXW
#else
#define LPFN_SETADDRINFOEX      LPFN_SETADDRINFOEXA
#endif
#endif

#endif

#if INCL_WINSOCK_API_TYPEDEFS
WINSOCK_API_LINKAGE
VOID
WSAAPI
freeaddrinfo(
    _In_opt_        PADDRINFOA      pAddrInfo
    );

#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502)
WINSOCK_API_LINKAGE
VOID
WSAAPI
FreeAddrInfoW(
    _In_opt_        PADDRINFOW      pAddrInfo
    );
#endif

#define FreeAddrInfoA   freeaddrinfo

#ifdef UNICODE
#define FreeAddrInfo    FreeAddrInfoW
#else
#define FreeAddrInfo    FreeAddrInfoA
#endif
#endif

#if INCL_WINSOCK_API_TYPEDEFS
typedef
VOID
(WSAAPI * LPFN_FREEADDRINFO)(
    _In_opt_        PADDRINFOA      pAddrInfo
    );
typedef
VOID
(WSAAPI * LPFN_FREEADDRINFOW)(
    _In_opt_        PADDRINFOW      pAddrInfo
    );

#define LPFN_FREEADDRINFOA      LPFN_FREEADDRINFO

#ifdef UNICODE
#define LPFN_FREEADDRINFOT      LPFN_FREEADDRINFOW
#else
#define LPFN_FREEADDRINFOT      LPFN_FREEADDRINFOA
#endif
#endif

#if (_WIN32_WINNT >= 0x0600)

WINSOCK_API_LINKAGE
void
WSAAPI
FreeAddrInfoEx(
    _In_opt_  PADDRINFOEXA    pAddrInfoEx
    );

WINSOCK_API_LINKAGE
void
WSAAPI
FreeAddrInfoExW(
    _In_opt_  PADDRINFOEXW    pAddrInfoEx
    );

#define FreeAddrInfoExA     FreeAddrInfoEx

#ifdef UNICODE
#define FreeAddrInfoEx      FreeAddrInfoExW
#endif

#ifdef INCL_WINSOCK_API_TYPEDEFS
typedef
void
(WSAAPI *LPFN_FREEADDRINFOEXA)(
    _In_    PADDRINFOEXA    pAddrInfoEx
    );

typedef
void
(WSAAPI *LPFN_FREEADDRINFOEXW)(
    _In_    PADDRINFOEXW    pAddrInfoEx
    );

#ifdef UNICODE
#define LPFN_FREEADDRINFOEX     LPFN_FREEADDRINFOEXW
#else
#define LPFN_FREEADDRINFOEX     LPFN_FREEADDRINFOEXA
#endif

#endif
#endif

typedef int socklen_t;

WINSOCK_API_LINKAGE
INT
WSAAPI
getnameinfo(
    _In_reads_bytes_(SockaddrLength)         const SOCKADDR *    pSockaddr,
    _In_                                socklen_t           SockaddrLength,
    _Out_writes_opt_(NodeBufferSize)    PCHAR               pNodeBuffer,
    _In_                                DWORD               NodeBufferSize,
    _Out_writes_opt_(ServiceBufferSize) PCHAR               pServiceBuffer,
    _In_                                DWORD               ServiceBufferSize,
    _In_                                INT                 Flags
    );

#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502)
WINSOCK_API_LINKAGE
INT
WSAAPI
GetNameInfoW(
    _In_reads_bytes_(SockaddrLength)         const SOCKADDR *    pSockaddr,
    _In_                                socklen_t           SockaddrLength,
    _Out_writes_opt_(NodeBufferSize)    PWCHAR              pNodeBuffer,
    _In_                                DWORD               NodeBufferSize,
    _Out_writes_opt_(ServiceBufferSize) PWCHAR              pServiceBuffer,
    _In_                                DWORD               ServiceBufferSize,
    _In_                                INT                 Flags
    );

#define GetNameInfoA    getnameinfo

#ifdef UNICODE
#define GetNameInfo     GetNameInfoW
#else
#define GetNameInfo     GetNameInfoA
#endif
#endif

#if INCL_WINSOCK_API_TYPEDEFS
typedef
int
(WSAAPI * LPFN_GETNAMEINFO)(
    _In_reads_bytes_(SockaddrLength)         const SOCKADDR *    pSockaddr,
    _In_                                socklen_t           SockaddrLength,
    _Out_writes_opt_(NodeBufferSize)    PCHAR               pNodeBuffer,
    _In_                                DWORD               NodeBufferSize,
    _Out_writes_opt_(ServiceBufferSize) PCHAR               pServiceBuffer,
    _In_                                DWORD               ServiceBufferSize,
    _In_                                INT                 Flags
    );

typedef
INT
(WSAAPI * LPFN_GETNAMEINFOW)(
    _In_reads_bytes_(SockaddrLength)         const SOCKADDR *    pSockaddr,
    _In_                                socklen_t           SockaddrLength,
    _Out_writes_opt_(NodeBufferSize)    PWCHAR              pNodeBuffer,
    _In_                                DWORD               NodeBufferSize,
    _Out_writes_opt_(ServiceBufferSize) PWCHAR              pServiceBuffer,
    _In_                                DWORD               ServiceBufferSize,
    _In_                                INT                 Flags
    );

#define LPFN_GETNAMEINFOA      LPFN_GETNAMEINFO

#ifdef UNICODE
#define LPFN_GETNAMEINFOT      LPFN_GETNAMEINFOW
#else
#define LPFN_GETNAMEINFOT      LPFN_GETNAMEINFOA
#endif
#endif

#if (NTDDI_VERSION >= NTDDI_VISTA)
#if INCL_WINSOCK_API_TYPEDEFS
WINSOCK_API_LINKAGE
INT
WSAAPI
inet_pton(
    _In_                                INT             Family,
    _In_                                PCSTR           pszAddrString,
    _Out_writes_bytes_(sizeof(IN6_ADDR))      PVOID           pAddrBuf
    );

INT
WSAAPI
InetPtonW(
    _In_                                INT             Family,
    _In_                                PCWSTR          pszAddrString,
    _Out_writes_bytes_(sizeof(IN6_ADDR))      PVOID           pAddrBuf
    );

PCSTR
WSAAPI
inet_ntop(
    _In_                                INT             Family,
    _In_                                PVOID           pAddr,
    _Out_writes_(StringBufSize)         PSTR            pStringBuf,
    _In_                                size_t          StringBufSize
    );

PCWSTR
WSAAPI
InetNtopW(
    _In_                                INT             Family,
    _In_                                PVOID           pAddr,
    _Out_writes_(StringBufSize)         PWSTR           pStringBuf,
    _In_                                size_t          StringBufSize
    );

#define InetPtonA       inet_pton
#define InetNtopA       inet_ntop

#ifdef UNICODE
#define InetPton        InetPtonW
#define InetNtop        InetNtopW
#else
#define InetPton        InetPtonA
#define InetNtop        InetNtopA
#endif
#endif

#if INCL_WINSOCK_API_TYPEDEFS
typedef
INT
(WSAAPI * LPFN_INET_PTONA)(
    _In_                                INT             Family,
    _In_                                PCSTR           pszAddrString,
    _Out_writes_bytes_(sizeof(IN6_ADDR))      PVOID           pAddrBuf
    );

typedef
INT
(WSAAPI * LPFN_INET_PTONW)(
    _In_                                INT             Family,
    _In_                                PCWSTR          pszAddrString,
    _Out_writes_bytes_(sizeof(IN6_ADDR))      PVOID           pAddrBuf
    );

typedef
PCSTR
(WSAAPI * LPFN_INET_NTOPA)(
    _In_                                INT             Family,
    _In_                                PVOID           pAddr,
    _Out_writes_(StringBufSize)         PSTR            pStringBuf,
    _In_                                size_t          StringBufSize
    );

typedef
PCWSTR
(WSAAPI * LPFN_INET_NTOPW)(
    _In_                                INT             Family,
    _In_                                PVOID           pAddr,
    _Out_writes_(StringBufSize)         PWSTR           pStringBuf,
    _In_                                size_t          StringBufSize
    );

#ifdef UNICODE
#define LPFN_INET_PTON          LPFN_INET_PTONW
#define LPFN_INET_NTOP          LPFN_INET_NTOPW
#else
#define LPFN_INET_PTON          LPFN_INET_PTONA
#define LPFN_INET_NTOP          LPFN_INET_NTOPA
#endif

#endif  //  TYPEDEFS
#endif  //  (NTDDI_VERSION >= NTDDI_VISTA)

#if INCL_WINSOCK_API_PROTOTYPES
#ifdef UNICODE
#define gai_strerror   gai_strerrorW
#else
#define gai_strerror   gai_strerrorA
#endif  /* UNICODE */

// WARNING: The gai_strerror inline functions below use static buffers,
// and hence are not thread-safe.  We'll use buffers long enough to hold
// 1k characters.  Any system error messages longer than this will be
// returned as empty strings.  However 1k should work for the error codes
// used by getaddrinfo().
#define GAI_STRERROR_BUFFER_SIZE 1024

WS2TCPIP_INLINE
char *
gai_strerrorA(
    _In_ int ecode)
{
    DWORD dwMsgLen;
    static char buff[GAI_STRERROR_BUFFER_SIZE + 1];

    dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
                             |FORMAT_MESSAGE_IGNORE_INSERTS
                             |FORMAT_MESSAGE_MAX_WIDTH_MASK,
                              NULL,
                              ecode,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPSTR)buff,
                              GAI_STRERROR_BUFFER_SIZE,
                              NULL);

    return buff;
}

WS2TCPIP_INLINE
WCHAR *
gai_strerrorW(
    _In_ int ecode
    )
{
    DWORD dwMsgLen;
    static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];

    dwMsgLen = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
                             |FORMAT_MESSAGE_IGNORE_INSERTS
                             |FORMAT_MESSAGE_MAX_WIDTH_MASK,
                              NULL,
                              ecode,
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPWSTR)buff,
                              GAI_STRERROR_BUFFER_SIZE,
                              NULL);

    return buff;
}
#endif /* INCL_WINSOCK_API_PROTOTYPES */

#if INCL_WINSOCK_API_PROTOTYPES

/* Multicast source filter APIs from RFC 3678. */

WS2TCPIP_INLINE
int
setipv4sourcefilter(
    _In_ SOCKET Socket,
    _In_ IN_ADDR Interface,
    _In_ IN_ADDR Group,
    _In_ MULTICAST_MODE_TYPE FilterMode,
    _In_ ULONG SourceCount,
    _In_reads_(SourceCount) CONST IN_ADDR *SourceList
    )
{
    int Error;
    DWORD Size, Returned;
    PIP_MSFILTER Filter;

    if (SourceCount >
        (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Size = IP_MSFILTER_SIZE(SourceCount);
    Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
    if (Filter == NULL) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Filter->imsf_multiaddr = Group;
    Filter->imsf_interface = Interface;
    Filter->imsf_fmode = FilterMode;
    Filter->imsf_numsrc = SourceCount;
    if (SourceCount > 0) {
        CopyMemory(Filter->imsf_slist, SourceList,
                   SourceCount * sizeof(*SourceList));
    }

    Error = WSAIoctl(Socket, SIOCSIPMSFILTER, Filter, Size, NULL, 0,
                     &Returned, NULL, NULL);

    HeapFree(GetProcessHeap(), 0, Filter);

    return Error;
}

_Success_(return == 0)
WS2TCPIP_INLINE
int
getipv4sourcefilter(
    _In_ SOCKET Socket,
    _In_ IN_ADDR Interface,
    _In_ IN_ADDR Group,
    _Out_ MULTICAST_MODE_TYPE *FilterMode,
    _Inout_ ULONG *SourceCount,
    _Out_writes_(*SourceCount) IN_ADDR *SourceList
    )
{
    int Error;
    DWORD Size, Returned;
    PIP_MSFILTER Filter;

    if (*SourceCount >
        (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Size = IP_MSFILTER_SIZE(*SourceCount);
    Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
    if (Filter == NULL) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Filter->imsf_multiaddr = Group;
    Filter->imsf_interface = Interface;
    Filter->imsf_numsrc = *SourceCount;

    Error = WSAIoctl(Socket, SIOCGIPMSFILTER, Filter, Size, Filter, Size,
                     &Returned, NULL, NULL);

    if (Error == 0) {
        if (*SourceCount > 0) {
            CopyMemory(SourceList, Filter->imsf_slist,
                       *SourceCount * sizeof(*SourceList));
            *SourceCount = Filter->imsf_numsrc;
        }
        *FilterMode = Filter->imsf_fmode;
    }

    HeapFree(GetProcessHeap(), 0, Filter);

    return Error;
}
#endif /* INCL_WINSOCK_API_PROTOTYPES */

#if (NTDDI_VERSION >= NTDDI_WINXP)
#if INCL_WINSOCK_API_PROTOTYPES

WS2TCPIP_INLINE
int
setsourcefilter(
    _In_ SOCKET Socket,
    _In_ ULONG Interface,
    _In_ CONST SOCKADDR *Group,
    _In_ int GroupLength,
    _In_ MULTICAST_MODE_TYPE FilterMode,
    _In_ ULONG SourceCount,
    _In_reads_(SourceCount) CONST SOCKADDR_STORAGE *SourceList
    )
{
    int Error;
    DWORD Size, Returned;
    PGROUP_FILTER Filter;

    if (SourceCount >=
        (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Size = GROUP_FILTER_SIZE(SourceCount);
    Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
    if (Filter == NULL) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Filter->gf_interface = Interface;
    ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
    CopyMemory(&Filter->gf_group, Group, GroupLength);
    Filter->gf_fmode = FilterMode;
    Filter->gf_numsrc = SourceCount;
    if (SourceCount > 0) {
        CopyMemory(Filter->gf_slist, SourceList,
                   SourceCount * sizeof(*SourceList));
    }

    Error = WSAIoctl(Socket, SIOCSMSFILTER, Filter, Size, NULL, 0,
                     &Returned, NULL, NULL);

    HeapFree(GetProcessHeap(), 0, Filter);

    return Error;
}

_Success_(return == 0)
WS2TCPIP_INLINE
int
getsourcefilter(
    _In_ SOCKET Socket,
    _In_ ULONG Interface,
    _In_ CONST SOCKADDR *Group,
    _In_ int GroupLength,
    _Out_ MULTICAST_MODE_TYPE *FilterMode,
    _Inout_ ULONG *SourceCount,
    _Out_writes_(*SourceCount) SOCKADDR_STORAGE *SourceList
    )
{
    int Error;
    DWORD Size, Returned;
    PGROUP_FILTER Filter;

    if (*SourceCount >
        (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Size = GROUP_FILTER_SIZE(*SourceCount);
    Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
    if (Filter == NULL) {
        WSASetLastError(WSAENOBUFS);
        return SOCKET_ERROR;
    }

    Filter->gf_interface = Interface;
    ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
    CopyMemory(&Filter->gf_group, Group, GroupLength);
    Filter->gf_numsrc = *SourceCount;

    Error = WSAIoctl(Socket, SIOCGMSFILTER, Filter, Size, Filter, Size,
                     &Returned, NULL, NULL);

    if (Error == 0) {
        if (*SourceCount > 0) {
            CopyMemory(SourceList, Filter->gf_slist,
                       *SourceCount * sizeof(*SourceList));
            *SourceCount = Filter->gf_numsrc;
        }
        *FilterMode = Filter->gf_fmode;
    }

    HeapFree(GetProcessHeap(), 0, Filter);

    return Error;
}
#endif /* INCL_WINSOCK_API_PROTOTYPES */
#endif

#ifdef IDEAL_SEND_BACKLOG_IOCTLS

//
// Wrapper functions for the ideal send backlog query and change notification
// ioctls
//

#if INCL_WINSOCK_API_PROTOTYPES

WS2TCPIP_INLINE
int
idealsendbacklogquery(
    _In_ SOCKET s,
    _Out_ ULONG *pISB
    )
{
    DWORD bytes;

    return WSAIoctl(s, SIO_IDEAL_SEND_BACKLOG_QUERY,
                    NULL, 0, pISB, sizeof(*pISB), &bytes, NULL, NULL);
}

WS2TCPIP_INLINE
int
idealsendbacklognotify(
    _In_ SOCKET s,
    _In_opt_ LPWSAOVERLAPPED lpOverlapped,
    _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    )
{
    DWORD bytes;

    return WSAIoctl(s, SIO_IDEAL_SEND_BACKLOG_CHANGE,
                    NULL, 0, NULL, 0, &bytes,
                    lpOverlapped, lpCompletionRoutine);
}
#endif /* INCL_WINSOCK_API_PROTOTYPES */

#endif

#if (_WIN32_WINNT >= 0x0600)
#ifdef _SECURE_SOCKET_TYPES_DEFINED_

//
// Secure socket API definitions
//

WINSOCK_API_LINKAGE
INT
WSAAPI
WSASetSocketSecurity (
   _In_ SOCKET Socket,
   _In_reads_bytes_opt_(SecuritySettingsLen) const SOCKET_SECURITY_SETTINGS* SecuritySettings,
   _In_ ULONG SecuritySettingsLen,
   _In_opt_ LPWSAOVERLAPPED Overlapped,
   _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);

WINSOCK_API_LINKAGE
INT
WSAAPI
WSAQuerySocketSecurity (
   _In_ SOCKET Socket,
   _In_reads_bytes_opt_(SecurityQueryTemplateLen) const SOCKET_SECURITY_QUERY_TEMPLATE* SecurityQueryTemplate,
   _In_ ULONG SecurityQueryTemplateLen,
   _Out_writes_bytes_to_opt_(*SecurityQueryInfoLen, *SecurityQueryInfoLen) SOCKET_SECURITY_QUERY_INFO* SecurityQueryInfo,
   _Inout_ ULONG* SecurityQueryInfoLen,
   _In_opt_ LPWSAOVERLAPPED Overlapped,
   _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);

WINSOCK_API_LINKAGE
INT
WSAAPI
WSASetSocketPeerTargetName (
   _In_ SOCKET Socket,
   _In_reads_bytes_(PeerTargetNameLen) const SOCKET_PEER_TARGET_NAME* PeerTargetName,
   _In_ ULONG PeerTargetNameLen,
   _In_opt_ LPWSAOVERLAPPED Overlapped,
   _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);

WINSOCK_API_LINKAGE
INT
WSAAPI
WSADeleteSocketPeerTargetName (
   _In_ SOCKET Socket,
   _In_reads_bytes_(PeerAddrLen) const struct sockaddr* PeerAddr,
   _In_ ULONG PeerAddrLen,
   _In_opt_ LPWSAOVERLAPPED Overlapped,
   _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);

WINSOCK_API_LINKAGE
INT
WSAAPI
WSAImpersonateSocketPeer (
   _In_ SOCKET Socket,
   _In_reads_bytes_opt_(PeerAddrLen) const struct sockaddr* PeerAddr,
   _In_ ULONG PeerAddrLen
);

WINSOCK_API_LINKAGE
INT
WSAAPI
WSARevertImpersonation ();

#endif //_SECURE_SOCKET_TYPES_DEFINED_
#endif //(_WIN32_WINNT >= 0x0600)

#ifdef __cplusplus
}
#endif

//
// Unless the build environment is explicitly targeting only
// platforms that include built-in getaddrinfo() support, include
// the backwards-compatibility version of the relevant APIs.
//
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT <= 0x0500)
#include <wspiapi.h>
#endif

#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion

#endif  /* _WS2TCPIP_H_ */


text:
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  - 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.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
/*
  Default header file for malloc-2.8.x, written by Doug Lea
  and released to the public domain, as explained at
  http://creativecommons.org/publicdomain/zero/1.0/

  This header is for ANSI C/C++ only.  You can set any of
  the following #defines before including:

  * If USE_DL_PREFIX is defined, it is assumed that malloc.c
    was also compiled with this option, so all routines
    have names starting with "dl".

  * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this
    file will be #included AFTER <malloc.h>. This is needed only if
    your system defines a struct mallinfo that is incompatible with the
    standard one declared here.  Otherwise, you can include this file
    INSTEAD of your system system <malloc.h>.  At least on ANSI, all
    declarations should be compatible with system versions

  * If MSPACES is defined, declarations for mspace versions are included.
*/

#ifdef USE_DLMALLOC
#ifndef MALLOC_280_H
#define MALLOC_280_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>   /* for size_t */

#ifndef ONLY_MSPACES
#define ONLY_MSPACES 0     /* define to a value */
#elif ONLY_MSPACES != 0
#define ONLY_MSPACES 1
#endif  /* ONLY_MSPACES */
#ifndef NO_MALLINFO
#define NO_MALLINFO 0
#endif  /* NO_MALLINFO */

#ifndef MSPACES
#if ONLY_MSPACES
#define MSPACES 1
#else   /* ONLY_MSPACES */
#define MSPACES 0
#endif  /* ONLY_MSPACES */
#endif  /* MSPACES */

#if !ONLY_MSPACES

#ifndef USE_DL_PREFIX
#define dlcalloc               calloc
#define dlfree                 free
#define dlmalloc               malloc
#define dlmemalign             memalign
#define dlposix_memalign       posix_memalign
#define dlrealloc              realloc
#define dlvalloc               valloc
#define dlpvalloc              pvalloc
#define dlmallinfo             mallinfo
#define dlmallopt              mallopt
#define dlmalloc_trim          malloc_trim
#define dlmalloc_stats         malloc_stats
#define dlmalloc_usable_size   malloc_usable_size
#define dlmalloc_footprint     malloc_footprint
#define dlmalloc_max_footprint malloc_max_footprint
#define dlmalloc_footprint_limit malloc_footprint_limit
#define dlmalloc_set_footprint_limit malloc_set_footprint_limit
#define dlmalloc_inspect_all   malloc_inspect_all
#define dlindependent_calloc   independent_calloc
#define dlindependent_comalloc independent_comalloc
#define dlbulk_free            bulk_free
#endif /* USE_DL_PREFIX */

#if !NO_MALLINFO
#ifndef HAVE_USR_INCLUDE_MALLOC_H
#ifndef _MALLOC_H
#ifndef MALLINFO_FIELD_TYPE
#define MALLINFO_FIELD_TYPE size_t
#endif /* MALLINFO_FIELD_TYPE */
#ifndef STRUCT_MALLINFO_DECLARED
#define STRUCT_MALLINFO_DECLARED 1
struct mallinfo {
  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
  MALLINFO_FIELD_TYPE fordblks; /* total free space */
  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
};
#endif /* STRUCT_MALLINFO_DECLARED */
#endif  /* _MALLOC_H */
#endif  /* HAVE_USR_INCLUDE_MALLOC_H */
#endif  /* !NO_MALLINFO */

/*
Stuffs the global malloc_params and malloc_state data into a buffer. Calling with an incorrect buffer size
or a NULL buffer pointer will cause this call to return EINVAL and update the bufferSize argument.
*/
int GetDLMallocGlobalState(size_t* bufferSize, void* buffer);

/*
Copies the supplied data over the global malloc_params and malloc_state variables. This is done to
support the QFork implementation in the forked process.
*/
int SetDLMallocGlobalState(size_t bufferSize, void* buffer);

/*
  malloc(size_t n)
  Returns a pointer to a newly allocated chunk of at least n bytes, or
  null if no space is available, in which case errno is set to ENOMEM
  on ANSI C systems.

  If n is zero, malloc returns a minimum-sized chunk. (The minimum
  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
  systems.)  Note that size_t is an unsigned type, so calls with
  arguments that would be negative if signed are interpreted as
  requests for huge amounts of space, which will often fail. The
  maximum supported value of n differs across systems, but is in all
  cases less than the maximum representable value of a size_t.
*/
void* dlmalloc(size_t);

/*
  free(void* p)
  Releases the chunk of memory pointed to by p, that had been previously
  allocated using malloc or a related routine such as realloc.
  It has no effect if p is null. If p was not malloced or already
  freed, free(p) will by default cuase the current program to abort.
*/
void  dlfree(void*);

/*
  calloc(size_t n_elements, size_t element_size);
  Returns a pointer to n_elements * element_size bytes, with all locations
  set to zero.
*/
void* dlcalloc(size_t, size_t);

/*
  realloc(void* p, size_t n)
  Returns a pointer to a chunk of size n that contains the same data
  as does chunk p up to the minimum of (n, p's size) bytes, or null
  if no space is available.

  The returned pointer may or may not be the same as p. The algorithm
  prefers extending p in most cases when possible, otherwise it
  employs the equivalent of a malloc-copy-free sequence.

  If p is null, realloc is equivalent to malloc.

  If space is not available, realloc returns null, errno is set (if on
  ANSI) and p is NOT freed.

  if n is for fewer bytes than already held by p, the newly unused
  space is lopped off and freed if possible.  realloc with a size
  argument of zero (re)allocates a minimum-sized chunk.

  The old unix realloc convention of allowing the last-free'd chunk
  to be used as an argument to realloc is not supported.
*/
void* dlrealloc(void*, size_t);

/*
  realloc_in_place(void* p, size_t n)
  Resizes the space allocated for p to size n, only if this can be
  done without moving p (i.e., only if there is adjacent space
  available if n is greater than p's current allocated size, or n is
  less than or equal to p's size). This may be used instead of plain
  realloc if an alternative allocation strategy is needed upon failure
  to expand space; for example, reallocation of a buffer that must be
  memory-aligned or cleared. You can use realloc_in_place to trigger
  these alternatives only when needed.

  Returns p if successful; otherwise null.
*/
void* dlrealloc_in_place(void*, size_t);

/*
  memalign(size_t alignment, size_t n);
  Returns a pointer to a newly allocated chunk of n bytes, aligned
  in accord with the alignment argument.

  The alignment argument should be a power of two. If the argument is
  not a power of two, the nearest greater power is used.
  8-byte alignment is guaranteed by normal malloc calls, so don't
  bother calling memalign with an argument of 8 or less.

  Overreliance on memalign is a sure way to fragment space.
*/
void* dlmemalign(size_t, size_t);

/*
  int posix_memalign(void** pp, size_t alignment, size_t n);
  Allocates a chunk of n bytes, aligned in accord with the alignment
  argument. Differs from memalign only in that it (1) assigns the
  allocated memory to *pp rather than returning it, (2) fails and
  returns EINVAL if the alignment is not a power of two (3) fails and
  returns ENOMEM if memory cannot be allocated.
*/
int dlposix_memalign(void**, size_t, size_t);

/*
  valloc(size_t n);
  Equivalent to memalign(pagesize, n), where pagesize is the page
  size of the system. If the pagesize is unknown, 4096 is used.
*/
void* dlvalloc(size_t);

/*
  mallopt(int parameter_number, int parameter_value)
  Sets tunable parameters The format is to provide a
  (parameter-number, parameter-value) pair.  mallopt then sets the
  corresponding parameter to the argument value if it can (i.e., so
  long as the value is meaningful), and returns 1 if successful else
  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,
  normally defined in malloc.h.  None of these are use in this malloc,
  so setting them has no effect. But this malloc also supports other
  options in mallopt:

  Symbol            param #  default    allowed param values
  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1U disables trimming)
  M_GRANULARITY        -2     page size   any power of 2 >= page size
  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
*/
int dlmallopt(int, int);

#define M_TRIM_THRESHOLD     (-1)
#define M_GRANULARITY        (-2)
#define M_MMAP_THRESHOLD     (-3)

/*
  malloc_footprint();
  Returns the number of bytes obtained from the system.  The total
  number of bytes allocated by malloc, realloc etc., is less than this
  value. Unlike mallinfo, this function returns only a precomputed
  result, so can be called frequently to monitor memory consumption.
  Even if locks are otherwise defined, this function does not use them,
  so results might not be up to date.
*/
size_t dlmalloc_footprint(void);

/*
  malloc_max_footprint();
  Returns the maximum number of bytes obtained from the system. This
  value will be greater than current footprint if deallocated space
  has been reclaimed by the system. The peak number of bytes allocated
  by malloc, realloc etc., is less than this value. Unlike mallinfo,
  this function returns only a precomputed result, so can be called
  frequently to monitor memory consumption.  Even if locks are
  otherwise defined, this function does not use them, so results might
  not be up to date.
*/
size_t dlmalloc_max_footprint(void);

/*
  malloc_footprint_limit();
  Returns the number of bytes that the heap is allowed to obtain from
  the system, returning the last value returned by
  malloc_set_footprint_limit, or the maximum size_t value if
  never set. The returned value reflects a permission. There is no
  guarantee that this number of bytes can actually be obtained from
  the system.
*/
size_t dlmalloc_footprint_limit(void);

/*
  malloc_set_footprint_limit();
  Sets the maximum number of bytes to obtain from the system, causing
  failure returns from malloc and related functions upon attempts to
  exceed this value. The argument value may be subject to page
  rounding to an enforceable limit; this actual value is returned.
  Using an argument of the maximum possible size_t effectively
  disables checks. If the argument is less than or equal to the
  current malloc_footprint, then all future allocations that require
  additional system memory will fail. However, invocation cannot
  retroactively deallocate existing used memory.
*/
size_t dlmalloc_set_footprint_limit(size_t bytes);

/*
  malloc_inspect_all(void(*handler)(void *start,
                                    void *end,
                                    size_t used_bytes,
                                    void* callback_arg),
                      void* arg);
  Traverses the heap and calls the given handler for each managed
  region, skipping all bytes that are (or may be) used for bookkeeping
  purposes.  Traversal does not include include chunks that have been
  directly memory mapped. Each reported region begins at the start
  address, and continues up to but not including the end address.  The
  first used_bytes of the region contain allocated data. If
  used_bytes is zero, the region is unallocated. The handler is
  invoked with the given callback argument. If locks are defined, they
  are held during the entire traversal. It is a bad idea to invoke
  other malloc functions from within the handler.

  For example, to count the number of in-use chunks with size greater
  than 1000, you could write:
  static int count = 0;
  void count_chunks(void* start, void* end, size_t used, void* arg) {
    if (used >= 1000) ++count;
  }
  then:
    malloc_inspect_all(count_chunks, NULL);

  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
*/
void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
                           void* arg);

#if !NO_MALLINFO
/*
  mallinfo()
  Returns (by copy) a struct containing various summary statistics:

  arena:     current total non-mmapped bytes allocated from system
  ordblks:   the number of free chunks
  smblks:    always zero.
  hblks:     current number of mmapped regions
  hblkhd:    total bytes held in mmapped regions
  usmblks:   the maximum total allocated space. This will be greater
                than current total if trimming has occurred.
  fsmblks:   always zero
  uordblks:  current total allocated space (normal or mmapped)
  fordblks:  total free space
  keepcost:  the maximum number of bytes that could ideally be released
               back to system via malloc_trim. ("ideally" means that
               it ignores page restrictions etc.)

  Because these fields are ints, but internal bookkeeping may
  be kept as longs, the reported values may wrap around zero and
  thus be inaccurate.
*/

struct mallinfo dlmallinfo(void);
#endif  /* NO_MALLINFO */

/*
  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);

  independent_calloc is similar to calloc, but instead of returning a
  single cleared space, it returns an array of pointers to n_elements
  independent elements that can hold contents of size elem_size, each
  of which starts out cleared, and can be independently freed,
  realloc'ed etc. The elements are guaranteed to be adjacently
  allocated (this is not guaranteed to occur with multiple callocs or
  mallocs), which may also improve cache locality in some
  applications.

  The "chunks" argument is optional (i.e., may be null, which is
  probably the most typical usage). If it is null, the returned array
  is itself dynamically allocated and should also be freed when it is
  no longer needed. Otherwise, the chunks array must be of at least
  n_elements in length. It is filled in with the pointers to the
  chunks.

  In either case, independent_calloc returns this pointer array, or
  null if the allocation failed.  If n_elements is zero and "chunks"
  is null, it returns a chunk representing an array with zero elements
  (which should be freed if not wanted).

  Each element must be freed when it is no longer needed. This can be
  done all at once using bulk_free.

  independent_calloc simplifies and speeds up implementations of many
  kinds of pools.  It may also be useful when constructing large data
  structures that initially have a fixed number of fixed-sized nodes,
  but the number is not known at compile time, and some of the nodes
  may later need to be freed. For example:

  struct Node { int item; struct Node* next; };

  struct Node* build_list() {
    struct Node** pool;
    int n = read_number_of_nodes_needed();
    if (n <= 0) return 0;
    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
    if (pool == 0) die();
    // organize into a linked list...
    struct Node* first = pool[0];
    for (i = 0; i < n-1; ++i)
      pool[i]->next = pool[i+1];
    free(pool);     // Can now free the array (or not, if it is needed later)
    return first;
  }
*/
void** dlindependent_calloc(size_t, size_t, void**);

/*
  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);

  independent_comalloc allocates, all at once, a set of n_elements
  chunks with sizes indicated in the "sizes" array.    It returns
  an array of pointers to these elements, each of which can be
  independently freed, realloc'ed etc. The elements are guaranteed to
  be adjacently allocated (this is not guaranteed to occur with
  multiple callocs or mallocs), which may also improve cache locality
  in some applications.

  The "chunks" argument is optional (i.e., may be null). If it is null
  the returned array is itself dynamically allocated and should also
  be freed when it is no longer needed. Otherwise, the chunks array
  must be of at least n_elements in length. It is filled in with the
  pointers to the chunks.

  In either case, independent_comalloc returns this pointer array, or
  null if the allocation failed.  If n_elements is zero and chunks is
  null, it returns a chunk representing an array with zero elements
  (which should be freed if not wanted).

  Each element must be freed when it is no longer needed. This can be
  done all at once using bulk_free.

  independent_comallac differs from independent_calloc in that each
  element may have a different size, and also that it does not
  automatically clear elements.

  independent_comalloc can be used to speed up allocation in cases
  where several structs or objects must always be allocated at the
  same time.  For example:

  struct Head { ... }
  struct Foot { ... }

  void send_message(char* msg) {
    int msglen = strlen(msg);
    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
    void* chunks[3];
    if (independent_comalloc(3, sizes, chunks) == 0)
      die();
    struct Head* head = (struct Head*)(chunks[0]);
    char*        body = (char*)(chunks[1]);
    struct Foot* foot = (struct Foot*)(chunks[2]);
    // ...
  }

  In general though, independent_comalloc is worth using only for
  larger values of n_elements. For small values, you probably won't
  detect enough difference from series of malloc calls to bother.

  Overuse of independent_comalloc can increase overall memory usage,
  since it cannot reuse existing noncontiguous small chunks that
  might be available for some of the elements.
*/
void** dlindependent_comalloc(size_t, size_t*, void**);

/*
  bulk_free(void* array[], size_t n_elements)
  Frees and clears (sets to null) each non-null pointer in the given
  array.  This is likely to be faster than freeing them one-by-one.
  If footers are used, pointers that have been allocated in different
  mspaces are not freed or cleared, and the count of all such pointers
  is returned.  For large arrays of pointers with poor locality, it
  may be worthwhile to sort this array before calling bulk_free.
*/
size_t  dlbulk_free(void**, size_t n_elements);

/*
  pvalloc(size_t n);
  Equivalent to valloc(minimum-page-that-holds(n)), that is,
  round up n to nearest pagesize.
 */
void*  dlpvalloc(size_t);

/*
  malloc_trim(size_t pad);

  If possible, gives memory back to the system (via negative arguments
  to sbrk) if there is unused memory at the `high' end of the malloc
  pool or in unused MMAP segments. You can call this after freeing
  large blocks of memory to potentially reduce the system-level memory
  requirements of a program. However, it cannot guarantee to reduce
  memory. Under some allocation patterns, some large free blocks of
  memory will be locked between two used chunks, so they cannot be
  given back to the system.

  The `pad' argument to malloc_trim represents the amount of free
  trailing space to leave untrimmed. If this argument is zero, only
  the minimum amount of memory to maintain internal data structures
  will be left. Non-zero arguments can be supplied to maintain enough
  trailing space to service future expected allocations without having
  to re-obtain memory from the system.

  Malloc_trim returns 1 if it actually released any memory, else 0.
*/
int  dlmalloc_trim(size_t);

/*
  malloc_stats();
  Prints on stderr the amount of space obtained from the system (both
  via sbrk and mmap), the maximum amount (which may be more than
  current if malloc_trim and/or munmap got called), and the current
  number of bytes allocated via malloc (or realloc, etc) but not yet
  freed. Note that this is the number of bytes allocated, not the
  number requested. It will be larger than the number requested
  because of alignment and bookkeeping overhead. Because it includes
  alignment wastage as being in use, this figure may be greater than
  zero even when no user-level chunks are allocated.

  The reported current and maximum system memory can be inaccurate if
  a program makes other calls to system memory allocation functions
  (normally sbrk) outside of malloc.

  malloc_stats prints only the most commonly interesting statistics.
  More information can be obtained by calling mallinfo.

  malloc_stats is not compiled if NO_MALLOC_STATS is defined.
*/
void  dlmalloc_stats(void);

#endif /* !ONLY_MSPACES */

/*
  malloc_usable_size(void* p);

  Returns the number of bytes you can actually use in
  an allocated chunk, which may be more than you requested (although
  often not) due to alignment and minimum size constraints.
  You can use this many bytes without worrying about
  overwriting other allocated objects. This is not a particularly great
  programming practice. malloc_usable_size can be more useful in
  debugging and assertions, for example:

  p = malloc(n);
  assert(malloc_usable_size(p) >= 256);
*/
size_t dlmalloc_usable_size(const void*);

#if MSPACES

/*
  mspace is an opaque type representing an independent
  region of space that supports mspace_malloc, etc.
*/
typedef void* mspace;

/*
  create_mspace creates and returns a new independent space with the
  given initial capacity, or, if 0, the default granularity size.  It
  returns null if there is no system memory available to create the
  space.  If argument locked is non-zero, the space uses a separate
  lock to control access. The capacity of the space will grow
  dynamically as needed to service mspace_malloc requests.  You can
  control the sizes of incremental increases of this space by
  compiling with a different DEFAULT_GRANULARITY or dynamically
  setting with mallopt(M_GRANULARITY, value).
*/
mspace create_mspace(size_t capacity, int locked);

/*
  destroy_mspace destroys the given space, and attempts to return all
  of its memory back to the system, returning the total number of
  bytes freed. After destruction, the results of access to all memory
  used by the space become undefined.
*/
size_t destroy_mspace(mspace msp);

/*
  create_mspace_with_base uses the memory supplied as the initial base
  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
  space is used for bookkeeping, so the capacity must be at least this
  large. (Otherwise 0 is returned.) When this initial space is
  exhausted, additional memory will be obtained from the system.
  Destroying this space will deallocate all additionally allocated
  space (if possible) but not the initial base.
*/
mspace create_mspace_with_base(void* base, size_t capacity, int locked);

/*
  mspace_track_large_chunks controls whether requests for large chunks
  are allocated in their own untracked mmapped regions, separate from
  others in this mspace. By default large chunks are not tracked,
  which reduces fragmentation. However, such chunks are not
  necessarily released to the system upon destroy_mspace.  Enabling
  tracking by setting to true may increase fragmentation, but avoids
  leakage when relying on destroy_mspace to release all memory
  allocated using this space.  The function returns the previous
  setting.
*/
int mspace_track_large_chunks(mspace msp, int enable);

#if !NO_MALLINFO
/*
  mspace_mallinfo behaves as mallinfo, but reports properties of
  the given space.
*/
struct mallinfo mspace_mallinfo(mspace msp);
#endif /* NO_MALLINFO */

/*
  An alias for mallopt.
*/
int mspace_mallopt(int, int);

/*
  The following operate identically to their malloc counterparts
  but operate only for the given mspace argument
*/
void* mspace_malloc(mspace msp, size_t bytes);
void mspace_free(mspace msp, void* mem);
void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize);
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
void** mspace_independent_calloc(mspace msp, size_t n_elements,
                                 size_t elem_size, void* chunks[]);
void** mspace_independent_comalloc(mspace msp, size_t n_elements,
                                   size_t sizes[], void* chunks[]);
size_t mspace_bulk_free(mspace msp, void**, size_t n_elements);
size_t mspace_usable_size(const void* mem);
void mspace_malloc_stats(mspace msp);
int mspace_trim(mspace msp, size_t pad);
size_t mspace_footprint(mspace msp);
size_t mspace_max_footprint(mspace msp);
size_t mspace_footprint_limit(mspace msp);
size_t mspace_set_footprint_limit(mspace msp, size_t bytes);
void mspace_inspect_all(mspace msp,
                        void(*handler)(void *, void *, size_t, void*),
                        void* arg);
#endif  /* MSPACES */

#ifdef __cplusplus
};  /* end of extern "C" */
#endif

#endif /* MALLOC_280_H */
#endif /* USE_DLMALLOC */


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

    void SetupRedisGlobals(LPVOID redisData, size_t redisDataSize, uint32_t dictHashKey);
    int do_rdbSave(char* filename);
    int do_aofSave(char* filename, int aof_pipe_read_ack, int aof_pipe_read_data, int aof_pipe_write_ack);
    int do_socketSave(int *fds, int numfds, uint64_t *clientids, int pipe_write_fd);

#ifdef __cplusplus
}
#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 WIN32_INTEROP_APIS_H
#define WIN32_INTEROP_APIS_H

#include "Win32_types.h"
#include <Windows.h>
#include <stdio.h>      // for rename

// API replacement for non-fd stdio functions
#define fseeko      _fseeki64
#define ftello      _ftelli64
#define snprintf    _snprintf
#define strcasecmp  _stricmp
#define strtoll     _strtoi64

#ifdef _WIN64
#define strtol      _strtoi64
#define strtoul     _strtoui64
#endif

#define sleep(x) Sleep((x)*1000)
/* Redis calls usleep(1) to give thread some time.
 * Sleep(0) should do the same on Windows.
 * In other cases, usleep is called with millisec resolution
 * which can be directly translated to WinAPI Sleep() */
#undef usleep
#define usleep(x) (x == 1) ? Sleep(0) : Sleep((int)((x)/1000))

/* following defined to choose little endian byte order */
#define __i386__ 1
#if !defined(va_copy)
#define va_copy(d,s)  d = (s)
#endif

#ifndef __RTL_GENRANDOM
#define __RTL_GENRANDOM 1
typedef BOOLEAN(_stdcall* RtlGenRandomFunc)(void * RandomBuffer, ULONG RandomBufferLength);
#endif
RtlGenRandomFunc RtlGenRandom;

#define random()    replace_random()
#define rand()      replace_random()
#define srandom     srand
int replace_random();

#define rename(a,b) replace_rename(a,b)
int replace_rename(const char *src, const char *dest);

int truncate(const char *path, PORT_LONGLONG length);

#define lseek lseek64

#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void InitThreadControl();
void IncrementWorkerThreadCount();
void DecrementWorkerThreadCount();
void RequestSuspension();
BOOL SuspensionCompleted();
void ResumeFromSuspension();

void WorkerThread_EnterSafeMode();
void WorkerThread_ExitSafeMode();

#ifdef __cplusplus
}
#endif


text:
/*
 * Copyright (c), Microsoft Open Technologies, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - 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.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */

#pragma once

#include <Windows.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

BOOL g_IsForkedProcess;

typedef enum operationType {
    otINVALID = 0,
    otRDB = 1,
    otAOF = 2,
    otSocket = 3
} OperationType;

typedef enum operationStatus {
    osUNSTARTED = 0,
    osINPROGRESS = 1,
    osCOMPLETE = 2,
    osFAILED = 3
} OperationStatus;

typedef enum startupStatus {
    ssFAILED = 0,                 // Something went wrong, exit program with error.
    ssCONTINUE_AS_PARENT = 1,     // Parent qfork initialization complete, continue as parent instance. Call QForkShutdown when exiting.
    ssCHILD_EXIT = 2              // Child completed operation. Call QForkShutdown and exit.
} StartupStatus;

// For parent process use only
pid_t BeginForkOperation_Rdb(
    char* fileName,
    LPVOID redisData,
    int sizeOfRedisData,
    uint32_t dictHashSeed);

pid_t BeginForkOperation_Aof(
    int aof_pipe_write_ack_to_parent,
    int aof_pipe_read_ack_from_parent,
    int aof_pipe_read_data_from_parent,
    char* fileName,
    LPVOID redisData,
    int sizeOfRedisData,
    uint32_t dictHashSeed);

pid_t BeginForkOperation_Socket(
    int *fds,
    int numfds,
    uint64_t *clientids,
    int pipe_write_fd,
    LPVOID redisData,
    int sizeOfRedisData,
    uint32_t dictHashSeed);

void BeginForkOperation_Socket_Duplicate(DWORD dwProcessId);

OperationStatus GetForkOperationStatus();
BOOL EndForkOperation(int * pExitCode);
BOOL AbortForkOperation();

#ifdef USE_DLMALLOC
  LPVOID AllocHeapBlock(size_t size, BOOL allocateHigh);
  // for no persistence optimization/feature when using dlmalloc
  extern void*(*g_malloc)(size_t);
  extern void*(*g_calloc)(size_t, size_t);
  extern void*(*g_realloc)(void*, size_t);
  extern void(*g_free)(void*);
  extern size_t(*g_msize)(void*);
#elif USE_JEMALLOC
  LPVOID AllocHeapBlock(LPVOID addr, size_t size, BOOL zero);
  BOOL PurgePages(LPVOID addr, size_t length);
#endif
BOOL FreeHeapBlock(LPVOID addr, size_t size);

#ifndef NO_QFORKIMPL
#ifdef QFORK_MAIN_IMPL
int redis_main(int argc, char** argv);
#else
#define main redis_main
#endif
#endif

#ifdef __cplusplus
}
#endif


text:
/* tolua: functions to push C values.
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Apr 2003
** $Id: $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/

#include "tolua++.h"
#include "lauxlib.h"

#include <stdlib.h>

TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
{
 lua_pushvalue(L,lo);
}

TOLUA_API void tolua_pushboolean (lua_State* L, int value)
{
 lua_pushboolean(L,value);
}

TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value)
{
 lua_pushnumber(L,value);
}

TOLUA_API void tolua_pushstring (lua_State* L, const char* value)
{
 if (value == NULL)
  lua_pushnil(L);
 else
  lua_pushstring(L,value);
}

TOLUA_API void tolua_pushuserdata (lua_State* L, void* value)
{
 if (value == NULL)
  lua_pushnil(L);
 else
  lua_pushlightuserdata(L,value);
}

TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
{
 if (value == NULL)
  lua_pushnil(L);
 else
 {
  luaL_getmetatable(L, type);
  lua_pushstring(L,"tolua_ubox");
  lua_rawget(L,-2);        /* stack: mt ubox */
  if (lua_isnil(L, -1)) {
	  lua_pop(L, 1);
	  lua_pushstring(L, "tolua_ubox");
	  lua_rawget(L, LUA_REGISTRYINDEX);
  };
  lua_pushlightuserdata(L,value);
  lua_rawget(L,-2);                       /* stack: mt ubox ubox[u] */
  if (lua_isnil(L,-1))
  {
   lua_pop(L,1);                          /* stack: mt ubox */
   lua_pushlightuserdata(L,value);
   *(void**)lua_newuserdata(L,sizeof(void *)) = value;   /* stack: mt ubox u newud */
   lua_pushvalue(L,-1);                   /* stack: mt ubox u newud newud */
   lua_insert(L,-4);                      /* stack: mt newud ubox u newud */
   lua_rawset(L,-3);                      /* stack: mt newud ubox */
   lua_pop(L,1);                          /* stack: mt newud */
   /*luaL_getmetatable(L,type);*/
   lua_pushvalue(L, -2);			/* stack: mt newud mt */
   lua_setmetatable(L,-2);			/* stack: mt newud */

   #ifdef LUA_VERSION_NUM
   lua_pushvalue(L, TOLUA_NOPEER);
   #if LUA_VERSION_NUM > 501
	   lua_setuservalue(L, -2);
   #else
	   lua_setfenv(L, -2);
   #endif
   #endif
  }
  else
  {
   /* check the need of updating the metatable to a more specialized class */
   lua_insert(L,-2);                       /* stack: mt ubox[u] ubox */
   lua_pop(L,1);                           /* stack: mt ubox[u] */
   lua_pushstring(L,"tolua_super");
   lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: mt ubox[u] super */
   lua_getmetatable(L,-2);                 /* stack: mt ubox[u] super mt */
   lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] */
			if (lua_istable(L,-1))
			{
				lua_pushstring(L,type);                 /* stack: mt ubox[u] super super[mt] type */
				lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] flag */
				if (lua_toboolean(L,-1) == 1)   /* if true */
				{
					lua_pop(L,3);	/* mt ubox[u]*/
					lua_remove(L, -2);
					return;
				}
			}
			/* type represents a more specilized type */
			/*luaL_getmetatable(L,type);             // stack: mt ubox[u] super super[mt] flag mt */
			lua_pushvalue(L, -5);					/* stack: mt ubox[u] super super[mt] flag mt */
			lua_setmetatable(L,-5);                /* stack: mt ubox[u] super super[mt] flag */
			lua_pop(L,3);                          /* stack: mt ubox[u] */
  }
  lua_remove(L, -2);	/* stack: ubox[u]*/
 }
}

TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type)
{
	tolua_pushusertype(L,value,type);
	tolua_register_gc(L,lua_gettop(L));
}

TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v)
{
 lua_pushnumber(L,index);
 lua_pushvalue(L,v);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v)
{
 lua_pushnumber(L,index);
 lua_pushboolean(L,v);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v)
{
 lua_pushnumber(L,index);
 tolua_pushnumber(L,v);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v)
{
 lua_pushnumber(L,index);
 tolua_pushstring(L,v);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v)
{
 lua_pushnumber(L,index);
 tolua_pushuserdata(L,v);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type)
{
 lua_pushnumber(L,index);
 tolua_pushusertype(L,v,type);
 lua_settable(L,lo);
}

TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type)
{
 lua_pushnumber(L,index);
 tolua_pushusertype(L,v,type);
	tolua_register_gc(L,lua_gettop(L));
 lua_settable(L,lo);
}