From 5b74bda58f47e7894a83643b86d24f0c78e60285 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Thu, 24 Nov 2011 16:55:09 +0000 Subject: added HTTPServer git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@206 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- HTTPServer/main.cpp | 1101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1101 insertions(+) create mode 100644 HTTPServer/main.cpp (limited to 'HTTPServer/main.cpp') diff --git a/HTTPServer/main.cpp b/HTTPServer/main.cpp new file mode 100644 index 0000000..0ff96f6 --- /dev/null +++ b/HTTPServer/main.cpp @@ -0,0 +1,1101 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifdef NDEBUG //release +#include "AggressiveOptimize.h" //create small code +#endif + +#include +#include +#include +#include +#include + +#pragma warning( push, 3 ) + +#include +using namespace std; + +#include "newpluginapi.h" +#include "m_database.h" +#include "m_clist.h" +#include "m_skin.h" +#include "m_langpack.h" +#include "m_options.h" +#include "m_system.h" +#include "m_history.h" +#include "m_userinfo.h" +#include "m_netlib.h" +#include "m_message.h" +#include "m_popup.h" +#include "m_protosvc.h" + +#pragma warning( pop ) + +//#include +//#include +#include "m_HTTPServer.h" +#include "FileShareNode.h" +#include "HttpUser.h" +#include "GuiElements.h" +#include "MimeHandling.h" +#include "Glob.h" +#include "resource.h" +#include "IndexCreation.h" + +#define szConfigFile "HTTPServer.xml" + +const char szXmlHeader[] = "\r\n" + "\r\n" + "\r\n"; + +const char szXmlData[] = "\t\r\n" + "\t\t%s\r\n" + "\t\t%s\r\n" + "\t\t%d\r\n" + "\t\t%d.%d.%d.%d\r\n" + "\t\t%d.%d.%d.%d\r\n" + "\t\r\n"; + +const char szXmlTail[] = ""; + +const char* pszDefaultShares[] = { + "htdocs\\@settings\\favicon.ico", "/favicon.ico", + "htdocs\\@settings\\index.xsl", "/index.xsl", + "htdocs\\@settings\\placeholder.gif", "/placeholder.gif", + "htdocs\\@settings\\icons\\", "/icons/", + "htdocs\\", "/", + 0, 0 +}; + +void ConnectionOpen(HANDLE hNewConnection, DWORD dwRemoteIP); +int PreShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/); + +HANDLE hNetlibUser; +HANDLE hDirectBoundPort; + +HINSTANCE hInstance = NULL; +PLUGINLINK *pluginLink; + +string sLogFilePath; + +// static so they can not be used from other modules ( sourcefiles ) +static HANDLE hEventSystemInit = 0; +static HANDLE hPreShutdown = 0; + +static HANDLE hHttpAcceptConnectionsService = 0; +static HANDLE hHttpAddChangeRemoveService = 0; +static HANDLE hHttpGetShareService = 0; +static HANDLE hHttpGetAllShares = 0; + +static HANDLE hAcceptConnectionsMenuItem = 0; + +char szPluginPath[MAX_PATH] = {0}; +int nPluginPathLen = 0; + +DWORD dwLocalIpAddress = 0; +DWORD dwLocalPortUsed = 0; +DWORD dwExternalIpAddress = 0; + +int nMaxUploadSpeed = -1; +int nMaxConnectionsTotal = -1; +int nMaxConnectionsPerUser = -1; +int nDefaultDownloadLimit = -1; + +bool bIsOnline = true; +static HANDLE hEventProtoAck = 0; + +bool bLimitOnlyWhenOnline = true; + +void* (*MirandaMalloc)(size_t); +void (*MirandaFree)(void*); + + +bool bShutdownInProgress = false; + + +struct NETLIBUSERSETTINGS_V032 { + int cbSize; //to be filled in before calling + int useProxy; //1 or 0 + int proxyType; //a PROXYTYPE_ + char* szProxyServer; //can be NULL + int wProxyPort; //host byte order + int useProxyAuth; //1 or 0. Always 0 for SOCKS4 + char* szProxyAuthUser; //can be NULL, always used by SOCKS4 + char* szProxyAuthPassword; //can be NULL + int useProxyAuthNtlm; //1 or 0, only used by HTTP, HTTPS + int dnsThroughProxy; //1 or 0 + int specifyIncomingPorts; //1 or 0 + char* szIncomingPorts; //can be NULL. Of form "1024-1050,1060-1070,2000" +} ; + + +char* pszVersion = "0.1.2.2"; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + MODULE, + PLUGIN_MAKE_VERSION(0, 1, 2, 2), + "HTTP Server\r\n" + "HTTP Web Server plugin for Miranda", + "Kennet Nielsen, modified by Vampik, Houdini", + "", + "© 2003-2009 Kennet Nielsen, Vampik, Houdini", + "http://www.miranda-im.org/download/details.php?action=viewfile&id=2304", + 0, + 0, + // {67848B07-83D2-49e9-8844-7E3DE268E304} + { 0x67848b07, 0x83d2, 0x49e9, { 0x88, 0x44, 0x7e, 0x3d, 0xe2, 0x68, 0xe3, 0x4 } } +}; + + +struct FORK_ARG { + HANDLE hEvent; + void (__cdecl *threadcode)(void*); + unsigned(__stdcall *threadcodeex)(void*); + void *arg; +}; + +void __cdecl forkthread_r(void * fa2) { + struct FORK_ARG * fa = (struct FORK_ARG *)fa2; + void (*callercode)(void*) = fa->threadcode; + void *arg = fa->arg; + CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + SetEvent(fa->hEvent); + __try { + callercode(arg); + } __finally { + CallService(MS_SYSTEM_THREAD_POP, 0, 0); + } + return; +} + +unsigned long forkthread( + void (__cdecl *threadcode)(void*), + unsigned long stacksize, + void *arg +) { + unsigned long rc; + struct FORK_ARG fa; + fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + fa.threadcode = threadcode; + fa.arg = arg; + rc = _beginthread(forkthread_r, stacksize, &fa); + if ((unsigned long) - 1L != rc) { + WaitForSingleObject(fa.hEvent, INFINITE); + } //if + CloseHandle(fa.hEvent); + return rc; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bOpenLogFile +// Type : Global +// Parameters : None +// Returns : Returns alway true +// Description : Open the log file in default program assoaitated +// with .log files +// References : - +// Remarks : - +// Created : 031020, 20 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bOpenLogFile() { + SHELLEXECUTEINFO st = {0}; + st.cbSize = sizeof(st); + st.fMask = SEE_MASK_INVOKEIDLIST; + st.hwnd = NULL; + st.lpFile = sLogFilePath.c_str(); + st.nShow = SW_SHOWDEFAULT; + ShellExecuteEx(&st); + return true; +} + + +bool bWriteToFile(HANDLE hFile, const char * pszSrc, int nLen = -1) { + if (nLen < 0) + nLen = strlen(pszSrc); + DWORD dwBytesWritten; + return WriteFile(hFile, pszSrc, nLen, &dwBytesWritten, NULL) && (dwBytesWritten == (DWORD)nLen); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : LogEvent +// Type : Global +// Parameters : title - ? +// logme - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030928, 28 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void LogEvent(const char * pszTitle, const char * pszLog) { + HANDLE hFile = CreateFile(sLogFilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(NULL, "Failed to open or create log file", MSG_BOX_TITEL, MB_OK); + return; + } + if (SetFilePointer(hFile, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER) { + CloseHandle(hFile); + MessageBox(NULL, "Failed to move to the end of the log file", MSG_BOX_TITEL, MB_OK); + return; + } + + char szTmp[128]; + time_t now; + time(&now); + int nLen = strftime(szTmp, sizeof(szTmp), "%d-%m-%Y %H:%M:%S -- ", localtime(&now)); + + int nLogLen = strlen(pszLog); + while (nLogLen > 0 && (pszLog[nLogLen-1] == '\r' || pszLog[nLogLen-1] == '\n')) + nLogLen--; + + if (!bWriteToFile(hFile, szTmp, nLen) || + !bWriteToFile(hFile, pszTitle) || + !bWriteToFile(hFile, " : ") || + !bWriteToFile(hFile, pszLog, nLogLen) || + !bWriteToFile(hFile, "\r\n")) { + MessageBox(NULL, "Failed to write some part of the log file", MSG_BOX_TITEL, MB_OK); + } + CloseHandle(hFile); +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : dwReadIPAddress +// Type : Global +// Parameters : pszStr - ? +// Returns : DWORD +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +DWORD dwReadIPAddress(char * pszStr, bool &bError) { + DWORD ip = 0; + char *pszEnd; + for (int n = 0 ; n < 4 ; n++) { + int nVal = strtol(pszStr, &pszEnd, 10); + if (pszEnd <= pszStr || (n != 3 && pszEnd[0] != '.') || (nVal < 0 || nVal > 255)) { + bError = true; + return 0; + } + pszStr = pszEnd + 1; + ip |= nVal << ((3 - n) * 8); + } + return ip; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bReadConfigurationFile +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030823, 23 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bReadConfigurationFile() { + CLFileShareListAccess clCritSection; + + CLFileShareNode * pclLastNode = NULL; + + char szBuf[1000]; + strcpy(szBuf, szPluginPath); + strcat(szBuf, szConfigFile); + HANDLE hFile = CreateFile(szBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return false; + + char *pszCurPos = szBuf; + + bool bEof = false; + while (!bEof) { + DWORD dwBytesInBuffer = 0; + + // move rest of buffer to front + if (pszCurPos && pszCurPos != szBuf) { + dwBytesInBuffer = sizeof(szBuf) - (pszCurPos - szBuf); + memmove(szBuf, pszCurPos, dwBytesInBuffer); + } + + // append data to buffer + DWORD dwBytesRead = 0; + bEof = !ReadFile(hFile, &szBuf[dwBytesInBuffer], sizeof(szBuf) - dwBytesInBuffer, + &dwBytesRead, NULL) || dwBytesRead <= 0; + pszCurPos = szBuf; + + if (pszCurPos) { + while (pszCurPos && (pszCurPos = strstr(pszCurPos, "")) != NULL) { + pszCurPos += 7; + + char * pszColData[5] = {NULL}; + for (int n = 0 ; n < 5 ; n++) { + pszColData[n] = strstr(pszCurPos, ">"); + if (!pszColData[n]) + break; + pszColData[n] += 1; + + pszCurPos = strstr(pszColData[n], ""); + + if (!pszCurPos) + break; + pszCurPos += 1; + } + if (!pszColData[4]) + continue; + + CLFileShareNode * pcl = new CLFileShareNode(pszColData[0], pszColData[1]); + + bool bError = false; + char * pszEnd; + + pcl->st.nMaxDownloads = strtol(pszColData[2], &pszEnd, NULL); + if (!pszEnd || *pszEnd != NULL) + bError = true; + + pcl->st.dwAllowedIP = dwReadIPAddress(pszColData[3], bError); + pcl->st.dwAllowedMask = dwReadIPAddress(pszColData[4], bError); + if (bError) { + delete pcl; + continue; + } + + if (! pclLastNode) { + pclLastNode = pclFirstNode = pcl; + } else { + pclLastNode->pclNext = pcl; + pclLastNode = pcl; + } + + // refill buffer + if (!bEof && pszCurPos - szBuf > sizeof(szBuf) / 2) + break; + } + } + } + CloseHandle(hFile); + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteConfigurationFile +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteConfigurationFile() { + CLFileShareListAccess clCritSection; + char szBuf[1000]; + strcpy(szBuf, szPluginPath); + strcat(szBuf, szConfigFile); + HANDLE hFile = CreateFile(szBuf, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(NULL, "Failed to open or create file " szConfigFile, MSG_BOX_TITEL, MB_OK); + return false; + } + + DWORD dwBytesWriten = 0; + if (! WriteFile(hFile, szXmlHeader, sizeof(szXmlHeader) - 1, &dwBytesWriten, NULL)) { + MessageBox(NULL, "Failed to write xml header to file " szConfigFile, MSG_BOX_TITEL, MB_OK); + } else { + CLFileShareNode * pclCur = pclFirstNode; + while (pclCur) { + DWORD dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szXmlData , + pclCur->st.pszSrvPath, + pclCur->pszOrigRealPath, + pclCur->st.nMaxDownloads, + SplitIpAddress(pclCur->st.dwAllowedIP), + SplitIpAddress(pclCur->st.dwAllowedMask)); + + if (! WriteFile(hFile, szBuf, dwBytesToWrite, &dwBytesWriten, NULL)) { + MessageBox(NULL, "Failed to write xml data to file " szConfigFile, MSG_BOX_TITEL, MB_OK); + break; + } + pclCur = pclCur->pclNext; + } + + if (! WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWriten, NULL)) { + MessageBox(NULL, "Failed to write xml tail to file " szConfigFile, MSG_BOX_TITEL, MB_OK); + } + } + SetEndOfFile(hFile); + CloseHandle(hFile); + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nAddChangeRemoveShare +// Type : Global +// Parameters : wParam - Contact handle +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN, Houdini, changed By Sergio Vieira Rolanski +///////////////////////////////////////////////////////////////////// + +static long nAddChangeRemoveShare(WPARAM wParam, LPARAM lParam) { + if (!lParam) + return 1001; + + STFileShareInfo * pclNew = (STFileShareInfo*)lParam; + + // make the server path lowercase + char* pszPos = pclNew->pszSrvPath; + while (*pszPos) { + *pszPos = (char)tolower(*pszPos); + pszPos++; + } + + if (pclNew->lStructSize != sizeof(STFileShareInfo)) + return 1002; + + CLFileShareListAccess clCritSection; + bool bIsDirectory = (pclNew->pszSrvPath[strlen(pclNew->pszSrvPath)-1] == '/'); + + CLFileShareNode **pclPrev = &pclFirstNode; + CLFileShareNode * pclCur = pclFirstNode; + + // insert files after directories + if (!bIsDirectory) { + while (pclCur && pclCur->bIsDirectory()) { + pclPrev = &pclCur->pclNext; + pclCur = pclCur->pclNext; + } + } + + while (pclCur) { + if (_stricmp(pclCur->st.pszSrvPath, pclNew->pszSrvPath) == 0) { + if (pclCur->bAnyUsers()) { + // Some downloads are in progress we will try an terminate them !! + // we try for 5 sec. + pclCur->CloseAllTransfers(); + int nTryCount = 0; + do { + nTryCount++; + if (nTryCount >= 100) + return 1004; + clCritSection.Unlock(); + Sleep(50); + clCritSection.Lock(); + } while (pclCur->bAnyUsers()); + } + + if (!pclNew->pszRealPath || pclNew->pszRealPath[0] == 0) { + // remove this one + *pclPrev = pclCur->pclNext; + delete pclCur; + } else { + // update info !! + if (! pclCur->bSetInfo(pclNew)) + return 1003; + } + return !bWriteConfigurationFile(); + } + pclPrev = &pclCur->pclNext; + pclCur = pclCur->pclNext; + } + + // Node was not found we will add a new one. + CLFileShareNode* pclNewNode = new CLFileShareNode(pclNew); + pclNewNode->pclNext = *pclPrev; + *pclPrev = pclNewNode; + + /* Add by Sérgio Vieira Rolanski */ + if (pclNew->dwOptions & OPT_SEND_LINK) + SendLinkToUser(wParam, pclNew->pszSrvPath); + + return !bWriteConfigurationFile(); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nGetShare +// Type : Global +// Parameters : WPARAM - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static long nGetShare(WPARAM /*wParam*/, LPARAM lParam) { + if (!lParam) + return 1001; + + CLFileShareListAccess clCritSection; + + STFileShareInfo * pclShare = (STFileShareInfo*)lParam; + CLFileShareNode * pclCur = pclFirstNode; + while (pclCur) { + if (strcmp(pclCur->st.pszSrvPath, pclShare->pszSrvPath) == 0) { + if (pclShare->dwMaxRealPath <= strlen(pclCur->st.pszRealPath) + 1) + return 1003; + strcpy(pclShare->pszRealPath, pclCur->st.pszRealPath); + pclShare->dwAllowedIP = pclCur->st.dwAllowedIP; + pclShare->dwAllowedMask = pclCur->st.dwAllowedMask; + pclShare->nMaxDownloads = pclCur->st.nMaxDownloads; + pclShare->dwOptions = pclCur->st.dwOptions; + return 0; + } + pclCur = pclCur->pclNext; + } + return 1002; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nAddChangeRemoveShare +// Type : Global +// Parameters : WPARAM - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 030903, 03 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static long nHttpGetAllShares(WPARAM /*wParam*/, LPARAM /*lParam*/) {/* + STFileShareInfo ** pTarget = (STFileShareInfo**)lParam; + CLFileShareNode * pclCur; + + CLFileShareListAccess clCritSection; + + int nShareCount = 0; + for( pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) + nShareCount++; + + int nCount = 0; + *pTarget = (STFileShareInfo*)MirandaMalloc( sizeof( STFileShareInfo) * nShareCount ); + for( pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) + { + // this code is not good !!! + // we need to alloc and copy psz strings also !! + memcpy( &((*pTarget)[nCount]), pclCur, sizeof( STFileShareInfo)); + nCount++; + } + */ + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : HandleNewConnection +// Type : Global +// Parameters : ch - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030903, 03 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void HandleNewConnection(void *ch) { + CLHttpUser * pclUser = (CLHttpUser *)ch; + pclUser->HandleNewConnection(); + delete pclUser; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ConnectionOpen +// Type : Global +// Parameters : hNewConnection - ? +// dwRemoteIP - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030813, 13 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ConnectionOpen(HANDLE hNewConnection, DWORD dwRemoteIP) { + in_addr stAddr; + stAddr.S_un.S_addr = htonl(dwRemoteIP); + + CLHttpUser * pclUser = new CLHttpUser(hNewConnection, stAddr); + forkthread(HandleNewConnection, 0, (void*)pclUser); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nProtoAck +// Type : Global +// Parameters : wParam - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 031213, 13 december 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static int nProtoAck(WPARAM /*wParam*/, LPARAM lParam) { + ACKDATA *ack; + //todo: ignore weather protos + ack = (ACKDATA *)lParam; + if (ack->type != ACKTYPE_STATUS || //only send for statuses + ack->result != ACKRESULT_SUCCESS) //only successful ones + return 0; + + bIsOnline = ((int)ack->lParam != ID_STATUS_AWAY && (int)ack->lParam != ID_STATUS_NA); + /* + char szTmp[200]; + _snprintf( szTmp, sizeof( szTmp ), "%s New status %d\n" ,ack->szModule, (int)bIsOnline); + OutputDebugString( szTmp );*/ + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nToggelAcceptConnections +// Type : Global +// Parameters : WPARAM - ? +// LPARAM - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +long nToggelAcceptConnections(WPARAM wparam, LPARAM /*lparam*/) { + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_NAME | CMIM_ICON; + + if (!hDirectBoundPort) { + NETLIBUSERSETTINGS nus = { 0 }; + nus.cbSize = sizeof(nus); + if (! CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM) hNetlibUser, (LPARAM) &nus)) { + nus.cbSize = sizeof(NETLIBUSERSETTINGS_V032); + if (! CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM) hNetlibUser, (LPARAM) &nus)) { + Netlib_Logf(hNetlibUser, "Failed to get NETLIBUSERSETTINGS using MS_NETLIB_GETUSERSETTINGS"); + } + } + + NETLIBBIND nlb = { 0 }; + nlb.cbSize = sizeof(NETLIBBIND); + nlb.pfnNewConnection = ConnectionOpen; + if (nus.specifyIncomingPorts && nus.szIncomingPorts && nus.szIncomingPorts[0]) + nlb.wPort = 0; + else { + //MessageBox( NULL, "Debug message using default port!", MSG_BOX_TITEL, MB_OK ); + nlb.wPort = 80; + } + hDirectBoundPort = (HANDLE) CallService(MS_NETLIB_BINDPORT, (WPARAM) hNetlibUser, (LPARAM) & nlb); + if (!hDirectBoundPort) { + char szTemp[200]; + _snprintf(szTemp, sizeof(szTemp), "Failed to bind to port %s\r\nThis is most likely because another program or service is using this port" , + nlb.wPort == 80 ? "80" : nus.szIncomingPorts); + MessageBox(NULL, szTemp, MSG_BOX_TITEL, MB_OK); + return 1001; + } + dwLocalPortUsed = nlb.wPort; + dwLocalIpAddress = nlb.dwInternalIP; + + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DISABLE_SERVER)); + mi.pszName = Translate("Disable HTTP server"); + Netlib_Logf(hNetlibUser, mi.pszName); + } else if (hDirectBoundPort && wparam == 0) { + Netlib_CloseHandle(hDirectBoundPort); + hDirectBoundPort = 0; + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.pszName = Translate("Enable HTTP server"); + Netlib_Logf(hNetlibUser, mi.pszName); + } else { + return 0; // no changes; + } + + if (hAcceptConnectionsMenuItem) + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hAcceptConnectionsMenuItem, (LPARAM)&mi); + + if (! bShutdownInProgress) + DBWriteContactSettingByte(NULL, MODULE, "AcceptConnections", hDirectBoundPort != 0); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DllMain +// Type : Global +// Parameters : hinst - ? +// fdwReason - ? +// lpvReserved - ? +// Returns : BOOL WINAPI +// Description : +// +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/) { + hInstance = hinst; + return 1; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : MainInit +// Type : Global +// Parameters : wparam - ? +// lparam - ? +// Returns : int +// Description : Called when system modules has been loaded +// +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int MainInit(WPARAM /*wparam*/, LPARAM /*lparam*/) { + /* + STFileShareInfo * pShares = (STFileShareInfo *)5; + CallService(MS_HTTP_GET_ALL_SHARES, 0, (LPARAM) &pShares); + MirandaFree( pShares );*/ + + if (! bReadConfigurationFile()) { + //MessageBox( NULL, "Failed to read configuration file : " szConfigFile, MSG_BOX_TITEL, MB_OK ); + + char szRealPath[MAX_PATH]; + char szSrvPath[MAX_PATH] = {0}; + STFileShareInfo share; + + const char** p = pszDefaultShares; + while (*p) { + memset(&share, 0, sizeof(share)); + share.lStructSize = sizeof(share); + share.dwAllowedIP = 0; + share.dwAllowedMask = 0; + share.nMaxDownloads = -1; + + share.pszRealPath = szRealPath; + share.dwMaxRealPath = sizeof(szRealPath); + strcpy(share.pszRealPath, p[0]); + + share.pszSrvPath = szSrvPath; + share.dwMaxSrvPath = sizeof(szSrvPath); + strcpy(share.pszSrvPath, p[1]); + + if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&share)) + break; + + p += 2; + } + + bWriteConfigurationFile(); + } + + + NETLIBUSER nlu = { 0 }; + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_INCOMING /*| NUF_HTTPCONNS*/; + nlu.szSettingsModule = MODULE; + nlu.szDescriptiveName = "HTTP Server"; + hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu); + if (!hNetlibUser) { + MessageBox(NULL, "Failed to register NetLib user", MSG_BOX_TITEL, MB_OK); + return 0; + } + + if (DBGetContactSettingByte(NULL, MODULE, "AcceptConnections", 1)) + nToggelAcceptConnections(0, 0); + + InitGuiElements(); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : PreShutdown +// Type : Global +// Parameters : WPARAM - ? +// LPARAM - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030811, 11 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int PreShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/) { + { + CLFileShareListAccess clCrit; + bShutdownInProgress = true; + + for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) { + pclCur->CloseAllTransfers(); + } + } + + if (hDirectBoundPort) + nToggelAcceptConnections(0, 0); + + Netlib_CloseHandle(hNetlibUser); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nSystemShutdown +// Type : Global +// Parameters : wparam - 0 +// lparam - 0 +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 020428, 28 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nSystemShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/) { + if (hEventProtoAck) + UnhookEvent(hEventProtoAck); + + while (pclFirstNode) { + CLFileShareNode * pclCur = pclFirstNode; + pclFirstNode = pclFirstNode->pclNext; + delete pclCur; + } + pclFirstNode = NULL; + + if (hEventSystemInit) { + UnhookEvent(hEventSystemInit); + hEventSystemInit = 0; + } + UnInitGuiElements(); + + DBWriteContactSettingByte(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode); + FreeIndexHTMLTemplate(); + + return 0; +} + + +#ifdef __cplusplus +extern "C" { +#endif + + ///////////////////////////////////////////////////////////////////// + // Member Function : MirandaPluginInfoEx & MirandaPluginInterfaces + // Type : Global + // Parameters : mirandaVersion - ? + // Returns : + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN, Houdini + ///////////////////////////////////////////////////////////////////// + + __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/) { + return &pluginInfo; + } + + // {CE5023BA-3A22-44b1-AB23-69081B2D9BC9} + //#define MIID_HTTPSERVER { 0xce5023ba, 0x3a22, 0x44b1, { 0xab, 0x23, 0x69, 0x8, 0x1b, 0x2d, 0x9b, 0xc9 } } + + static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST}; + __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { + return interfaces; + } + + ///////////////////////////////////////////////////////////////////// + // Member Function : Load + // Type : Global + // Parameters : link - ? + // Returns : int + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN + ///////////////////////////////////////////////////////////////////// + + int __declspec(dllexport)Load(PLUGINLINK *link) { + pluginLink = link; + /* + MM_INTERFACE stMirandaMMI; + CallService( MS_SYSTEM_GET_MMI, NULL, (LPARAM) &stMirandaMMI ); + MirandaMalloc = stMirandaMMI.malloc; + MirandaFree = stMirandaMMI.free; + */ + InitializeCriticalSection(&csFileShareListAccess); + + hHttpAcceptConnectionsService = CreateServiceFunction(MS_HTTP_ACCEPT_CONNECTIONS, nToggelAcceptConnections); + if (! hHttpAcceptConnectionsService) { + MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_ACCEPT_CONNECTIONS", MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpAddChangeRemoveService = CreateServiceFunction(MS_HTTP_ADD_CHANGE_REMOVE, nAddChangeRemoveShare); + if (! hHttpAddChangeRemoveService) { + MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_ADD_CHANGE_REMOVE", MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpGetShareService = CreateServiceFunction(MS_HTTP_GET_SHARE, nGetShare); + if (! hHttpGetShareService) { + MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_GET_SHARE", MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpGetAllShares = CreateServiceFunction(MS_HTTP_GET_ALL_SHARES, nHttpGetAllShares); + if (! hHttpGetAllShares) { + MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_GET_ALL_SHARES", MSG_BOX_TITEL, MB_OK); + return 0; + } + + + hEventSystemInit = HookEvent(ME_SYSTEM_MODULESLOADED, MainInit); + if (!hEventSystemInit) { + MessageBox(NULL, "Failed to HookEvent ME_SYSTEM_MODULESLOADED", MSG_BOX_TITEL, MB_OK); + return 0; + } + + hPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + if (!hPreShutdown) { + MessageBox(NULL, "Failed to HookEvent ME_SYSTEM_PRESHUTDOWN", MSG_BOX_TITEL, MB_OK); + return 0; + } + + szPluginPath[0] = 0; + if (GetModuleFileName(hInstance, szPluginPath, sizeof(szPluginPath))) { + char *str2 = strrchr(szPluginPath, '\\'); + if (str2 != NULL) { + str2[1] = NULL; + } + } + nPluginPathLen = strlen(szPluginPath); + + sLogFilePath = szPluginPath; + sLogFilePath += "HTTPServer.log"; + + if (! bInitMimeHandling()) { + MessageBox(NULL, "Failed to read configuration file : " szMimeTypeConfigFile, MSG_BOX_TITEL, MB_OK); + } + + // Plugin sweeper support + DBWriteContactSettingString(NULL, "Uninstall", "HTTPServer", MODULE); + + nMaxUploadSpeed = DBGetContactSettingDword(NULL, MODULE, "MaxUploadSpeed", nMaxUploadSpeed); + nMaxConnectionsTotal = DBGetContactSettingDword(NULL, MODULE, "MaxConnectionsTotal", nMaxConnectionsTotal); + nMaxConnectionsPerUser = DBGetContactSettingDword(NULL, MODULE, "MaxConnectionsPerUser", nMaxConnectionsPerUser); + bLimitOnlyWhenOnline = DBGetContactSettingByte(NULL, MODULE, "LimitOnlyWhenOnline", bLimitOnlyWhenOnline) != 0; + indexCreationMode = + (eIndexCreationMode)DBGetContactSettingByte(NULL, MODULE, "IndexCreationMode", 2); + + if (DBGetContactSettingByte(NULL, MODULE, "AddAcceptConMenuItem", 1)) { + CLISTMENUITEM mi; + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = 0; + mi.pszContactOwner = NULL; //all contacts + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.position = 1000085000; + mi.pszName = Translate("Enable HTTP server"); + mi.pszService = MS_HTTP_ACCEPT_CONNECTIONS; + hAcceptConnectionsMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi); + } + + if (indexCreationMode == INDEX_CREATION_HTML || + indexCreationMode == INDEX_CREATION_DETECT) + if (!LoadIndexHTMLTemplate()) { + indexCreationMode = INDEX_CREATION_DISABLE; + DBWriteContactSettingByte(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode); + } + + hEventProtoAck = HookEvent(ME_PROTO_ACK, nProtoAck); + return 0; + } + + ///////////////////////////////////////////////////////////////////// + // Member Function : Unload + // Type : Global + // Parameters : none + // Returns : + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN + ///////////////////////////////////////////////////////////////////// + + __declspec(dllexport)int Unload(void) { + nSystemShutdown(0, 0); + return 0; + } + +#ifdef __cplusplus +} +#endif -- cgit v1.2.3