//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.
#include "Glob.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\\theme\\", "/theme/",
"htdocs\\", "/",
0, 0
};
void ConnectionOpen(HANDLE hNewConnection, DWORD dwRemoteIP);
int PreShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/);
HNETLIBUSER hNetlibUser;
HANDLE hDirectBoundPort;
HINSTANCE hInstance = NULL;
CLIST_INTERFACE *pcli;
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 HGENMENU 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;
bool bShutdownInProgress = false;
int hLangpack = 0;
extern HWND hwndStatsticView;
PLUGININFOEX pluginInfo = {
sizeof(PLUGININFOEX),
__PLUGIN_NAME,
PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
__DESCRIPTION,
__AUTHOR,
__AUTHOREMAIL,
__COPYRIGHT,
__AUTHORWEB,
UNICODE_AWARE,
// {67848B07-83D2-49E9-8844-7E3DE268E304}
{0x67848b07, 0x83d2, 0x49e9, {0x88, 0x44, 0x7e, 0x3d, 0xe2, 0x68, 0xe3, 0x4}}
};
/////////////////////////////////////////////////////////////////////
// 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 = (int)mir_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, Translate("Failed to open or create log file"), MSG_BOX_TITEL, MB_OK);
return;
}
if (SetFilePointer(hFile, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER) {
MessageBox(NULL, Translate("Failed to move to the end of the log file"), MSG_BOX_TITEL, MB_OK);
CloseHandle(hFile);
return;
}
char szTmp[128];
time_t now;
time(&now);
int nLen = (int)strftime(szTmp, sizeof(szTmp), "%d-%m-%Y %H:%M:%S -- ", localtime(&now));
int nLogLen = (int)mir_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, Translate("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];
mir_strcpy(szBuf, szPluginPath);
mir_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 = DWORD(sizeof(szBuf) - (pszCurPos - szBuf));
memmove(szBuf, pszCurPos, dwBytesInBuffer * sizeof(wchar_t));
}
// 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[0] = 0;// NULL terminate row data, we overwrite the '<'
pszCurPos = strstr(pszCurPos + 3, ">");
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], temp[200];
mir_strcpy(szBuf, szPluginPath);
mir_strcat(szBuf, szConfigFile);
HANDLE hFile = CreateFile(szBuf, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
mir_snprintf(temp, "%s%s", Translate("Failed to open or create file "), szConfigFile);
MessageBox(NULL, temp, MSG_BOX_TITEL, MB_OK);
return false;
}
DWORD dwBytesWriten = 0;
if (!WriteFile(hFile, szXmlHeader, sizeof(szXmlHeader) - 1, &dwBytesWriten, NULL)) {
mir_snprintf(temp, "%s%s", TranslateT("Failed to write xml header to file "), szConfigFile);
MessageBox(NULL, temp, MSG_BOX_TITEL, MB_OK);
}
else {
CLFileShareNode *pclCur = pclFirstNode;
while (pclCur) {
DWORD dwBytesToWrite = mir_snprintf(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)) {
mir_snprintf(temp, "%s%s", Translate("Failed to write xml data to file "), szConfigFile);
MessageBox(NULL, temp, MSG_BOX_TITEL, MB_OK);
break;
}
pclCur = pclCur->pclNext;
}
if (!WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWriten, NULL)) {
mir_snprintf(temp, "%s%s", Translate("Failed to write xml tail to file "), szConfigFile);
MessageBox(NULL, temp, 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 INT_PTR 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[mir_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 INT_PTR nGetShare(WPARAM /*wParam*/, LPARAM lParam)
{
if (!lParam)
return 1001;
CLFileShareListAccess clCritSection;
STFileShareInfo * pclShare = (STFileShareInfo*)lParam;
CLFileShareNode * pclCur = pclFirstNode;
while (pclCur) {
if (mir_strcmp(pclCur->st.pszSrvPath, pclShare->pszSrvPath) == 0) {
if (pclShare->dwMaxRealPath <= mir_strlen(pclCur->st.pszRealPath) + 1)
return 1003;
mir_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 INT_PTR 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(HNETLIBCONN hNewConnection, DWORD dwRemoteIP)
{
in_addr stAddr;
stAddr.S_un.S_addr = htonl(dwRemoteIP);
CLHttpUser *pclUser = new CLHttpUser(hNewConnection, stAddr);
mir_forkthread(HandleNewConnection, 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)
{
//todo: ignore weather protos
ACKDATA *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);
return 0;
}
/////////////////////////////////////////////////////////////////////
// Member Function : nToggelAcceptConnections
// Type : Global
// Parameters : WPARAM - ?
// LPARAM - ?
// Returns : int
// Description :
//
// References : -
// Remarks : -
// Created : 031011, 11 oktober 2003
// Developer : KN
/////////////////////////////////////////////////////////////////////
INT_PTR nToggelAcceptConnections(WPARAM wparam, LPARAM /*lparam*/)
{
if (!hDirectBoundPort) {
NETLIBUSERSETTINGS nus = {};
nus.cbSize = sizeof(nus);
Netlib_GetUserSettings(hNetlibUser, &nus);
NETLIBBIND nlb = {};
nlb.pfnNewConnection = ConnectionOpen;
if (nus.specifyIncomingPorts && nus.szIncomingPorts && nus.szIncomingPorts[0])
nlb.wPort = 0;
else
nlb.wPort = 80;
hDirectBoundPort = Netlib_BindPort(hNetlibUser, &nlb);
if (!hDirectBoundPort) {
char szTemp[200];
mir_snprintf(szTemp, Translate("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;
Menu_ModifyItem(hAcceptConnectionsMenuItem, LPGENW("Disable HTTP server"), LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DISABLE_SERVER)));
}
else if (hDirectBoundPort && wparam == 0) {
Netlib_CloseHandle(hDirectBoundPort);
hDirectBoundPort = 0;
Menu_ModifyItem(hAcceptConnectionsMenuItem, LPGENW("Enable HTTP server"), LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)));
}
else return 0; // no changes;
if (!bShutdownInProgress)
db_set_b(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*/)
{
if (!bReadConfigurationFile()) {
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);
mir_strcpy(share.pszRealPath, p[0]);
share.pszSrvPath = szSrvPath;
share.dwMaxSrvPath = sizeof(szSrvPath);
mir_strcpy(share.pszSrvPath, p[1]);
if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&share))
break;
p += 2;
}
bWriteConfigurationFile();
}
NETLIBUSER nlu = {};
nlu.flags = NUF_OUTGOING | NUF_INCOMING;
nlu.szSettingsModule = MODULE;
nlu.szDescriptiveName = Translate("HTTP Server");
hNetlibUser = Netlib_RegisterUser(& nlu);
if (!hNetlibUser) {
MessageBox(NULL, "Failed to register NetLib user", MSG_BOX_TITEL, MB_OK);
return 0;
}
if (db_get_b(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*/)
{
while (pclFirstNode) {
CLFileShareNode * pclCur = pclFirstNode;
pclFirstNode = pclFirstNode->pclNext;
delete pclCur;
}
pclFirstNode = NULL;
UnInitGuiElements();
db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode);
FreeIndexHTMLTemplate();
return 0;
}
/////////////////////////////////////////////////////////////////////
// Member Function : MirandaPluginInfoEx
// Type : Global
// Parameters : mirandaVersion - ?
// Returns :
// Description :
//
// References : -
// Remarks : -
// Created : 020422, 22 April 2002
// Developer : KN, Houdini
/////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/)
{
return &pluginInfo;
}
/////////////////////////////////////////////////////////////////////
// Member Function : Load
// Type : Global
// Parameters : link - ?
// Returns : int
// Description :
//
// References : -
// Remarks : -
// Created : 020422, 22 April 2002
// Developer : KN
/////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) int Load()
{
mir_getLP(&pluginInfo);
pcli = Clist_GetInterface();
hHttpAcceptConnectionsService = CreateServiceFunction(MS_HTTP_ACCEPT_CONNECTIONS, nToggelAcceptConnections);
if (!hHttpAcceptConnectionsService) {
MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_ACCEPT_CONNECTIONS", MSG_BOX_TITEL, MB_OK);
return 1;
}
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 1;
}
hHttpGetShareService = CreateServiceFunction(MS_HTTP_GET_SHARE, nGetShare);
if (!hHttpGetShareService) {
MessageBox(NULL, "Failed to CreateServiceFunction MS_HTTP_GET_SHARE", MSG_BOX_TITEL, MB_OK);
return 1;
}
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 1;
}
hEventSystemInit = HookEvent(ME_SYSTEM_MODULESLOADED, MainInit);
if (!hEventSystemInit) {
MessageBox(NULL, "Failed to HookEvent ME_SYSTEM_MODULESLOADED", MSG_BOX_TITEL, MB_OK);
return 1;
}
hPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
if (!hPreShutdown) {
MessageBox(NULL, "Failed to HookEvent ME_SYSTEM_PRESHUTDOWN", MSG_BOX_TITEL, MB_OK);
return 1;
}
if (Profile_GetPathA(MAX_PATH, szPluginPath)) {
MessageBox(NULL, "Failed to retrieve plugin path.", MSG_BOX_TITEL, MB_OK);
return 1;
}
mir_strncat(szPluginPath, "\\HTTPServer\\", _countof(szPluginPath) - mir_strlen(szPluginPath));
int err = CreateDirectoryTree(szPluginPath);
if ((err != 0) && (err != ERROR_ALREADY_EXISTS)) {
MessageBox(NULL, "Failed to create HTTPServer directory.", MSG_BOX_TITEL, MB_OK);
return 1;
}
nPluginPathLen = (int)mir_strlen(szPluginPath);
sLogFilePath = szPluginPath;
sLogFilePath += "HTTPServer.log";
if (!bInitMimeHandling())
MessageBox(NULL, "Failed to read configuration file : " szMimeTypeConfigFile, MSG_BOX_TITEL, MB_OK);
nMaxUploadSpeed = db_get_dw(NULL, MODULE, "MaxUploadSpeed", nMaxUploadSpeed);
nMaxConnectionsTotal = db_get_dw(NULL, MODULE, "MaxConnectionsTotal", nMaxConnectionsTotal);
nMaxConnectionsPerUser = db_get_dw(NULL, MODULE, "MaxConnectionsPerUser", nMaxConnectionsPerUser);
bLimitOnlyWhenOnline = db_get_b(NULL, MODULE, "LimitOnlyWhenOnline", bLimitOnlyWhenOnline) != 0;
indexCreationMode = (eIndexCreationMode)db_get_b(NULL, MODULE, "IndexCreationMode", 2);
if (db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1)) {
CMenuItem mi;
SET_UID(mi, 0xf0a68784, 0xc30e, 0x4245, 0xb6, 0x2b, 0xb8, 0x71, 0x7e, 0xe6, 0xe1, 0x73);
mi.flags = CMIF_UNICODE;
mi.hIcolibItem = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE));
mi.position = 1000085000;
mi.name.a = LPGEN("Enable HTTP server");
mi.pszService = MS_HTTP_ACCEPT_CONNECTIONS;
hAcceptConnectionsMenuItem = Menu_AddMainMenuItem(&mi);
}
if (indexCreationMode == INDEX_CREATION_HTML || indexCreationMode == INDEX_CREATION_DETECT)
if (!LoadIndexHTMLTemplate()) {
indexCreationMode = INDEX_CREATION_DISABLE;
db_set_b(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
/////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) int Unload()
{
nSystemShutdown(0, 0);
if (hwndStatsticView)
DestroyWindow(hwndStatsticView);
return 0;
}