SysDepWin.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:49k
- /*
- * XMail by Davide Libenzi ( Intranet and Internet mail server )
- * Copyright (C) 1999,..,2004 Davide Libenzi
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Davide Libenzi <davidel@xmailserver.org>
- *
- */
- #include "SysInclude.h"
- #include "SysDep.h"
- #include "AppDefines.h"
- #define MAX_TLS_KEYS 64
- #define UNUSED_TLS_KEY_PROC ((void (*)(void *)) -1)
- #define SOCK_VERSION_REQUESTED MAKEWORD(2, 0)
- #define SHUTDOWN_RECV_TIMEOUT 2
- ///////////////////////////////////////////////////////////////////////////////
- // Under certain circumstances ( M$ Proxy installed ?! ) a waiting operation
- // may be unlocked even if the IO terminal is not ready to perform following
- // IO request ( an error code WSAEWOULDBLOCK is returned ). The only solution
- // I see is to sleep a bit to prevent processor time wasting :(
- ///////////////////////////////////////////////////////////////////////////////
- #define BLOCKED_SNDRCV_MSSLEEP 200
- #define HANDLE_SOCKS_SUCKS() do { Sleep(BLOCKED_SNDRCV_MSSLEEP); } while (0)
- #define SAIN_Addr(s) (s).sin_addr.S_un.S_addr
- #define MIN_TCP_SEND_SIZE (1024 * 8)
- #define MAX_TCP_SEND_SIZE (1024 * 128)
- #define K_IO_TIME_RATIO 8
- #define MAX_STACK_SHIFT 2048
- #define STACK_ALIGN_BYTES sizeof(int)
- struct TlsKeyEntry {
- void (*pFreeProc) (void *);
- };
- struct TlsKeyData {
- void *pData;
- };
- struct FileFindData {
- char szFindPath[SYS_MAX_PATH];
- HANDLE hFind;
- WIN32_FIND_DATA WFD;
- };
- struct ThreadRunner {
- unsigned int (*pThreadProc) (void *);
- void *pThreadData;
- };
- static void SysInitTlsKeyEntries(void);
- static void SysInitTlsKeys(void);
- static void SysCleanupTlsKeys(void);
- static char const *SysGetLastError(void);
- static int SysSetServerName(void);
- static int SysBlockSocket(SYS_SOCKET SockFD, int OnOff);
- static int SysSetSocketsOptions(SYS_SOCKET SockFD);
- static int SysRecvLL(SYS_SOCKET SockFD, char *pszBuffer, int iBufferSize);
- static int SysSendLL(SYS_SOCKET SockFD, char const *pszBuffer, int iBufferSize);
- static unsigned int SysThreadRunner(void *pRunData);
- static int SysThreadSetup(void);
- static int SysThreadCleanup(void);
- static BOOL WINAPI SysBreakHandlerRoutine(DWORD dwCtrlType);
- static void SysTimetToFileTime(time_t tTime, LPFILETIME pFT);
- static time_t SysFileTimeToTimet(LPFILETIME pFT);
- static unsigned int SysStkCall(unsigned int (*pProc) (void *), void *pData);
- static char szServerName[SYS_MAX_PATH];
- static CRITICAL_SECTION csTLS;
- static bool bSetupEntries = true;
- static TlsKeyEntry TlsKeyEntries[MAX_TLS_KEYS];
- static __declspec(thread)
- TlsKeyData TlsKeys[MAX_TLS_KEYS];
- static time_t tSysStart;
- static SYS_INT64 PCFreq;
- static SYS_INT64 PCSysStart;
- static unsigned int uSRandBase;
- static int iSndBufSize = -1, iRcvBufSize = -1;
- static CRITICAL_SECTION csLog;
- static void (*SysBreakHandler) (void) = NULL;
- static HANDLE hShutdownEvent = NULL;
- static void SysInitTlsKeyEntries(void)
- {
- if (bSetupEntries) {
- for (int ii = 0; ii < MAX_TLS_KEYS; ii++)
- TlsKeyEntries[ii].pFreeProc = UNUSED_TLS_KEY_PROC;
- bSetupEntries = false;
- }
- }
- static void SysInitTlsKeys(void)
- {
- for (int ii = 0; ii < MAX_TLS_KEYS; ii++)
- TlsKeys[ii].pData = NULL;
- }
- static void SysCleanupTlsKeys(void)
- {
- EnterCriticalSection(&csTLS);
- for (int ii = 0; ii < MAX_TLS_KEYS; ii++) {
- if ((TlsKeyEntries[ii].pFreeProc != UNUSED_TLS_KEY_PROC) &&
- (TlsKeyEntries[ii].pFreeProc != NULL))
- TlsKeyEntries[ii].pFreeProc(TlsKeys[ii].pData);
- TlsKeys[ii].pData = NULL;
- }
- LeaveCriticalSection(&csTLS);
- }
- static char const *SysGetLastError(void)
- {
- char *pszMessage = NULL;
- DWORD dwError = GetLastError();
- DWORD dwRet =
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_ARGUMENT_ARRAY,
- NULL,
- dwError,
- LANG_NEUTRAL,
- (LPTSTR) & pszMessage,
- 0,
- NULL);
- static char szMessage[1024] = "";
- if (dwRet == 0)
- SysSNPrintf(szMessage, sizeof(szMessage) - 1, "(0x%lX) Unknown error",
- (unsigned long) dwError);
- else
- SysSNPrintf(szMessage, sizeof(szMessage) - 1, "(0x%lX) %s",
- (unsigned long) dwError, pszMessage);
- if (pszMessage != NULL)
- LocalFree((HLOCAL) pszMessage);
- return (szMessage);
- }
- static int SysSetServerName(void)
- {
- int iSize;
- char *pszSlash;
- char *pszDot;
- char szPath[SYS_MAX_PATH] = APP_NAME_STR;
- GetModuleFileName(NULL, szPath, CountOf(szPath));
- if ((pszSlash = strrchr(szPath, '\')) == NULL)
- pszSlash = szPath;
- else
- pszSlash++;
- if ((pszDot = strchr(pszSlash, '.')) == NULL)
- pszDot = pszSlash + strlen(pszSlash);
- iSize = Min(sizeof(szServerName) - 1, (int) (pszDot - pszSlash));
- Cpy2Sz(szServerName, pszSlash, iSize);
- return (0);
- }
- int SysInitLibrary(void)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Setup timers
- ///////////////////////////////////////////////////////////////////////////////
- LARGE_INTEGER PerfCntFreq;
- LARGE_INTEGER PerfCntCurr;
- QueryPerformanceFrequency(&PerfCntFreq);
- QueryPerformanceCounter(&PerfCntCurr);
- PCFreq = *(SYS_INT64 *) & PerfCntFreq;
- PCFreq /= 1000;
- PCSysStart = *(SYS_INT64 *) & PerfCntCurr;
- _tzset();
- time(&tSysStart);
- uSRandBase = (unsigned int) tSysStart;
- ///////////////////////////////////////////////////////////////////////////////
- // Set the server name
- ///////////////////////////////////////////////////////////////////////////////
- SysSetServerName();
- ///////////////////////////////////////////////////////////////////////////////
- // Setup sockets
- ///////////////////////////////////////////////////////////////////////////////
- WSADATA WSD;
- ZeroData(WSD);
- if (WSAStartup(SOCK_VERSION_REQUESTED, &WSD)) {
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- InitializeCriticalSection(&csTLS);
- SysInitTlsKeyEntries();
- InitializeCriticalSection(&csLog);
- if ((hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) {
- DeleteCriticalSection(&csLog);
- DeleteCriticalSection(&csTLS);
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- if (SysThreadSetup() < 0) {
- ErrorPush();
- CloseHandle(hShutdownEvent);
- DeleteCriticalSection(&csLog);
- DeleteCriticalSection(&csTLS);
- return (ErrorPop());
- }
- return (0);
- }
- void SysCleanupLibrary(void)
- {
- SysThreadCleanup();
- DeleteCriticalSection(&csLog);
- DeleteCriticalSection(&csTLS);
- CloseHandle(hShutdownEvent);
- WSACleanup();
- }
- int SysShutdownLibrary(int iMode)
- {
- SetEvent(hShutdownEvent);
- return (0);
- }
- int SysSetupSocketBuffers(int *piSndBufSize, int *piRcvBufSize)
- {
- if (piSndBufSize != NULL)
- iSndBufSize = *piSndBufSize;
- if (piRcvBufSize != NULL)
- iRcvBufSize = *piRcvBufSize;
- return (0);
- }
- SYS_SOCKET SysCreateSocket(int iAddressFamily, int iType, int iProtocol)
- {
- SOCKET SockFD = WSASocket(iAddressFamily, iType, iProtocol, NULL, 0,
- WSA_FLAG_OVERLAPPED);
- if (SockFD == INVALID_SOCKET) {
- ErrSetErrorCode(ERR_SOCKET_CREATE);
- return (SYS_INVALID_SOCKET);
- }
- if (SysSetSocketsOptions((SYS_SOCKET) SockFD) < 0) {
- SysCloseSocket((SYS_SOCKET) SockFD);
- return (SYS_INVALID_SOCKET);
- }
- return ((SYS_SOCKET) SockFD);
- }
- static int SysBlockSocket(SYS_SOCKET SockFD, int OnOff)
- {
- u_long IoctlLong = (OnOff) ? 0 : 1;
- if (ioctlsocket(SockFD, FIONBIO, &IoctlLong) == SOCKET_ERROR) {
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- return (0);
- }
- static int SysSetSocketsOptions(SYS_SOCKET SockFD)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Set socket buffer sizes
- ///////////////////////////////////////////////////////////////////////////////
- if (iSndBufSize > 0) {
- int iSize = iSndBufSize;
- setsockopt((int) SockFD, SOL_SOCKET, SO_SNDBUF, (const char *) &iSize,
- sizeof(iSize));
- }
- if (iRcvBufSize > 0) {
- int iSize = iRcvBufSize;
- setsockopt((int) SockFD, SOL_SOCKET, SO_RCVBUF, (const char *) &iSize,
- sizeof(iSize));
- }
- int iActivate = 1;
- if (setsockopt(SockFD, SOL_SOCKET, SO_REUSEADDR, (const char *) &iActivate,
- sizeof(iActivate)) != 0) {
- ErrSetErrorCode(ERR_SETSOCKOPT);
- return (ERR_SETSOCKOPT);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Disable linger
- ///////////////////////////////////////////////////////////////////////////////
- struct linger Ling;
- ZeroData(Ling);
- Ling.l_onoff = 0;
- Ling.l_linger = 0;
- setsockopt(SockFD, SOL_SOCKET, SO_LINGER, (const char *) &Ling, sizeof(Ling));
- ///////////////////////////////////////////////////////////////////////////////
- // Set KEEPALIVE if supported
- ///////////////////////////////////////////////////////////////////////////////
- setsockopt(SockFD, SOL_SOCKET, SO_KEEPALIVE, (const char *) &iActivate,
- sizeof(iActivate));
- return (0);
- }
- void SysCloseSocket(SYS_SOCKET SockFD)
- {
- closesocket(SockFD);
- }
- int SysBindSocket(SYS_SOCKET SockFD, const struct sockaddr *SockName, int iNameLen)
- {
- if (bind(SockFD, SockName, iNameLen) == SOCKET_ERROR) {
- ErrSetErrorCode(ERR_SOCKET_BIND);
- return (ERR_SOCKET_BIND);
- }
- return (0);
- }
- void SysListenSocket(SYS_SOCKET SockFD, int iConnections)
- {
- listen(SockFD, iConnections);
- }
- static int SysRecvLL(SYS_SOCKET SockFD, char *pszBuffer, int iBufferSize)
- {
- DWORD dwRtxBytes = 0;
- DWORD dwRtxFlags = 0;
- WSABUF WSABuff;
- ZeroData(WSABuff);
- WSABuff.len = iBufferSize;
- WSABuff.buf = pszBuffer;
- return ((WSARecv(SockFD, &WSABuff, 1, &dwRtxBytes, &dwRtxFlags,
- NULL, NULL) == 0) ? (int) dwRtxBytes : -WSAGetLastError());
- }
- static int SysSendLL(SYS_SOCKET SockFD, char const *pszBuffer, int iBufferSize)
- {
- DWORD dwRtxBytes = 0;
- WSABUF WSABuff;
- ZeroData(WSABuff);
- WSABuff.len = iBufferSize;
- WSABuff.buf = (char *) pszBuffer;
- return ((WSASend(SockFD, &WSABuff, 1, &dwRtxBytes, 0,
- NULL, NULL) == 0) ? (int) dwRtxBytes : -WSAGetLastError());
- }
- int SysRecvData(SYS_SOCKET SockFD, char *pszBuffer, int iBufferSize, int iTimeout)
- {
- HANDLE hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hReadEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- int iRecvBytes = 0;
- HANDLE hWaitEvents[2] = { hReadEvent, hShutdownEvent };
- for (;;) {
- WSAEventSelect(SockFD, (WSAEVENT) hReadEvent, FD_READ | FD_CLOSE);
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- WSAEventSelect(SockFD, (WSAEVENT) hReadEvent, 0);
- if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1)) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- return (ERR_SERVER_SHUTDOWN);
- } else if (dwWaitResult != WSA_WAIT_EVENT_0) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- if ((iRecvBytes = SysRecvLL(SockFD, pszBuffer, iBufferSize)) >= 0)
- break;
- int iErrorCode = -iRecvBytes;
- if (iErrorCode != WSAEWOULDBLOCK) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // You should never get here if Win32 API worked fine
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE_SOCKS_SUCKS();
- }
- CloseHandle(hReadEvent);
- return (iRecvBytes);
- }
- int SysRecv(SYS_SOCKET SockFD, char *pszBuffer, int iBufferSize, int iTimeout)
- {
- int iRtxBytes = 0;
- while (iRtxBytes < iBufferSize) {
- int iRtxCurrent = SysRecvData(SockFD, pszBuffer + iRtxBytes,
- iBufferSize - iRtxBytes, iTimeout);
- if (iRtxCurrent <= 0)
- return (iRtxBytes);
- iRtxBytes += iRtxCurrent;
- }
- return (iRtxBytes);
- }
- int SysRecvDataFrom(SYS_SOCKET SockFD, struct sockaddr *pFrom, int iFromlen,
- char *pszBuffer, int iBufferSize, int iTimeout)
- {
- HANDLE hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hReadEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- DWORD dwRtxBytes = 0;
- WSABUF WSABuff;
- HANDLE hWaitEvents[2] = { hReadEvent, hShutdownEvent };
- ZeroData(WSABuff);
- WSABuff.len = iBufferSize;
- WSABuff.buf = pszBuffer;
- for (;;) {
- WSAEventSelect(SockFD, (WSAEVENT) hReadEvent, FD_READ | FD_CLOSE);
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- WSAEventSelect(SockFD, (WSAEVENT) hReadEvent, 0);
- if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1)) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- return (ERR_SERVER_SHUTDOWN);
- } else if (dwWaitResult != WSA_WAIT_EVENT_0) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- INT FromLen = (INT) iFromlen;
- DWORD dwRtxFlags = 0;
- if (WSARecvFrom(SockFD, &WSABuff, 1, &dwRtxBytes, &dwRtxFlags,
- pFrom, &FromLen, NULL, NULL) == 0)
- break;
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- CloseHandle(hReadEvent);
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // You should never get here if Win32 API worked fine
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE_SOCKS_SUCKS();
- }
- CloseHandle(hReadEvent);
- return ((int) dwRtxBytes);
- }
- int SysSendData(SYS_SOCKET SockFD, char const *pszBuffer, int iBufferSize, int iTimeout)
- {
- HANDLE hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hWriteEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- int iSendBytes = 0;
- HANDLE hWaitEvents[2] = { hWriteEvent, hShutdownEvent };
- for (;;) {
- WSAEventSelect(SockFD, (WSAEVENT) hWriteEvent, FD_WRITE | FD_CLOSE);
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- WSAEventSelect(SockFD, (WSAEVENT) hWriteEvent, 0);
- if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1)) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- return (ERR_SERVER_SHUTDOWN);
- } else if (dwWaitResult != WSA_WAIT_EVENT_0) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- if ((iSendBytes = SysSendLL(SockFD, pszBuffer, iBufferSize)) >= 0)
- break;
- int iErrorCode = -iSendBytes;
- if (iErrorCode != WSAEWOULDBLOCK) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // You should never get here if Win32 API worked fine
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE_SOCKS_SUCKS();
- }
- CloseHandle(hWriteEvent);
- return (iSendBytes);
- }
- int SysSend(SYS_SOCKET SockFD, char const *pszBuffer, int iBufferSize, int iTimeout)
- {
- int iRtxBytes = 0;
- while (iRtxBytes < iBufferSize) {
- int iRtxCurrent = SysSendData(SockFD, pszBuffer + iRtxBytes,
- iBufferSize - iRtxBytes, iTimeout);
- if (iRtxCurrent <= 0)
- return (iRtxBytes);
- iRtxBytes += iRtxCurrent;
- }
- return (iRtxBytes);
- }
- int SysSendDataTo(SYS_SOCKET SockFD, const struct sockaddr *pTo,
- int iToLen, char const *pszBuffer, int iBufferSize, int iTimeout)
- {
- HANDLE hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hWriteEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- DWORD dwRtxBytes = 0;
- WSABUF WSABuff;
- HANDLE hWaitEvents[2] = { hWriteEvent, hShutdownEvent };
- ZeroData(WSABuff);
- WSABuff.len = iBufferSize;
- WSABuff.buf = (char *) pszBuffer;
- for (;;) {
- WSAEventSelect(SockFD, (WSAEVENT) hWriteEvent, FD_WRITE | FD_CLOSE);
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- WSAEventSelect(SockFD, (WSAEVENT) hWriteEvent, 0);
- if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1)) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- return (ERR_SERVER_SHUTDOWN);
- } else if (dwWaitResult != WSA_WAIT_EVENT_0) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- DWORD dwRtxFlags = 0;
- if (WSASendTo(SockFD, &WSABuff, 1, &dwRtxBytes, dwRtxFlags,
- pTo, iToLen, NULL, NULL) == 0)
- break;
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- CloseHandle(hWriteEvent);
- ErrSetErrorCode(ERR_NETWORK);
- return (ERR_NETWORK);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // You should never get here if Win32 API worked fine
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE_SOCKS_SUCKS();
- }
- CloseHandle(hWriteEvent);
- return ((int) dwRtxBytes);
- }
- int SysConnect(SYS_SOCKET SockFD, const SYS_INET_ADDR * pSockName, int iNameLen, int iTimeout)
- {
- HANDLE hConnectEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hConnectEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (ERR_CREATEEVENT);
- }
- WSAEventSelect(SockFD, (WSAEVENT) hConnectEvent, FD_CONNECT);
- int iConnectResult = WSAConnect(SockFD, (const struct sockaddr *) &pSockName->Addr,
- iNameLen, NULL, NULL, NULL, NULL);
- int iConnectError = WSAGetLastError();
- if ((iConnectResult != 0) && (iConnectError == WSAEWOULDBLOCK)) {
- HANDLE hWaitEvents[2] = { hConnectEvent, hShutdownEvent };
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- if (dwWaitResult == WSA_WAIT_EVENT_0) {
- WSANETWORKEVENTS NetEvents;
- if ((WSAEnumNetworkEvents(SockFD, hConnectEvent, &NetEvents) != 0) ||
- (NetEvents.iErrorCode[FD_CONNECT_BIT] != 0)) {
- ErrSetErrorCode(ERR_CONNECT);
- iConnectResult = ERR_CONNECT;
- } else
- iConnectResult = 0;
- } else if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1)) {
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- iConnectResult = ERR_SERVER_SHUTDOWN;
- } else {
- ErrSetErrorCode(ERR_TIMEOUT);
- iConnectResult = ERR_TIMEOUT;
- }
- }
- WSAEventSelect(SockFD, (WSAEVENT) hConnectEvent, 0);
- CloseHandle(hConnectEvent);
- return (iConnectResult);
- }
- SYS_SOCKET SysAccept(SYS_SOCKET SockFD, SYS_INET_ADDR * pSockName, int *iNameLen, int iTimeout)
- {
- HANDLE hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hAcceptEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (SYS_INVALID_SOCKET);
- }
- WSAEventSelect(SockFD, (WSAEVENT) hAcceptEvent, FD_ACCEPT);
- SOCKET SockFDAccept =
- WSAAccept(SockFD, (struct sockaddr *) &pSockName->Addr, iNameLen, NULL, 0);
- int iConnectError = WSAGetLastError();
- if ((SockFDAccept == INVALID_SOCKET) && (iConnectError == WSAEWOULDBLOCK)) {
- HANDLE hWaitEvents[2] = { hAcceptEvent, hShutdownEvent };
- DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hWaitEvents, FALSE,
- (DWORD) (iTimeout * 1000), TRUE);
- if (dwWaitResult == WSA_WAIT_EVENT_0)
- SockFDAccept =
- WSAAccept(SockFD, (struct sockaddr *) &pSockName->Addr, iNameLen,
- NULL, 0);
- else if (dwWaitResult == (WSA_WAIT_EVENT_0 + 1))
- ErrSetErrorCode(ERR_SERVER_SHUTDOWN);
- else
- ErrSetErrorCode(ERR_TIMEOUT);
- }
- WSAEventSelect(SockFD, (WSAEVENT) hAcceptEvent, 0);
- CloseHandle(hAcceptEvent);
- if (SockFDAccept != INVALID_SOCKET) {
- if ((SysBlockSocket(SockFDAccept, 0) < 0) ||
- (SysSetSocketsOptions(SockFDAccept) < 0)) {
- SysCloseSocket(SockFDAccept);
- return (SYS_INVALID_SOCKET);
- }
- }
- return (SockFDAccept);
- }
- int SysSelect(int iMaxFD, SYS_fd_set * pReadFDs, SYS_fd_set * pWriteFDs, SYS_fd_set * pExcptFDs,
- int iTimeout)
- {
- struct timeval TV;
- ZeroData(TV);
- TV.tv_sec = iTimeout;
- TV.tv_usec = 0;
- int iSelectResult = select(iMaxFD + 1, pReadFDs, pWriteFDs, pExcptFDs, &TV);
- if (iSelectResult < 0) {
- ErrSetErrorCode(ERR_SELECT);
- return (ERR_SELECT);
- }
- if (iSelectResult == 0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (iSelectResult);
- }
- int SysSendFile(SYS_SOCKET SockFD, char const *pszFileName, unsigned long ulBaseOffset,
- unsigned long ulEndOffset, int iTimeout)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Open the source file
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- ErrSetErrorCode(ERR_FILE_OPEN);
- return (ERR_FILE_OPEN);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Create file mapping and the file
- ///////////////////////////////////////////////////////////////////////////////
- DWORD dwFileSizeHi = 0;
- DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
- HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY,
- dwFileSizeHi, dwFileSizeLo, NULL);
- if (hFileMap == NULL) {
- CloseHandle(hFile);
- ErrSetErrorCode(ERR_CREATEFILEMAPPING);
- return (ERR_CREATEFILEMAPPING);
- }
- void *pAddress = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
- if (pAddress == NULL) {
- CloseHandle(hFileMap);
- CloseHandle(hFile);
- ErrSetErrorCode(ERR_MAPVIEWOFFILE);
- return (ERR_MAPVIEWOFFILE);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Send the file
- ///////////////////////////////////////////////////////////////////////////////
- int iSndBuffSize = MIN_TCP_SEND_SIZE;
- SYS_UINT64 ullFileSize = (((SYS_UINT64) dwFileSizeHi) << 32) | (SYS_UINT64) dwFileSizeLo;
- SYS_UINT64 ullEndOffset = (ulEndOffset != (unsigned long) -1) ?
- ((SYS_UINT64) ulEndOffset) : ullFileSize;
- SYS_UINT64 ullCurrOffset = (SYS_UINT64) ulBaseOffset;
- char *pszBuffer = (char *) pAddress + ulBaseOffset;
- time_t tStart;
- while (ullCurrOffset < ullEndOffset) {
- int iCurrSend = (int) Min(iSndBuffSize, ullEndOffset - ullCurrOffset);
- tStart = time(NULL);
- if ((iCurrSend = SysSendData(SockFD, pszBuffer, iCurrSend, iTimeout)) < 0) {
- ErrorPush();
- UnmapViewOfFile(pAddress);
- CloseHandle(hFileMap);
- CloseHandle(hFile);
- return (ErrorPop());
- }
- if ((((time(NULL) - tStart) * K_IO_TIME_RATIO) < iTimeout) &&
- (iSndBuffSize < MAX_TCP_SEND_SIZE))
- iSndBuffSize = Min(iSndBuffSize * 2, MAX_TCP_SEND_SIZE);
- pszBuffer += iCurrSend;
- ullCurrOffset += (SYS_UINT64) iCurrSend;
- }
- UnmapViewOfFile(pAddress);
- CloseHandle(hFileMap);
- CloseHandle(hFile);
- return (0);
- }
- int SysSetupAddress(SYS_INET_ADDR & AddrInfo, int iFamily,
- NET_ADDRESS const &NetAddr, int iPortNo)
- {
- ZeroData(AddrInfo);
- AddrInfo.Addr.sin_family = iFamily;
- SAIN_Addr(AddrInfo.Addr) = NetAddr;
- AddrInfo.Addr.sin_port = htons((short) iPortNo);
- return (0);
- }
- int SysGetAddrAddress(SYS_INET_ADDR const &AddrInfo, NET_ADDRESS & NetAddr)
- {
- NetAddr = SAIN_Addr(AddrInfo.Addr);
- return (0);
- }
- int SysGetAddrPort(SYS_INET_ADDR const &AddrInfo)
- {
- return (ntohs(AddrInfo.Addr.sin_port));
- }
- int SysSetAddrAddress(SYS_INET_ADDR & AddrInfo, NET_ADDRESS const &NetAddr)
- {
- SAIN_Addr(AddrInfo.Addr) = NetAddr;
- return (0);
- }
- int SysSetAddrPort(SYS_INET_ADDR & AddrInfo, int iPortNo)
- {
- AddrInfo.Addr.sin_port = htons((short) iPortNo);
- return (0);
- }
- int SysGetHostByName(char const *pszName, NET_ADDRESS & NetAddr)
- {
- struct hostent *pHostEnt = gethostbyname(pszName);
- if ((pHostEnt == NULL) || (pHostEnt->h_addr_list[0] == NULL)) {
- ErrSetErrorCode(ERR_BAD_SERVER_ADDR, pszName);
- return (ERR_BAD_SERVER_ADDR);
- }
- memcpy(&NetAddr, pHostEnt->h_addr_list[0], sizeof(NetAddr));
- return (0);
- }
- int SysGetHostByAddr(SYS_INET_ADDR const &AddrInfo, char *pszFQDN)
- {
- struct hostent *pHostEnt = gethostbyaddr((const char *) &SAIN_Addr(AddrInfo.Addr),
- sizeof(SAIN_Addr(AddrInfo.Addr)), AF_INET);
- if (pHostEnt == NULL) {
- char szIP[128] = "???.???.???.???";
- ErrSetErrorCode(ERR_GET_SOCK_HOST, SysInetNToA(AddrInfo, szIP));
- return (ERR_GET_SOCK_HOST);
- }
- strcpy(pszFQDN, pHostEnt->h_name);
- return (0);
- }
- int SysGetPeerInfo(SYS_SOCKET SockFD, SYS_INET_ADDR & AddrInfo)
- {
- ZeroData(AddrInfo);
- socklen_t InfoSize = sizeof(AddrInfo.Addr);
- if (getpeername(SockFD, (struct sockaddr *) &AddrInfo.Addr, &InfoSize) == -1) {
- ErrSetErrorCode(ERR_GET_PEER_INFO);
- return (ERR_GET_PEER_INFO);
- }
- return (0);
- }
- int SysGetSockInfo(SYS_SOCKET SockFD, SYS_INET_ADDR & AddrInfo)
- {
- ZeroData(AddrInfo);
- socklen_t InfoSize = sizeof(AddrInfo.Addr);
- if (getsockname(SockFD, (struct sockaddr *) &AddrInfo.Addr, &InfoSize) == -1) {
- ErrSetErrorCode(ERR_GET_SOCK_INFO);
- return (ERR_GET_SOCK_INFO);
- }
- return (0);
- }
- char *SysInetNToA(SYS_INET_ADDR const &AddrInfo, char *pszIP)
- {
- union {
- unsigned int a;
- unsigned char b[4];
- } UAddr;
- memcpy(&UAddr, &AddrInfo.Addr.sin_addr, sizeof(UAddr));
- sprintf(pszIP, "%u.%u.%u.%u",
- (unsigned int) UAddr.b[0],
- (unsigned int) UAddr.b[1], (unsigned int) UAddr.b[2], (unsigned int) UAddr.b[3]);
- return (pszIP);
- }
- int SysInetAddr(char const *pszDotName, NET_ADDRESS & NetAddr)
- {
- if ((NetAddr = (NET_ADDRESS) inet_addr(pszDotName)) == SYS_INVALID_NET_ADDRESS) {
- ErrSetErrorCode(ERR_BAD_SERVER_ADDR, pszDotName);
- return (ERR_BAD_SERVER_ADDR);
- }
- return (0);
- }
- int SysSameAddress(NET_ADDRESS const &NetAddr1, NET_ADDRESS const &NetAddr2)
- {
- return (memcmp(&NetAddr1, &NetAddr2, sizeof(NET_ADDRESS)) == 0);
- }
- SYS_SEMAPHORE SysCreateSemaphore(int iInitCount, int iMaxCount)
- {
- HANDLE hSemaphore = CreateSemaphore(NULL, iInitCount, iMaxCount, NULL);
- if (hSemaphore == NULL) {
- ErrSetErrorCode(ERR_CREATESEMAPHORE);
- return (SYS_INVALID_SEMAPHORE);
- }
- return ((SYS_SEMAPHORE) hSemaphore);
- }
- int SysCloseSemaphore(SYS_SEMAPHORE hSemaphore)
- {
- if (!CloseHandle((HANDLE) hSemaphore)) {
- ErrSetErrorCode(ERR_CLOSEHANDLE);
- return (ERR_CLOSEHANDLE);
- }
- return (0);
- }
- int SysWaitSemaphore(SYS_SEMAPHORE hSemaphore, int iTimeout)
- {
- if (WaitForSingleObject((HANDLE) hSemaphore, (DWORD) (iTimeout * 1000)) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- int SysReleaseSemaphore(SYS_SEMAPHORE hSemaphore, int iCount)
- {
- if (!ReleaseSemaphore((HANDLE) hSemaphore, (LONG) iCount, NULL)) {
- ErrSetErrorCode(ERR_RELEASESEMAPHORE);
- return (ERR_RELEASESEMAPHORE);
- }
- return (0);
- }
- int SysTryWaitSemaphore(SYS_SEMAPHORE hSemaphore)
- {
- if (WaitForSingleObject((HANDLE) hSemaphore, 0) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- SYS_MUTEX SysCreateMutex(void)
- {
- HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
- if (hMutex == NULL) {
- ErrSetErrorCode(ERR_CREATEMUTEX);
- return (SYS_INVALID_MUTEX);
- }
- return ((SYS_MUTEX) hMutex);
- }
- int SysCloseMutex(SYS_MUTEX hMutex)
- {
- if (!CloseHandle((HANDLE) hMutex)) {
- ErrSetErrorCode(ERR_CLOSEHANDLE);
- return (ERR_CLOSEHANDLE);
- }
- return (0);
- }
- int SysLockMutex(SYS_MUTEX hMutex, int iTimeout)
- {
- if (WaitForSingleObject((HANDLE) hMutex, (DWORD) (iTimeout * 1000)) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- int SysUnlockMutex(SYS_MUTEX hMutex)
- {
- ReleaseMutex((HANDLE) hMutex);
- return (0);
- }
- int SysTryLockMutex(SYS_MUTEX hMutex)
- {
- if (WaitForSingleObject((HANDLE) hMutex, 0) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- SYS_EVENT SysCreateEvent(int iManualReset)
- {
- HANDLE hEvent = CreateEvent(NULL, iManualReset, FALSE, NULL);
- if (hEvent == NULL) {
- ErrSetErrorCode(ERR_CREATEEVENT);
- return (SYS_INVALID_EVENT);
- }
- return ((SYS_EVENT) hEvent);
- }
- int SysCloseEvent(SYS_EVENT hEvent)
- {
- if (!CloseHandle((HANDLE) hEvent)) {
- ErrSetErrorCode(ERR_CLOSEHANDLE);
- return (ERR_CLOSEHANDLE);
- }
- return (0);
- }
- int SysWaitEvent(SYS_EVENT hEvent, int iTimeout)
- {
- if (WaitForSingleObject((HANDLE) hEvent, (DWORD) (iTimeout * 1000)) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- int SysSetEvent(SYS_EVENT hEvent)
- {
- SetEvent((HANDLE) hEvent);
- return (0);
- }
- int SysResetEvent(SYS_EVENT hEvent)
- {
- ResetEvent((HANDLE) hEvent);
- return (0);
- }
- int SysTryWaitEvent(SYS_EVENT hEvent)
- {
- if (WaitForSingleObject((HANDLE) hEvent, 0) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- static unsigned int SysThreadRunner(void *pRunData)
- {
- ThreadRunner *pTR = (ThreadRunner *) pRunData;
- if (SysThreadSetup() < 0) {
- SysFree(pTR);
- return (ErrGetErrorCode());
- }
- unsigned int uResultCode = SysStkCall(pTR->pThreadProc, pTR->pThreadData);
- SysThreadCleanup();
- SysFree(pTR);
- return (uResultCode);
- }
- SYS_THREAD SysCreateThread(unsigned int (*pThreadProc) (void *), void *pThreadData)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Alloc thread runner data
- ///////////////////////////////////////////////////////////////////////////////
- ThreadRunner *pTR = (ThreadRunner *) SysAlloc(sizeof(ThreadRunner));
- if (pTR == NULL)
- return (SYS_INVALID_THREAD);
- pTR->pThreadProc = pThreadProc;
- pTR->pThreadData = pThreadData;
- ///////////////////////////////////////////////////////////////////////////////
- // Create the thread
- ///////////////////////////////////////////////////////////////////////////////
- unsigned int uThreadId = 0;
- unsigned long ulThread = _beginthreadex(NULL, 0,
- (unsigned (__stdcall *) (void *)) SysThreadRunner,
- pTR, 0, &uThreadId);
- if (ulThread == 0) {
- SysFree(pTR);
- ErrSetErrorCode(ERR_BEGINTHREADEX);
- return (SYS_INVALID_THREAD);
- }
- return ((SYS_THREAD) ulThread);
- }
- SYS_THREAD SysCreateServiceThread(unsigned int (*pThreadProc) (void *), SYS_SOCKET SockFD)
- {
- SYS_THREAD ThreadID = SysCreateThread(pThreadProc, (void *) (unsigned int) SockFD);
- return (ThreadID);
- }
- static int SysThreadSetup(void)
- {
- SysInitTlsKeys();
- return (0);
- }
- static int SysThreadCleanup(void)
- {
- SysCleanupTlsKeys();
- return (0);
- }
- void SysCloseThread(SYS_THREAD ThreadID, int iForce)
- {
- if (iForce)
- TerminateThread((HANDLE) ThreadID, (DWORD) - 1);
- CloseHandle((HANDLE) ThreadID);
- }
- int SysSetThreadPriority(SYS_THREAD ThreadID, int iPriority)
- {
- BOOL bSetResult = FALSE;
- switch (iPriority) {
- case (SYS_PRIORITY_NORMAL):
- bSetResult = SetThreadPriority((HANDLE) ThreadID, THREAD_PRIORITY_NORMAL);
- break;
- case (SYS_PRIORITY_LOWER):
- bSetResult = SetThreadPriority((HANDLE) ThreadID, THREAD_PRIORITY_BELOW_NORMAL);
- break;
- case (SYS_PRIORITY_HIGHER):
- bSetResult = SetThreadPriority((HANDLE) ThreadID, THREAD_PRIORITY_ABOVE_NORMAL);
- break;
- }
- if (!bSetResult) {
- ErrSetErrorCode(ERR_SET_THREAD_PRIORITY);
- return (ERR_SET_THREAD_PRIORITY);
- }
- return (0);
- }
- int SysWaitThread(SYS_THREAD ThreadID, int iTimeout)
- {
- if (WaitForSingleObject((HANDLE) ThreadID, (DWORD) (iTimeout * 1000)) != WAIT_OBJECT_0) {
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- return (0);
- }
- unsigned long SysGetCurrentThreadId(void)
- {
- return ((unsigned long) GetCurrentThreadId());
- }
- int SysExec(char const *pszCommand, char const *const *pszArgs, int iWaitTimeout,
- int iPriority, int *piExitStatus)
- {
- int ii;
- int iCommandLength = strlen(pszCommand) + 4;
- for (ii = 1; pszArgs[ii] != NULL; ii++)
- iCommandLength += strlen(pszArgs[ii]) + 4;
- char *pszCmdLine = (char *) SysAlloc(iCommandLength + 1);
- if (pszCmdLine == NULL)
- return (ErrGetErrorCode());
- strcpy(pszCmdLine, pszCommand);
- for (ii = 1; pszArgs[ii] != NULL; ii++)
- sprintf(StrAppend(pszCmdLine), " "%s"", pszArgs[ii]);
- PROCESS_INFORMATION PI;
- STARTUPINFO SI;
- ZeroData(PI);
- ZeroData(SI);
- SI.cb = sizeof(STARTUPINFO);
- BOOL bProcessCreated = CreateProcess(NULL, pszCmdLine, NULL, NULL, FALSE,
- CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL, NULL,
- &SI, &PI);
- SysFree(pszCmdLine);
- if (!bProcessCreated) {
- ErrSetErrorCode(ERR_PROCESS_EXECUTE);
- return (ERR_PROCESS_EXECUTE);
- }
- SysSetThreadPriority((SYS_THREAD) PI.hThread, iPriority);
- if (iWaitTimeout > 0) {
- if (WaitForSingleObject(PI.hProcess, iWaitTimeout * 1000) != WAIT_OBJECT_0) {
- CloseHandle(PI.hThread);
- CloseHandle(PI.hProcess);
- ErrSetErrorCode(ERR_TIMEOUT);
- return (ERR_TIMEOUT);
- }
- if (piExitStatus != NULL) {
- DWORD dwExitCode = 0;
- if (!GetExitCodeProcess(PI.hProcess, &dwExitCode))
- *piExitStatus = -1;
- else
- *piExitStatus = (int) dwExitCode;
- }
- } else if (piExitStatus != NULL)
- *piExitStatus = -1;
- CloseHandle(PI.hThread);
- CloseHandle(PI.hProcess);
- return (0);
- }
- static BOOL WINAPI SysBreakHandlerRoutine(DWORD dwCtrlType)
- {
- BOOL bReturnValue = FALSE;
- switch (dwCtrlType) {
- case (CTRL_C_EVENT):
- case (CTRL_CLOSE_EVENT):
- case (CTRL_SHUTDOWN_EVENT):
- if (SysBreakHandler != NULL)
- SysBreakHandler(), bReturnValue = TRUE;
- break;
- }
- return (bReturnValue);
- }
- void SysSetBreakHandler(void (*BreakHandler) (void))
- {
- if (SysBreakHandler == NULL)
- SetConsoleCtrlHandler(SysBreakHandlerRoutine,
- (BreakHandler != NULL) ? TRUE : FALSE);
- SysBreakHandler = BreakHandler;
- }
- int SysCreateTlsKey(SYS_TLSKEY & TlsKey, void (*pFreeProc) (void *))
- {
- EnterCriticalSection(&csTLS);
- for (int ii = 0; ii < MAX_TLS_KEYS; ii++) {
- if (TlsKeyEntries[ii].pFreeProc == UNUSED_TLS_KEY_PROC) {
- TlsKeyEntries[ii].pFreeProc = pFreeProc;
- LeaveCriticalSection(&csTLS);
- TlsKey = (SYS_TLSKEY) ii;
- return (0);
- }
- }
- LeaveCriticalSection(&csTLS);
- ErrSetErrorCode(ERR_NOMORE_TLSKEYS);
- return (ERR_NOMORE_TLSKEYS);
- }
- int SysDeleteTlsKey(SYS_TLSKEY & TlsKey)
- {
- int iKey = (int) TlsKey;
- EnterCriticalSection(&csTLS);
- if ((iKey < 0) || (iKey >= MAX_TLS_KEYS) ||
- (TlsKeyEntries[iKey].pFreeProc == UNUSED_TLS_KEY_PROC)) {
- LeaveCriticalSection(&csTLS);
- ErrSetErrorCode(ERR_INVALID_TLSKEY);
- return (ERR_INVALID_TLSKEY);
- }
- TlsKeyEntries[iKey].pFreeProc = UNUSED_TLS_KEY_PROC;
- LeaveCriticalSection(&csTLS);
- TlsKey = (SYS_TLSKEY) - 1;
- return (0);
- }
- int SysSetTlsKeyData(SYS_TLSKEY & TlsKey, void *pData)
- {
- int iKey = (int) TlsKey;
- if ((iKey < 0) || (iKey >= MAX_TLS_KEYS) ||
- (TlsKeyEntries[iKey].pFreeProc == UNUSED_TLS_KEY_PROC)) {
- ErrSetErrorCode(ERR_INVALID_TLSKEY);
- return (ERR_INVALID_TLSKEY);
- }
- TlsKeys[iKey].pData = pData;
- return (0);
- }
- void *SysGetTlsKeyData(SYS_TLSKEY & TlsKey)
- {
- int iKey = (int) TlsKey;
- if ((iKey < 0) || (iKey >= MAX_TLS_KEYS) ||
- (TlsKeyEntries[iKey].pFreeProc == UNUSED_TLS_KEY_PROC)) {
- ErrSetErrorCode(ERR_INVALID_TLSKEY);
- return (NULL);
- }
- return (TlsKeys[iKey].pData);
- }
- void SysThreadOnce(SYS_THREAD_ONCE * pThrOnce, void (*pOnceProc) (void))
- {
- if (InterlockedExchange(&pThrOnce->lOnce, 1) == 0) {
- pOnceProc();
- pThrOnce->lDone++;
- }
- while (!pThrOnce->lDone)
- Sleep(0);
- }
- void *SysAlloc(unsigned int uSize)
- {
- void *pData = malloc(uSize);
- if (pData != NULL)
- memset(pData, 0, uSize);
- else
- ErrSetErrorCode(ERR_MEMORY);
- return (pData);
- }
- void SysFree(void *pData)
- {
- free(pData);
- }
- void *SysRealloc(void *pData, unsigned int uSize)
- {
- void *pNewData = realloc(pData, uSize);
- if (pNewData == NULL)
- ErrSetErrorCode(ERR_MEMORY);
- return (pNewData);
- }
- int SysLockFile(const char *pszFileName, char const *pszLockExt)
- {
- char szLockFile[SYS_MAX_PATH] = "";
- SysSNPrintf(szLockFile, sizeof(szLockFile) - 1, "%s%s", pszFileName, pszLockExt);
- ///////////////////////////////////////////////////////////////////////////////
- // Try to create lock file
- ///////////////////////////////////////////////////////////////////////////////
- HANDLE hFile = CreateFile(szLockFile, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- if (GetLastError() == ERROR_ALREADY_EXISTS) {
- ErrSetErrorCode(ERR_LOCKED);
- return (ERR_LOCKED);
- }
- ErrSetErrorCode(ERR_FILE_CREATE);
- return (ERR_FILE_CREATE);
- }
- DWORD dwWritten = 0;
- char szLock[128] = "";
- sprintf(szLock, "%lu", (unsigned long) GetCurrentThreadId());
- if (!WriteFile(hFile, szLock, strlen(szLock) + 1, &dwWritten, NULL)) {
- CloseHandle(hFile);
- ErrSetErrorCode(ERR_FILE_WRITE);
- return (ERR_FILE_WRITE);
- }
- CloseHandle(hFile);
- return (0);
- }
- int SysUnlockFile(const char *pszFileName, char const *pszLockExt)
- {
- char szLockFile[SYS_MAX_PATH] = "";
- SysSNPrintf(szLockFile, sizeof(szLockFile) - 1, "%s%s", pszFileName, pszLockExt);
- if (_unlink(szLockFile) != 0) {
- ErrSetErrorCode(ERR_NOT_LOCKED);
- return (ERR_NOT_LOCKED);
- }
- return (0);
- }
- SYS_HANDLE SysOpenModule(char const *pszFilePath)
- {
- HMODULE hModule = LoadLibrary(pszFilePath);
- if (hModule == NULL) {
- ErrSetErrorCode(ERR_LOADMODULE, pszFilePath);
- return (SYS_INVALID_HANDLE);
- }
- return ((SYS_HANDLE) hModule);
- }
- int SysCloseModule(SYS_HANDLE hModule)
- {
- FreeLibrary((HMODULE) hModule);
- return (0);
- }
- void *SysGetSymbol(SYS_HANDLE hModule, char const *pszSymbol)
- {
- void *pSymbol = (void *) GetProcAddress((HMODULE) hModule, pszSymbol);
- if (pSymbol == NULL) {
- ErrSetErrorCode(ERR_LOADMODULESYMBOL, pszSymbol);
- return (NULL);
- }
- return (pSymbol);
- }
- int SysEventLogV(int iLogLevel, char const *pszFormat, va_list Args)
- {
- HANDLE hEventSource = RegisterEventSource(NULL, szServerName);
- if (hEventSource == NULL) {
- ErrSetErrorCode(ERR_REGISTER_EVENT_SOURCE);
- return (ERR_REGISTER_EVENT_SOURCE);
- }
- char *pszStrings[2];
- char szBuffer[2048] = "";
- _vsnprintf(szBuffer, sizeof(szBuffer) - 1, pszFormat, Args);
- pszStrings[0] = szBuffer;
- ReportEvent(hEventSource,
- iLogLevel == LOG_LEV_ERROR ? EVENTLOG_ERROR_TYPE:
- iLogLevel == LOG_LEV_WARNING ? EVENTLOG_WARNING_TYPE:
- EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **) pszStrings, NULL);
- DeregisterEventSource(hEventSource);
- return (0);
- }
- int SysEventLog(int iLogLevel, char const *pszFormat, ...)
- {
- va_list Args;
- va_start(Args, pszFormat);
- int iLogResult = SysEventLogV(iLogLevel, pszFormat, Args);
- va_end(Args);
- return (0);
- }
- int SysLogMessage(int iLogLevel, char const *pszFormat, ...)
- {
- extern bool bServerDebug;
- EnterCriticalSection(&csLog);
- va_list Args;
- va_start(Args, pszFormat);
- if (bServerDebug) {
- ///////////////////////////////////////////////////////////////////////////////
- // Debug implementation
- ///////////////////////////////////////////////////////////////////////////////
- vprintf(pszFormat, Args);
- } else {
- switch (iLogLevel) {
- case (LOG_LEV_WARNING):
- case (LOG_LEV_ERROR):
- SysEventLogV(iLogLevel, pszFormat, Args);
- break;
- }
- }
- va_end(Args);
- LeaveCriticalSection(&csLog);
- return (0);
- }
- void SysSleep(int iTimeout)
- {
- SysMsSleep(iTimeout * 1000);
- }
- void SysMsSleep(int iMsTimeout)
- {
- Sleep(iMsTimeout);
- }
- static void SysTimetToFileTime(time_t tTime, LPFILETIME pFT)
- {
- LONGLONG llTime = Int32x32To64(tTime, 10000000) + 116444736000000000;
- pFT->dwLowDateTime = (DWORD) llTime;
- pFT->dwHighDateTime = (DWORD) (llTime >> 32);
- }
- static time_t SysFileTimeToTimet(LPFILETIME pFT)
- {
- LONGLONG llTime = ((LONGLONG) pFT->dwLowDateTime) |
- (((LONGLONG) pFT->dwHighDateTime) << 32);
- return ((time_t) ((llTime - 116444736000000000) / 10000000));
- }
- SYS_INT64 SysMsTime(void)
- {
- LARGE_INTEGER PerfCntCurr;
- QueryPerformanceCounter(&PerfCntCurr);
- SYS_INT64 MsTicks = *(SYS_INT64 *) & PerfCntCurr;
- MsTicks -= PCSysStart;
- MsTicks /= PCFreq;
- MsTicks += (SYS_INT64) tSysStart *1000;
- return (MsTicks);
- }
- int SysExistFile(const char *pszFilePath)
- {
- DWORD dwAttr = GetFileAttributes(pszFilePath);
- if (dwAttr == (DWORD) - 1)
- return (0);
- return ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) ? 0 : 1);
- }
- int SysExistDir(const char *pszDirPath)
- {
- DWORD dwAttr = GetFileAttributes(pszDirPath);
- if (dwAttr == (DWORD) - 1)
- return (0);
- return ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0);
- }
- SYS_HANDLE SysFirstFile(const char *pszPath, char *pszFileName)
- {
- char szMatch[SYS_MAX_PATH] = "";
- strcpy(szMatch, pszPath);
- AppendSlash(szMatch);
- strcat(szMatch, "*");
- WIN32_FIND_DATA WFD;
- HANDLE hFind = FindFirstFile(szMatch, &WFD);
- if (hFind == INVALID_HANDLE_VALUE)
- return (SYS_INVALID_HANDLE);
- FileFindData *pFFD = (FileFindData *) SysAlloc(sizeof(FileFindData));
- if (pFFD == NULL) {
- FindClose(hFind);
- return (SYS_INVALID_HANDLE);
- }
- strcpy(pFFD->szFindPath, pszPath);
- AppendSlash(pFFD->szFindPath);
- pFFD->hFind = hFind;
- pFFD->WFD = WFD;
- strcpy(pszFileName, pFFD->WFD.cFileName);
- return ((SYS_HANDLE) pFFD);
- }
- int SysIsDirectory(SYS_HANDLE hFind)
- {
- FileFindData *pFFD = (FileFindData *) hFind;
- return ((pFFD->WFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0);
- }
- unsigned long SysGetSize(SYS_HANDLE hFind)
- {
- FileFindData *pFFD = (FileFindData *) hFind;
- return ((unsigned long) pFFD->WFD.nFileSizeLow);
- }
- int SysNextFile(SYS_HANDLE hFind, char *pszFileName)
- {
- FileFindData *pFFD = (FileFindData *) hFind;
- if (!FindNextFile(pFFD->hFind, &pFFD->WFD))
- return (0);
- strcpy(pszFileName, pFFD->WFD.cFileName);
- return (1);
- }
- void SysFindClose(SYS_HANDLE hFind)
- {
- FileFindData *pFFD = (FileFindData *) hFind;
- FindClose(pFFD->hFind);
- SysFree(pFFD);
- }
- int SysGetFileInfo(char const *pszFileName, SYS_FILE_INFO & FI)
- {
- WIN32_FIND_DATA WFD;
- HANDLE hFind = FindFirstFile(pszFileName, &WFD);
- if (hFind == INVALID_HANDLE_VALUE) {
- ErrSetErrorCode(ERR_STAT);
- return (ERR_STAT);
- }
- ZeroData(FI);
- FI.iFileType = (WFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? ftDirectory : ftNormal;
- FI.ulSize = (unsigned long) WFD.nFileSizeLow;
- FI.tMod = SysFileTimeToTimet(&WFD.ftLastWriteTime);
- FindClose(hFind);
- return (0);
- }
- int SysSetFileModTime(char const *pszFileName, time_t tMod)
- {
- HANDLE hFile = CreateFile(pszFileName, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- ErrSetErrorCode(ERR_SET_FILE_TIME);
- return (ERR_SET_FILE_TIME);
- }
- FILETIME MFT;
- SysTimetToFileTime(tMod, &MFT);
- if (!SetFileTime(hFile, NULL, &MFT, &MFT)) {
- CloseHandle(hFile);
- ErrSetErrorCode(ERR_SET_FILE_TIME);
- return (ERR_SET_FILE_TIME);
- }
- CloseHandle(hFile);
- return (0);
- }
- char *SysStrDup(const char *pszString)
- {
- int iStrLength = strlen(pszString);
- char *pszBuffer = (char *) SysAlloc(iStrLength + 1);
- if (pszBuffer != NULL)
- strcpy(pszBuffer, pszString);
- return (pszBuffer);
- }
- char *SysGetEnv(const char *pszVarName)
- {
- char szRKeyPath[256] = "";
- SysSNPrintf(szRKeyPath, sizeof(szRKeyPath) - 1, "SOFTWARE\%s\%s",
- APP_PRODUCER, szServerName);
- HKEY hKey;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRKeyPath, 0, KEY_QUERY_VALUE,
- &hKey) == ERROR_SUCCESS) {
- char szKeyValue[2048] = "";
- DWORD dwSize = sizeof(szKeyValue);
- DWORD dwKeyType;
- if (RegQueryValueEx(hKey, pszVarName, NULL, &dwKeyType, (u_char *) szKeyValue,
- &dwSize) == ERROR_SUCCESS) {
- RegCloseKey(hKey);
- return (SysStrDup(szKeyValue));
- }
- RegCloseKey(hKey);
- }
- const char *pszValue = getenv(pszVarName);
- return ((pszValue != NULL) ? SysStrDup(pszValue) : NULL);
- }
- char *SysGetTmpFile(char *pszFileName)
- {
- char szTmpPath[SYS_MAX_PATH] = "";
- GetTempPath(sizeof(szTmpPath) - 1, szTmpPath);
- static unsigned int uFileSeqNr = 0;
- SYS_LONGLONG llFileID =
- (((SYS_LONGLONG) GetCurrentThreadId()) << 32) | (SYS_LONGLONG)++ uFileSeqNr;
- SysSNPrintf(pszFileName, SYS_MAX_PATH - 1, "%smsrv%I64x.tmp", szTmpPath, llFileID);
- return (pszFileName);
- }
- int SysRemove(const char *pszFileName)
- {
- if (!DeleteFile(pszFileName)) {
- ErrSetErrorCode(ERR_FILE_DELETE);
- return (ERR_FILE_DELETE);
- }
- return (0);
- }
- int SysMakeDir(const char *pszPath)
- {
- if (!CreateDirectory(pszPath, NULL)) {
- ErrSetErrorCode(ERR_DIR_CREATE);
- return (ERR_DIR_CREATE);
- }
- return (0);
- }
- int SysRemoveDir(const char *pszPath)
- {
- if (!RemoveDirectory(pszPath)) {
- ErrSetErrorCode(ERR_DIR_DELETE);
- return (ERR_DIR_DELETE);
- }
- return (0);
- }
- int SysMoveFile(char const *pszOldName, char const *pszNewName)
- {
- if (!MoveFileEx(pszOldName, pszNewName,
- MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
- ErrSetErrorCode(ERR_FILE_MOVE);
- return (ERR_FILE_MOVE);
- }
- return (0);
- }
- int SysVSNPrintf(char *pszBuffer, int iSize, char const *pszFormat, va_list Args)
- {
- return (_vsnprintf(pszBuffer, iSize, pszFormat, Args));
- }
- int SysFileSync(FILE * pFile)
- {
- if (fflush(pFile) || _commit(_fileno(pFile))) {
- ErrSetErrorCode(ERR_FILE_WRITE);
- return (ERR_FILE_WRITE);
- }
- return (0);
- }
- char *SysStrTok(char *pszData, char const *pszDelim, char **ppszSavePtr)
- {
- return (*ppszSavePtr = strtok(pszData, pszDelim));
- }
- char *SysCTime(time_t * pTimer, char *pszBuffer)
- {
- return (strcpy(pszBuffer, ctime(pTimer)));
- }
- struct tm *SysLocalTime(time_t * pTimer, struct tm *pTStruct)
- {
- *pTStruct = *localtime(pTimer);
- return (pTStruct);
- }
- struct tm *SysGMTime(time_t * pTimer, struct tm *pTStruct)
- {
- *pTStruct = *gmtime(pTimer);
- return (pTStruct);
- }
- char *SysAscTime(struct tm *pTStruct, char *pszBuffer, int iBufferSize)
- {
- strncpy(pszBuffer, asctime(pTStruct), iBufferSize);
- pszBuffer[iBufferSize - 1] = ' ';
- return (pszBuffer);
- }
- long SysGetTimeZone(void)
- {
- return ((long) _timezone);
- }
- long SysGetDayLight(void)
- {
- time_t tCurr = time(NULL);
- struct tm tmCurr = *localtime(&tCurr);
- return ((long) ((tmCurr.tm_isdst <= 0) ? 0 : 3600));
- }
- int SysGetDiskSpace(char const *pszPath, SYS_INT64 * pTotal, SYS_INT64 * pFree)
- {
- ULARGE_INTEGER BytesAvail;
- ULARGE_INTEGER BytesOnDisk;
- ULARGE_INTEGER BytesFree;
- char szXPath[SYS_MAX_PATH] = "";
- StrSNCpy(szXPath, pszPath);
- AppendSlash(szXPath);
- if (!GetDiskFreeSpaceEx(szXPath, &BytesAvail, &BytesOnDisk, &BytesFree)) {
- ErrSetErrorCode(ERR_GET_DISK_SPACE_INFO);
- return (ERR_GET_DISK_SPACE_INFO);
- }
- *pTotal = *(SYS_INT64 *) & BytesOnDisk;
- *pFree = *(SYS_INT64 *) & BytesAvail;
- return (0);
- }
- int SysMemoryInfo(SYS_INT64 * pRamTotal, SYS_INT64 * pRamFree,
- SYS_INT64 * pVirtTotal, SYS_INT64 * pVirtFree)
- {
- #if _WIN32_WINNT >= 0x0500
- MEMORYSTATUSEX MSEX;
- ZeroData(MSEX);
- if (!GlobalMemoryStatusEx(&MSEX)) {
- ErrSetErrorCode(ERR_GET_MEMORY_INFO);
- return (ERR_GET_MEMORY_INFO);
- }
- *pRamTotal = (SYS_INT64) MSEX.ullTotalPhys;
- *pRamFree = (SYS_INT64) MSEX.ullAvailPhys;
- *pVirtTotal = (SYS_INT64) MSEX.ullTotalVirtual;
- *pVirtFree = (SYS_INT64) MSEX.ullAvailVirtual;
- #else // #if defined(_WIN32_WINNT 0x0500)
- MEMORYSTATUS MS;
- ZeroData(MS);
- GlobalMemoryStatus(&MS);
- *pRamTotal = (SYS_INT64) MS.dwTotalPhys;
- *pRamFree = (SYS_INT64) MS.dwAvailPhys;
- *pVirtTotal = (SYS_INT64) MS.dwTotalVirtual;
- *pVirtFree = (SYS_INT64) MS.dwAvailVirtual;
- #endif // #if defined(_WIN32_WINNT 0x0500)
- return (0);
- }
- static unsigned int SysStkCall(unsigned int (*pProc) (void *), void *pData)
- {
- srand(GetCurrentThreadId() * (unsigned int) time(NULL) * uSRandBase);
- unsigned int uResult;
- unsigned int uStkDisp =
- (unsigned int) (rand() % MAX_STACK_SHIFT) & ~(STACK_ALIGN_BYTES - 1);
- #if !defined(USE_ASM_STK_DISP)
- void *pStkSpace = _alloca(uStkDisp);
- uResult = pProc(pData);
- #else
- __asm {
- sub esp, uStkDisp;
- }
- uResult = pProc(pData);
- __asm {
- add esp, uStkDisp;
- }
- #endif
- return (uResult);
- }