summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/HTTPServer/HTTPServer_11.vcxproj215
-rw-r--r--plugins/HTTPServer/HTTPServer_11.vcxproj.filters67
-rw-r--r--plugins/HTTPServer/docs/Changelog.txt206
-rw-r--r--plugins/HTTPServer/docs/data/Changelog.txt206
-rw-r--r--plugins/HTTPServer/docs/data/HTTPMimeTypes478
-rw-r--r--plugins/HTTPServer/docs/data/HTTPServer.dllbin0 -> 55296 bytes
-rw-r--r--plugins/HTTPServer/docs/data/HTTPServer.pdfbin0 -> 117677 bytes
-rw-r--r--plugins/HTTPServer/docs/data/HTTPServer.xsl35
-rw-r--r--plugins/HTTPServer/docs/data/HTTPServerIndex.html34
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/favicon.icobin0 -> 1406 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.pngbin0 -> 702 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.pngbin0 -> 357 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.pngbin0 -> 3172 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.pngbin0 -> 912 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.pngbin0 -> 747 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.pngbin0 -> 771 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.pngbin0 -> 633 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.pngbin0 -> 863 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.pngbin0 -> 558 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.pngbin0 -> 784 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.pngbin0 -> 944 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.pngbin0 -> 734 bytes
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl121
-rw-r--r--plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gifbin0 -> 72 bytes
-rw-r--r--plugins/HTTPServer/res/dis_srv.icobin0 -> 1406 bytes
-rw-r--r--plugins/HTTPServer/res/resource.rc207
-rw-r--r--plugins/HTTPServer/res/share_ne.icobin0 -> 1406 bytes
-rw-r--r--plugins/HTTPServer/src/FileShareNode.cpp375
-rw-r--r--plugins/HTTPServer/src/FileShareNode.h103
-rw-r--r--plugins/HTTPServer/src/Glob.h94
-rw-r--r--plugins/HTTPServer/src/GuiElements.cpp1553
-rw-r--r--plugins/HTTPServer/src/GuiElements.h29
-rw-r--r--plugins/HTTPServer/src/HttpUser.cpp888
-rw-r--r--plugins/HTTPServer/src/HttpUser.h70
-rw-r--r--plugins/HTTPServer/src/IndexCreation.h42
-rw-r--r--plugins/HTTPServer/src/IndexHTML.cpp527
-rw-r--r--plugins/HTTPServer/src/IndexXML.cpp255
-rw-r--r--plugins/HTTPServer/src/MimeHandling.cpp147
-rw-r--r--plugins/HTTPServer/src/MimeHandling.h52
-rw-r--r--plugins/HTTPServer/src/m_HTTPServer.h105
-rw-r--r--plugins/HTTPServer/src/main.cpp974
-rw-r--r--plugins/HTTPServer/src/resource.h56
42 files changed, 6839 insertions, 0 deletions
diff --git a/plugins/HTTPServer/HTTPServer_11.vcxproj b/plugins/HTTPServer/HTTPServer_11.vcxproj
new file mode 100644
index 0000000000..0d5ecf7dc2
--- /dev/null
+++ b/plugins/HTTPServer/HTTPServer_11.vcxproj
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F7A70398-AFA0-4A58-B645-85268F9517DE}</ProjectGuid>
+ <ProjectName>HTTPServer</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>Glob.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin11\lib</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x22500000</BaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <AdditionalDependencies>comctl32.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>Glob.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin11\lib</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x22500000</BaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <AdditionalDependencies>comctl32.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>Glob.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/PDBALTPATH:%_PDB% %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin11\lib</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <BaseAddress>0x22500000</BaseAddress>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>Glob.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/PDBALTPATH:%_PDB% %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin11\lib</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <BaseAddress>0x22500000</BaseAddress>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="src\FileShareNode.h" />
+ <ClInclude Include="src\Glob.h" />
+ <ClInclude Include="src\GuiElements.h" />
+ <ClInclude Include="src\HttpUser.h" />
+ <ClInclude Include="src\IndexCreation.h" />
+ <ClInclude Include="src\MimeHandling.h" />
+ <ClInclude Include="src\resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\FileShareNode.cpp" />
+ <ClCompile Include="src\GuiElements.cpp" />
+ <ClCompile Include="src\HttpUser.cpp" />
+ <ClCompile Include="src\IndexHTML.cpp" />
+ <ClCompile Include="src\IndexXML.cpp" />
+ <ClCompile Include="src\main.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\MimeHandling.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/HTTPServer/HTTPServer_11.vcxproj.filters b/plugins/HTTPServer/HTTPServer_11.vcxproj.filters
new file mode 100644
index 0000000000..adc7a96302
--- /dev/null
+++ b/plugins/HTTPServer/HTTPServer_11.vcxproj.filters
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{8a708544-2fc2-467e-8bf3-77362b20ae40}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{2b0034fb-2dba-462b-b88b-8800f2ed581e}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{dd12eb67-8352-411d-a553-86edc311c3e6}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\FileShareNode.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\Glob.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\GuiElements.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\HttpUser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\IndexCreation.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\MimeHandling.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\FileShareNode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\GuiElements.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\HttpUser.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\IndexHTML.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\IndexXML.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\MimeHandling.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/HTTPServer/docs/Changelog.txt b/plugins/HTTPServer/docs/Changelog.txt
new file mode 100644
index 0000000000..de682e0249
--- /dev/null
+++ b/plugins/HTTPServer/docs/Changelog.txt
@@ -0,0 +1,206 @@
+
+
+Version 0.0.1.0
+
+This is a beta version.
+Some features are not yet implemented.
+A shared file will only be remove when the maximum downloads has been reached.
+Suggestions and contributions are welcome.
+
+
+Version 0.0.2.0
+
+[+] You can change the default port used in Miranda options network "incoming connections"
+[+] Popup the message dialog with link when new file is shared.
+[!] Crash sometimes when share was about to be removed.
+[*] xsl file changed so that it shows link to file.
+
+
+Version 0.0.3.0
+
+[+] Uses popup plugin if installed to show when the HTTP server is accessed.
+[!] File path was not stored correctly, which meant that only files in the plugin folder could be shared.
+
+
+Version 0.0.4.0
+
+[!] Server did not use any port if you did not set a "incoming connections" port in the options.
+[+] More error dialog boxes if there is something that failes when initilizing. e.i. unable to bind port
+
+
+Version 0.0.4.1
+
+[+] If the open file dialog in "HTTP Share new file" fails an error message is displayed
+[!] Shutdown while file transfer is in progress is now handled correctly
+
+
+Version 0.0.4.2
+
+[!] "HTTP Share new file" only worked on Windows XP.
+
+
+Version 0.0.5.0
+
+[+] HTTP Server can now be accessed by multiply users simultaniously.
+[+] HTTP Server "statistics view" includes shares and current useres accessing the server.
+[+] Share can be removed from "statistics view"
+
+
+Version 0.0.6.0
+
+[!] Max downloads was not decreased so a share was never removed.
+[!] First share could not be removed then max downloads got to zero.
+[!] If a share was deleted while a download was in progress the download would not be stopped
+[*] Outgoing connections options has been removed.
+[+] Basic MIME support. Based on file extension.
+
+
+Version 0.0.7.0
+
+[+] In the "statistics view" you can copy a link to your shares.
+[+] Correct handling of UTF-8 encoded URIs in GET requests.fixes spaces and none US-ASCII characters.
+[!] Only masks 255.255.255.255 and 0.0.0.0 worked correctly any other was interpreted like 255.255.255.255.
+
+
+Version 0.0.8.0
+
+[+] Popup when a share is removed
+[!] Fixed bug in UTF-8 handling. Basically %?? part of handling did not work
+[!] Some spelling errors corrected.
+[*] Homepage link in options updated
+[*] Some internal Elements.
+
+
+Version 0.0.9.0
+
+[+] Downloads can be resumed. Tested with ( IE 6.0, Mozilla, wget and FlashGet )
+[+] You can drag and drop file to the "statistics view"
+[+] Logs server requests to file ( optional default yes )
+[+] Right click on popup shows "statistics view"
+[+] The HTTP server can be enabled and disable from the main menu
+[+] The user list shows which Agent he is using.
+[+] "New share" menu item added to Right click menu.
+[+] "Edit share" menu item added to Right click menu.
+[+] Experimental external ip detection (known not to work well under windows 98)
+[+] Error dialogs when the link copy to clipboard fails
+[*] Some internal Elements.
+[!] Tab order in "statistics view"
+
+
+Version 0.1.0.0
+
+[+] Stores the position of the "statistics view"
+[+] New button in the "share new file dialog" to toggle the mask between 0.0.0.0 and 255.255.255.255
+[+] You can drag and drop files to the lower part of the "share new file dialog"
+[+] New button in option page to open the log file.
+[+] The state of the HTTP server is keep between sessions.
+[+] The popups can be disabled in the options.
+[+] HTTP Error codes are returned for some errors..
+[*] Web based ip detection. ( see help )
+[*] When logging trailing new lines in GET request will be removed.
+[!] Clicking "Set to default" did not enable apply button.
+[!] Closed and Open the "statistics view" while downloads in progresse then auto update diden work.
+
+
+Version 0.1.1.0
+
+[+] Speed control, Set the maximum bandwidth that you wish the server shout use.
+[+] Speed control can be set active only when your status is online.
+[!] After a file had been accessed thru the server it was locked. Introduced in 1.0.0
+[!] Some missing translation was added
+[!] Some people where unable to set another port then the default 80.
+
+
+Version 0.1.1.1
+
+[!] Unable to changed port realy fixed now. To make it short.
+ Now it works with both the Latest nightly and Miranda V.0.3.2.
+
+
+Version 0.1.1.2
+
+[!] With the Nightly build after 18 Jan. external ip detection diden work
+
+
+Version 0.1.1.3
+
+[!] Fixed the incorrect Content-Length header in HTTP 206 Partial Content responces
+ Now the download can be resumed in any download manager without getting an "incorrect file size" or "file size changed" messages.
+
+
+Version 0.1.1.4
+
+[+] Service MS_HTTP_ACCEPT_CONNECTIONS now accepts wParam.
+ By default it toggles HTTP server state.
+ Now you can force enable server passing wParam as TRUE.
+
+
+Version 0.1.1.5
+
+[+] Added possibility to share directories
+[+] If no index.html exists a directory index is created
+
+
+Version 0.1.1.6
+
+[+] The generated index.html looks nicer and can be customized
+
+
+Version 0.1.1.7
+
+[!] Fixed some security issues
+[+] Crystal Icon set included
+ Thanks to Everaldo Coelho (www.everaldo.com) who released them under GPL
+[*] Fixed serveral bugs
+[+] On Kennet's advice (and with his help) the index generation was rewritten.
+ The generated file is now an XML like the configuration file. It is easier to maintain
+ and more flexible.
+[+] Applied chronon's modifications to make it work with his Send Screenshot plugin
+[!] Only the shares which are accessible by a user are shown on the index
+[+] Files and Folders starting with an @ are not shown in the index and create no popups
+ They are also hidden in the statistics view but can be revealed
+[+] The column widths in statistics view are preserved
+
+
+Version 0.1.1.9
+
+[!] Fixed the disappearing statistics view bug
+[!] Browsers display the right error message
+[+] Maximum number of connections can be defined (total & per user)
+[+] Index creation can be disabled now
+[+] The user can decide now if the generated index shoud be a HTML or a XML
+ HTMLs are just for compatibility, it is recommended to use the XMLs
+ By default it sends XML to MSIE and Firefox and HTML to Opera and other browsers
+[+] "Open in Browser" menu entry in statistics view
+[!] External IP is updated if it is older than 10 minutes
+
+
+Version 0.1.1.91
+
+[!] When updating to a new version the shared files list is not cleared
+
+
+Version 0.1.2.0
+
+contributed by Vapik:
+[+] The browser is now redirected when trying to access a directory without the trailing slash
+[+] The error messages which are shown by the browser contain the version number of the plugin
+
+
+Version 0.1.2.1
+
+[!] Fixed several bugs (external IP generation, config files > 10kb,...)
+[!] Made HTTP-"Not Modified" response work again
+[+] Added [FileModified] and [FileCreated] tags to index (added the first one to the default templates)
+[+] Enhanced the controls in the statistic view
+[+] Multiple files can be selected & shared at once in the share new file dialog
+[+] Multiple files can be dropped into the statistic view (the default settings are used)
+[+] Fixed popup clicks (left opens the statistics view / right hides the popup)
+[+] Share names & requests are automatically converted to lowercase (to make it case insensitive)
+[+] Added "Default download limit" option
+[-] Removed "detect brower" option (which tried to detect whether a browser supports XSLT)
+
+
+Version 0.1.2.2
+
+[!] Recompiled with new Miranda headers.
diff --git a/plugins/HTTPServer/docs/data/Changelog.txt b/plugins/HTTPServer/docs/data/Changelog.txt
new file mode 100644
index 0000000000..de682e0249
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/Changelog.txt
@@ -0,0 +1,206 @@
+
+
+Version 0.0.1.0
+
+This is a beta version.
+Some features are not yet implemented.
+A shared file will only be remove when the maximum downloads has been reached.
+Suggestions and contributions are welcome.
+
+
+Version 0.0.2.0
+
+[+] You can change the default port used in Miranda options network "incoming connections"
+[+] Popup the message dialog with link when new file is shared.
+[!] Crash sometimes when share was about to be removed.
+[*] xsl file changed so that it shows link to file.
+
+
+Version 0.0.3.0
+
+[+] Uses popup plugin if installed to show when the HTTP server is accessed.
+[!] File path was not stored correctly, which meant that only files in the plugin folder could be shared.
+
+
+Version 0.0.4.0
+
+[!] Server did not use any port if you did not set a "incoming connections" port in the options.
+[+] More error dialog boxes if there is something that failes when initilizing. e.i. unable to bind port
+
+
+Version 0.0.4.1
+
+[+] If the open file dialog in "HTTP Share new file" fails an error message is displayed
+[!] Shutdown while file transfer is in progress is now handled correctly
+
+
+Version 0.0.4.2
+
+[!] "HTTP Share new file" only worked on Windows XP.
+
+
+Version 0.0.5.0
+
+[+] HTTP Server can now be accessed by multiply users simultaniously.
+[+] HTTP Server "statistics view" includes shares and current useres accessing the server.
+[+] Share can be removed from "statistics view"
+
+
+Version 0.0.6.0
+
+[!] Max downloads was not decreased so a share was never removed.
+[!] First share could not be removed then max downloads got to zero.
+[!] If a share was deleted while a download was in progress the download would not be stopped
+[*] Outgoing connections options has been removed.
+[+] Basic MIME support. Based on file extension.
+
+
+Version 0.0.7.0
+
+[+] In the "statistics view" you can copy a link to your shares.
+[+] Correct handling of UTF-8 encoded URIs in GET requests.fixes spaces and none US-ASCII characters.
+[!] Only masks 255.255.255.255 and 0.0.0.0 worked correctly any other was interpreted like 255.255.255.255.
+
+
+Version 0.0.8.0
+
+[+] Popup when a share is removed
+[!] Fixed bug in UTF-8 handling. Basically %?? part of handling did not work
+[!] Some spelling errors corrected.
+[*] Homepage link in options updated
+[*] Some internal Elements.
+
+
+Version 0.0.9.0
+
+[+] Downloads can be resumed. Tested with ( IE 6.0, Mozilla, wget and FlashGet )
+[+] You can drag and drop file to the "statistics view"
+[+] Logs server requests to file ( optional default yes )
+[+] Right click on popup shows "statistics view"
+[+] The HTTP server can be enabled and disable from the main menu
+[+] The user list shows which Agent he is using.
+[+] "New share" menu item added to Right click menu.
+[+] "Edit share" menu item added to Right click menu.
+[+] Experimental external ip detection (known not to work well under windows 98)
+[+] Error dialogs when the link copy to clipboard fails
+[*] Some internal Elements.
+[!] Tab order in "statistics view"
+
+
+Version 0.1.0.0
+
+[+] Stores the position of the "statistics view"
+[+] New button in the "share new file dialog" to toggle the mask between 0.0.0.0 and 255.255.255.255
+[+] You can drag and drop files to the lower part of the "share new file dialog"
+[+] New button in option page to open the log file.
+[+] The state of the HTTP server is keep between sessions.
+[+] The popups can be disabled in the options.
+[+] HTTP Error codes are returned for some errors..
+[*] Web based ip detection. ( see help )
+[*] When logging trailing new lines in GET request will be removed.
+[!] Clicking "Set to default" did not enable apply button.
+[!] Closed and Open the "statistics view" while downloads in progresse then auto update diden work.
+
+
+Version 0.1.1.0
+
+[+] Speed control, Set the maximum bandwidth that you wish the server shout use.
+[+] Speed control can be set active only when your status is online.
+[!] After a file had been accessed thru the server it was locked. Introduced in 1.0.0
+[!] Some missing translation was added
+[!] Some people where unable to set another port then the default 80.
+
+
+Version 0.1.1.1
+
+[!] Unable to changed port realy fixed now. To make it short.
+ Now it works with both the Latest nightly and Miranda V.0.3.2.
+
+
+Version 0.1.1.2
+
+[!] With the Nightly build after 18 Jan. external ip detection diden work
+
+
+Version 0.1.1.3
+
+[!] Fixed the incorrect Content-Length header in HTTP 206 Partial Content responces
+ Now the download can be resumed in any download manager without getting an "incorrect file size" or "file size changed" messages.
+
+
+Version 0.1.1.4
+
+[+] Service MS_HTTP_ACCEPT_CONNECTIONS now accepts wParam.
+ By default it toggles HTTP server state.
+ Now you can force enable server passing wParam as TRUE.
+
+
+Version 0.1.1.5
+
+[+] Added possibility to share directories
+[+] If no index.html exists a directory index is created
+
+
+Version 0.1.1.6
+
+[+] The generated index.html looks nicer and can be customized
+
+
+Version 0.1.1.7
+
+[!] Fixed some security issues
+[+] Crystal Icon set included
+ Thanks to Everaldo Coelho (www.everaldo.com) who released them under GPL
+[*] Fixed serveral bugs
+[+] On Kennet's advice (and with his help) the index generation was rewritten.
+ The generated file is now an XML like the configuration file. It is easier to maintain
+ and more flexible.
+[+] Applied chronon's modifications to make it work with his Send Screenshot plugin
+[!] Only the shares which are accessible by a user are shown on the index
+[+] Files and Folders starting with an @ are not shown in the index and create no popups
+ They are also hidden in the statistics view but can be revealed
+[+] The column widths in statistics view are preserved
+
+
+Version 0.1.1.9
+
+[!] Fixed the disappearing statistics view bug
+[!] Browsers display the right error message
+[+] Maximum number of connections can be defined (total & per user)
+[+] Index creation can be disabled now
+[+] The user can decide now if the generated index shoud be a HTML or a XML
+ HTMLs are just for compatibility, it is recommended to use the XMLs
+ By default it sends XML to MSIE and Firefox and HTML to Opera and other browsers
+[+] "Open in Browser" menu entry in statistics view
+[!] External IP is updated if it is older than 10 minutes
+
+
+Version 0.1.1.91
+
+[!] When updating to a new version the shared files list is not cleared
+
+
+Version 0.1.2.0
+
+contributed by Vapik:
+[+] The browser is now redirected when trying to access a directory without the trailing slash
+[+] The error messages which are shown by the browser contain the version number of the plugin
+
+
+Version 0.1.2.1
+
+[!] Fixed several bugs (external IP generation, config files > 10kb,...)
+[!] Made HTTP-"Not Modified" response work again
+[+] Added [FileModified] and [FileCreated] tags to index (added the first one to the default templates)
+[+] Enhanced the controls in the statistic view
+[+] Multiple files can be selected & shared at once in the share new file dialog
+[+] Multiple files can be dropped into the statistic view (the default settings are used)
+[+] Fixed popup clicks (left opens the statistics view / right hides the popup)
+[+] Share names & requests are automatically converted to lowercase (to make it case insensitive)
+[+] Added "Default download limit" option
+[-] Removed "detect brower" option (which tried to detect whether a browser supports XSLT)
+
+
+Version 0.1.2.2
+
+[!] Recompiled with new Miranda headers.
diff --git a/plugins/HTTPServer/docs/data/HTTPMimeTypes b/plugins/HTTPServer/docs/data/HTTPMimeTypes
new file mode 100644
index 0000000000..8860fdb930
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/HTTPMimeTypes
@@ -0,0 +1,478 @@
+# This file is part of HTTPServer a Miranda IM plugin.
+# The file is taken from the apache project.
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here
+# For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at <http://www.iana.org/assignments/media-types/>.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/basic au snd
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-mod mod
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-c++hdr hpp hxx hh
+text/x-c++src cpp,cxx,cc
+text/x-chdr h
+text/x-csrc c
+text/x-setext etx
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
diff --git a/plugins/HTTPServer/docs/data/HTTPServer.dll b/plugins/HTTPServer/docs/data/HTTPServer.dll
new file mode 100644
index 0000000000..d315b17d8b
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/HTTPServer.dll
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/HTTPServer.pdf b/plugins/HTTPServer/docs/data/HTTPServer.pdf
new file mode 100644
index 0000000000..7aed97ba6b
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/HTTPServer.pdf
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/HTTPServer.xsl b/plugins/HTTPServer/docs/data/HTTPServer.xsl
new file mode 100644
index 0000000000..fc5006707e
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/HTTPServer.xsl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- Edited with XML Spy v4.2 -->
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:template match="/">
+ <html>
+ <body>
+ <h2>HTTP server configuration</h2>
+ <table border="1">
+ <tr bgcolor="#9acd32">
+ <th align="left">Name</th>
+ <th align="left">File</th>
+ <th align="left">Max downloads</th>
+ <th align="left">IP address</th>
+ <th align="left">IP mask</th>
+ </tr>
+ <xsl:for-each select="config/share">
+ <tr>
+ <td>
+ <xsl:element name="A">
+ <xsl:attribute name="href"><xsl:value-of select="name"/></xsl:attribute>
+ <xsl:value-of select="name"/>
+ </xsl:element>
+ </td>
+ <td><xsl:value-of select="file"/></td>
+ <td><xsl:value-of select="max_downloads"/></td>
+ <td><xsl:value-of select="ip_address"/></td>
+ <td><xsl:value-of select="ip_mask"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/plugins/HTTPServer/docs/data/HTTPServerIndex.html b/plugins/HTTPServer/docs/data/HTTPServerIndex.html
new file mode 100644
index 0000000000..4fdc41940a
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/HTTPServerIndex.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+<title>Directory Listing of [DirectoryName]</title>
+<style type="text/css">
+td { font-size:14px; color:#000033;}
+a:link { text-decoration: none; color:#003366; }
+a:visited { text-decoration: none; color:#003366; }
+a:active { text-decoration: none; color:#FFAA33; }
+a:hover { text-decoration: underline; color:#FFAA33; }
+</style>
+</head>
+<body bgcolor=#B0B0CC>
+<font face='tahoma, arial'>
+
+<table cellspacing=1 cellpadding=2 width=700>
+<tr height=40 bgcolor=#EEEEFF><td colspan=3 align=center>
+<h3 style='margin:0px'><font color="#666688">Directory Listing of [DirectoryName]</font></h3>
+[ForDirectoriesDo]<tr [IsEven]bgcolor=#EEEEFF[End][IsOdd]bgcolor=#DDDDEE[End]><td colspan=3><img src="/icons/folder_gray.png"><img src="/placeholder.gif" width=5><a href="[DirectoryUrl]">[DirectoryName]</a></td></tr>[End]
+[ForFilesDo]<tr [IsEven]bgcolor=#EEEEFF[End][IsOdd]bgcolor=#DDDDEE[End]><td>
+[IsFileType=jpg,jpeg,gif,png,bmp]<img src="/icons/image2.png">[End]
+[IsFileType=zip,rar,ace,arj,lha,lhz,tar,gz]<img src="/icons/tar.png">[End]
+[IsFileType=rtf,doc]<img src="/icons/doc.png">[End]
+[IsFileType=txt,diz]<img src="/icons/txt.png">[End]
+[IsFileType=pdf]<img src="/icons/pdf.png">[End]
+[IsFileType=exe,bat]<img src="/icons/win_apps.png">[End]
+[IsFileType=html,htm,xml]<img src="/icons/www.png">[End]
+[IsFileType=avi,mpg]<img src="/icons/video.png">[End]
+[IsFileType=c,cpp,h]<img src="/icons/source.png">[End]
+[IsFileType=mp3,ogg,wav,mid,mod,xm]<img src="/icons/sound.png">[End]
+[IsFileType=*]<img src="/icons/empty.png">[End]<img src="/placeholder.gif" width=5><a href="[FileUrl]">[FileName]</a></td><td>[FileModified]</td><td align='right'>[FileSize]</td></tr>[End]
+</font>
+</body>
+
+</html> \ No newline at end of file
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico b/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico
new file mode 100644
index 0000000000..1bd45b98e4
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png
new file mode 100644
index 0000000000..f4d5bfd139
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png
new file mode 100644
index 0000000000..bfe1d06e04
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png
new file mode 100644
index 0000000000..ea7f314dba
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png
new file mode 100644
index 0000000000..dbefd0ccfa
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png
new file mode 100644
index 0000000000..27faad6fc0
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png
new file mode 100644
index 0000000000..bfe6022c8c
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png
new file mode 100644
index 0000000000..14a9c6ee31
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png
new file mode 100644
index 0000000000..8bdfa8a0fc
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png
new file mode 100644
index 0000000000..b34ba0b892
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png
new file mode 100644
index 0000000000..6c5f692d79
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png
new file mode 100644
index 0000000000..c22b0e24c9
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png
new file mode 100644
index 0000000000..2bd96dd012
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png
Binary files differ
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl b/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl
new file mode 100644
index 0000000000..d8e8f4e872
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl
@@ -0,0 +1,121 @@
+<?xasml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!-- Icons by Everaldo Coelho (www.everaldo.com) -->
+
+<xsl:template match="/">
+
+ <xsl:variable name="dirname">
+ <xsl:choose>
+ <xsl:when test="config/dirname=''">my Miranda Webserver</xsl:when>
+ <xsl:otherwise><xsl:value-of select="config/dirname"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+<html>
+ <head>
+ <title>Directory Listing of <xsl:value-of select="$dirname"/></title>
+ <style type="text/css">
+ td { font-family:tahoma, arial; font-size:14px; color:#000033;}
+ a:link { text-decoration: none; color:#003366; }
+ a:visited { text-decoration: none; color:#003366; }
+ a:active { text-decoration: none; color:#FFAA33; }
+ a:hover { text-decoration: underline; color:#FFAA33; }
+ </style>
+ </head>
+
+ <body bgcolor='#B0B0CC'>
+ <font face='tahoma, arial'>
+ <table border='0' cellspacing='1' cellpadding='2' width='700'>
+ <tr height='40' bgcolor='#EEEEFF'>
+ <td colspan='3' align='center'>
+ <h3 style='margin:0px'><font color="#666688">Directory Listing of <xsl:value-of select="$dirname"/></font></h3>
+ </td>
+ </tr>
+ <xsl:for-each select="config/item">
+ <xsl:sort select="@isdir" order="descending"/>
+ <xsl:sort select="@name"/>
+ <xsl:element name='tr'>
+ <xsl:attribute name="bgcolor">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">#EEEEFF</xsl:when>
+ <xsl:otherwise>#DDDDEE</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:element name='td'>
+ <xsl:attribute name="colspan">
+ <xsl:choose>
+ <xsl:when test="@isdir='true'">3</xsl:when>
+ <xsl:otherwise>1</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:variable name="ext">
+ <xsl:value-of select="translate(@ext, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
+ </xsl:variable>
+ <xsl:variable name="icon">
+ <xsl:choose>
+ <xsl:when test="@isdir='true'">folder_gray.png</xsl:when>
+ <xsl:when test="$ext='jpg' or $ext='jpeg' or $ext='gif' or $ext='png' or $ext='bmp'">image2.png</xsl:when>
+ <xsl:when test="$ext='zip' or $ext='rar' or $ext='ace' or $ext='arj' or $ext='lha' or ext='lhz' or ext='tar' or ext='gz'">tar.png</xsl:when>
+ <xsl:when test="$ext='rtf' or $ext='doc'">document2.png</xsl:when>
+ <xsl:when test="$ext='txt' or $ext='diz'">txt.png</xsl:when>
+ <xsl:when test="$ext='pdf'">pdf.png</xsl:when>
+ <xsl:when test="$ext='exe' or $ext='bat'">win_apps.png</xsl:when>
+ <xsl:when test="$ext='html' or $ext='htm' or $ext='xml'">www.png</xsl:when>
+ <xsl:when test="$ext='avi' or $ext='mpg'">video.png</xsl:when>
+ <xsl:when test="$ext='c' or $ext='cpp' or $ext='h'">source.png</xsl:when>
+ <xsl:when test="$ext='mp3' or $ext='ogg' or $ext='wav' or $ext='mid' or $ext='mod' or $ext='xm'">sound.png</xsl:when>
+ <xsl:otherwise>empty.png</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:element name='img'>
+ <xsl:attribute name="src">/icons/<xsl:value-of select="$icon"/></xsl:attribute>
+ </xsl:element>
+ <xsl:element name='img'>
+ <xsl:attribute name="src">/placeholder.gif</xsl:attribute>
+ <xsl:attribute name="width">5</xsl:attribute>
+ </xsl:element>
+ <xsl:element name="a">
+ <xsl:attribute name="href">
+ <xsl:value-of select="@name"/>
+ <xsl:if test="@ext!=''">.<xsl:value-of select="@ext"/></xsl:if>
+ <xsl:if test="@isdir='true'">/</xsl:if>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ <xsl:if test="@ext!=''">.<xsl:value-of select="@ext"/></xsl:if>
+ </xsl:element>
+ </xsl:element>
+ <xsl:choose>
+ <xsl:when test="@isdir='true'"></xsl:when>
+ <xsl:otherwise>
+ <td><xsl:value-of select="@modified"/></td>
+ <!-- <td><xsl:value-of select="@created"/></td> -->
+ <td width='100' align='right'>
+ <xsl:choose>
+ <xsl:when test="@size >= 1073741824">
+ <xsl:value-of select="round(@size div 107374182.4) div 10"/><font size="-1"> GB</font>
+ </xsl:when>
+ <xsl:when test="@size >= 1048576">
+ <xsl:value-of select="round(@size div 104857.6) div 10"/><font size="-1"> MB</font>
+ </xsl:when>
+ <xsl:when test="@size >= 1024">
+ <xsl:value-of select="round(@size div 102.4) div 10"/><font size="-1"> KB</font>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@size"/><font size="-1"> Byte</font>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:for-each>
+ </table>
+ </font>
+ </body>
+</html>
+
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif b/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif
new file mode 100644
index 0000000000..213771dde3
--- /dev/null
+++ b/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif
Binary files differ
diff --git a/plugins/HTTPServer/res/dis_srv.ico b/plugins/HTTPServer/res/dis_srv.ico
new file mode 100644
index 0000000000..06647ecb18
--- /dev/null
+++ b/plugins/HTTPServer/res/dis_srv.ico
Binary files differ
diff --git a/plugins/HTTPServer/res/resource.rc b/plugins/HTTPServer/res/resource.rc
new file mode 100644
index 0000000000..20e5ae95d3
--- /dev/null
+++ b/plugins/HTTPServer/res/resource.rc
@@ -0,0 +1,207 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "..\src\resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Ðóññêèé (Ðîññèÿ) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_DISABLE_SERVER ICON "dis_srv.ico"
+IDI_SHARE_NEW_FILE ICON "share_ne.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_NEW_SHARE_PROPERTIES DIALOGEX 0, 0, 279, 57
+STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+EXSTYLE WS_EX_ACCEPTFILES
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_SHARE_NAME,46,10,63,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_MAX_DOWNLOADS,61,29,48,14,ES_AUTOHSCROLL
+ CONTROL "IPAddress1",IDC_ALLOWED_IPADDRESS,"SysIPAddress32",WS_TABSTOP,150,9,100,15
+ CONTROL "IPAddress2",IDC_ALLOWED_IP_MASK,"SysIPAddress32",WS_TABSTOP,150,31,100,15
+ LTEXT "Max downloads",IDC_STATIC,5,31,50,8
+ LTEXT "Address",IDC_STATIC,120,12,26,8
+ LTEXT "Mask",IDC_STATIC,120,34,18,8
+ LTEXT "Share name",IDC_STATIC,5,12,39,8
+ GROUPBOX "Allowed IP",IDC_STATIC,115,0,161,54
+ PUSHBUTTON "",IDC_TOGGLE_MASK,257,31,13,15
+END
+
+IDD_STATISTICS_VIEW DIALOGEX 0, 0, 410, 198
+STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_ACCEPTFILES
+CAPTION "HTTP Server statistics view"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "List1",IDC_CURRENT_SHARES,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,7,20,396,86
+ CONTROL "List1",IDC_CURRENT_USERS,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,7,111,396,80
+ CONTROL "Display hidden shares",IDC_SHOWHIDDENSHARES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,6,125,11
+ PUSHBUTTON "New share",ID_SHARELIST_NEWSHARE,6,5,70,12
+END
+
+IDD_OPT_HTTP_SERVER DIALOGEX 0, 0, 314, 240
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EXTERNAL_SRV_NAME,35,73,244,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+ CONTROL "Show HTTP server statistics",IDC_ADD_STATISTICS_MENU_ITEM,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,30,117,10
+ PUSHBUTTON "Set to default",IDC_EXTERNAL_SRV_DEFAULT,224,55,56,14
+ GROUPBOX "External server name",IDC_STATIC,30,47,254,106
+ LTEXT "This is the link pasted to the message window",IDC_STATIC,35,61,186,8
+ CONTROL "Write log file",IDC_WRITE_LOG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,31,66,10
+ CONTROL "Enable / Disable HTTP server",IDC_ACCEPT_COM_MENU_ITEM,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,15,115,10
+ GROUPBOX "Main menu items",IDC_STATIC,30,3,121,42
+ PUSHBUTTON "Open log",IDC_OPEN_LOG,230,27,50,14
+ CONTROL "Show popups",IDC_SHOW_POPUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,15,112,10
+ LTEXT "Page keyword",IDC_STATIC,40,129,46,8
+ LTEXT "URL address",IDC_STATIC,40,110,42,8
+ GROUPBOX "%ExternalIP% variable",IDC_STATIC,35,96,244,51
+ COMBOBOX IDC_URL_ADDRESS,94,108,180,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_PAGE_KEYWORD,93,127,123,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Test",IDC_TEST_EXTERNALIP,224,126,51,14
+ EDITTEXT IDC_MAX_SPEED,35,181,24,12,ES_AUTOHSCROLL
+ LTEXT "Transfer limit (kb/sec)",IDC_STATIC,62,183,91,8
+ CONTROL "No control when Away/NA",IDC_LIMIT_ONLY_WHEN_ONLINE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,224,114,10
+ GROUPBOX "Connection control",IDC_STATIC,30,155,127,81
+ GROUPBOX "Index creation",IDC_STATIC,162,155,122,56
+ CONTROL "Disable",IDC_INDEX_OFF,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,169,168,105,10
+ CONTROL "Create HTML (compatibility)",IDC_INDEX_HTML,"Button",BS_AUTORADIOBUTTON,169,182,105,10
+ CONTROL "Create XML",IDC_INDEX_XML,"Button",BS_AUTORADIOBUTTON,169,196,105,10
+ GROUPBOX "Notifications",IDC_STATIC,157,3,127,42
+ LTEXT "Total connection limit",IDC_STATIC,62,197,93,8
+ LTEXT "Connections per user limit",IDC_STATIC,62,211,92,8
+ EDITTEXT IDC_MAX_CONN_TOTAL,35,195,24,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_MAX_CONN_PER_USER,35,209,24,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_DEFAULT_DOWNLOAD_LIMIT,35,167,24,12,ES_AUTOHSCROLL
+ LTEXT "Default download limit",IDC_STATIC,62,169,91,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_NEW_SHARE_PROPERTIES, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ VERTGUIDE, 109
+ VERTGUIDE, 120
+ BOTTOMMARGIN, 46
+ HORZGUIDE, 31
+ END
+
+ IDD_STATISTICS_VIEW, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 403
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 191
+ END
+
+ IDD_OPT_HTTP_SERVER, DIALOG
+ BEGIN
+ RIGHTMARGIN, 313
+ VERTGUIDE, 30
+ VERTGUIDE, 35
+ VERTGUIDE, 40
+ VERTGUIDE, 162
+ VERTGUIDE, 274
+ VERTGUIDE, 279
+ VERTGUIDE, 284
+ HORZGUIDE, 20
+ HORZGUIDE, 36
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "..\\src\\resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU
+BEGIN
+ POPUP "1"
+ BEGIN
+ MENUITEM "&Edit share", ID_SHARELIST_EDITSHARE
+ MENUITEM "&Remove share", ID_SHARELIST_REMOVESHARE
+ MENUITEM SEPARATOR
+ MENUITEM "&Open in Browser", ID_SHARELIST_OPEN
+ MENUITEM "&Copy link", ID_SHARELIST_COPYLINK
+ END
+END
+
+#endif // Ðóññêèé (Ðîññèÿ) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/HTTPServer/res/share_ne.ico b/plugins/HTTPServer/res/share_ne.ico
new file mode 100644
index 0000000000..3ca16036b3
--- /dev/null
+++ b/plugins/HTTPServer/res/share_ne.ico
Binary files differ
diff --git a/plugins/HTTPServer/src/FileShareNode.cpp b/plugins/HTTPServer/src/FileShareNode.cpp
new file mode 100644
index 0000000000..d2e9f62731
--- /dev/null
+++ b/plugins/HTTPServer/src/FileShareNode.cpp
@@ -0,0 +1,375 @@
+//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"
+
+CLFileShareNode * pclFirstNode = NULL;
+CRITICAL_SECTION csFileShareListAccess;
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CLShareUser
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030918, 18 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLShareUser::CLShareUser(HANDLE hCon, in_addr stAdd) {
+ hConnection = hCon;
+ stAddr = stAdd;
+ pclNext = NULL;
+ dwTotalSize = 0;
+ dwCurrentDL = 0;
+ dwSpeed = 0;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ~CLShareUser
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031124, 24 november 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLShareUser::~CLShareUser() {
+ if (hConnection) {
+ CloseSocket();
+ Netlib_CloseHandle(hConnection);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CloseSend
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031124, 24 november 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void CLShareUser::CloseSocket() {
+ SOCKET s = CallService(MS_NETLIB_GETSOCKET, (WPARAM) hConnection, 0);
+ if (s != INVALID_SOCKET) {
+ shutdown(s, SD_SEND);
+ int nBytesRead;
+ do {
+ char szBuf[100];
+ nBytesRead = Netlib_Recv(hConnection, szBuf, sizeof(szBuf), 0);
+ } while (nBytesRead && nBytesRead != SOCKET_ERROR);
+ //shutdown( s, SD_RECEIVE );
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : dwGetDownloadSpeed
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns : DWORD
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030918, 18 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+DWORD CLShareUser::dwGetDownloadSpeed() {
+ return dwSpeed;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CLFileShareNode
+// Type : Private / Public / Protected
+// Parameters : NULL - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030826, 26 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLFileShareNode::CLFileShareNode(char * pszSrvPath, char * pszRealPath) {
+ memset(&st, 0, sizeof(STFileShareInfo));
+ st.lStructSize = sizeof(STFileShareInfo);
+ pclNext = NULL;
+ pclCurrentUsers = NULL;
+
+ bSetPaths(pszSrvPath, pszRealPath);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CLFileShareNode
+// Type : Global
+// Parameters : pstInfo - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030829, 29 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLFileShareNode::CLFileShareNode(STFileShareInfo * pstInfo) {
+ memset(&st, 0, sizeof(STFileShareInfo));
+ st.lStructSize = sizeof(STFileShareInfo);
+ pclNext = NULL;
+ pclCurrentUsers = NULL;
+
+ bSetInfo(pstInfo);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ~CLFileShareNode
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030826, 26 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLFileShareNode::~CLFileShareNode() {
+ delete [] st.pszSrvPath;
+ delete [] st.pszRealPath;
+
+ CLShareUser * pclCur = pclCurrentUsers;
+ while (pclCur) {
+ CLShareUser * pclNext = pclCur->pclNext;
+ delete pclCur;
+ pclCur = pclNext;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bSetPaths
+// Type : Private / Public / Protected
+// Parameters : pszSrvPath - ?
+// pszRealPath - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030829, 29 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool CLFileShareNode::bSetPaths(char * pszSrvPath, char * pszRealPath) {
+ /* This might be a problem !!
+ if( nDownloadsInProgress > 0 )
+ return false;
+ */
+
+ if (!pszSrvPath || !pszRealPath)
+ return false;
+
+ delete [] st.pszSrvPath;
+ delete [] st.pszRealPath;
+
+ st.dwMaxSrvPath = strlen(pszSrvPath) + 1;
+ st.pszSrvPath = new char[ st.dwMaxSrvPath ];
+ strcpy(st.pszSrvPath, pszSrvPath);
+
+ int nRealLen = strlen(pszRealPath);
+ if (nRealLen <= 2 || !(pszRealPath[1] == ':' ||
+ (pszRealPath[0] == '\\' && pszRealPath[1] == '\\'))) {
+ // Relative path
+ // we will prepend plugin path to avoid problems
+ st.dwMaxRealPath = nPluginPathLen + nRealLen + 1;
+ st.pszRealPath = new char[ st.dwMaxRealPath ];
+ strcpy(st.pszRealPath, szPluginPath);
+ pszOrigRealPath = &st.pszRealPath[nPluginPathLen];
+ } else {
+ st.dwMaxRealPath = nRealLen + 1;
+ st.pszRealPath = new char[ st.dwMaxRealPath ];
+ pszOrigRealPath = st.pszRealPath;
+ }
+ strcpy(pszOrigRealPath, pszRealPath);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bSetInfo
+// Type : Private / Public / Protected
+// Parameters : pstInfo - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030829, 29 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool CLFileShareNode::bSetInfo(STFileShareInfo * pstInfo) {
+ if (! bSetPaths(pstInfo->pszSrvPath, pstInfo->pszRealPath))
+ return false;
+ if (pstInfo->nMaxDownloads < -1)
+ return false;
+
+ st.dwAllowedIP = pstInfo->dwAllowedIP;
+ st.dwAllowedMask = pstInfo->dwAllowedMask;
+ st.nMaxDownloads = pstInfo->nMaxDownloads;
+ st.dwOptions = pstInfo->dwOptions;
+ return true;
+}
+
+/*
+/////////////////////////////////////////////////////////////////////
+// Member Function : bAddHttpUser
+// Type : Private / Public / Protected
+// Parameters : hConnection - ?
+// stAddr - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030902, 02 september 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+CLHttpUser * CLFileShareNode::pclAddHttpUser( HANDLE hConnection, in_addr stAddr )
+{
+ CLHttpUser * pclCur = pclCurrentUsers;
+ while( pclCur )
+ {
+ if( pclCur->hConnection == hConnection )
+ {
+ return NULL;
+ }
+ pclCur = pclCur->pclNext;
+ }
+ pclCurrentUsers = new CLHttpUser( hConnection, stAddr, pclCurrentUsers );
+ UpdateStatisticsView();
+ return pclCurrentUsers;
+}
+*/
+
+bool CLFileShareNode::bAddUser(CLShareUser * pclUser) {
+ // deny access
+ if (bIsOnline || !bLimitOnlyWhenOnline) {
+ int nConnectionCount = 0;
+ int nUserConnectionCount = 0;
+
+ // iterate through all shares
+ CLFileShareNode * pclShare = pclFirstNode;
+ while (pclShare) {
+ // iterate through its users
+ CLShareUser * pclCur = pclShare->pclCurrentUsers;
+ while (pclCur) {
+ //strcmp(pclCur->szCurrentDLSrvPath, pclUser->szCurrentDLSrvPath) == 0) // same file
+ if (memcmp(&pclCur->stAddr, &pclUser->stAddr, sizeof(in_addr)) == 0) // same IP
+ nUserConnectionCount++;
+
+ nConnectionCount++;
+
+ pclCur = pclCur->pclNext;
+ }
+ pclShare = pclShare->pclNext;
+ }
+
+ if (nMaxConnectionsTotal >= 0)
+ if (nConnectionCount + 1 > nMaxConnectionsTotal)
+ return false;
+
+ if (nMaxConnectionsPerUser >= 0)
+ if (nUserConnectionCount + 1 > nMaxConnectionsPerUser)
+ return false;
+ }
+
+ pclUser->pclNext = pclCurrentUsers;
+ pclCurrentUsers = pclUser;
+ UpdateStatisticsView();
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bRemoveUser
+// Type : Private / Public / Protected
+// Parameters : pclUser - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030918, 18 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool CLFileShareNode::bRemoveUser(CLShareUser * pclUser) {
+ CLShareUser **pclPrev = &pclCurrentUsers;
+ CLShareUser * pclCur = pclCurrentUsers;
+ while (pclCur) {
+ if (pclCur == pclUser) {
+ *pclPrev = pclCur->pclNext;
+ UpdateStatisticsView();
+ return true;
+ }
+ pclPrev = &pclCur->pclNext;
+ pclCur = pclCur->pclNext;
+ }
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CloseAllTransfers
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030902, 02 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void CLFileShareNode::CloseAllTransfers() {
+ CLShareUser * pclCur = pclCurrentUsers;
+ while (pclCur) {
+ pclCur->CloseSocket();
+ pclCur = pclCur->pclNext;
+ }
+} \ No newline at end of file
diff --git a/plugins/HTTPServer/src/FileShareNode.h b/plugins/HTTPServer/src/FileShareNode.h
new file mode 100644
index 0000000000..706a31f093
--- /dev/null
+++ b/plugins/HTTPServer/src/FileShareNode.h
@@ -0,0 +1,103 @@
+//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.
+
+#ifndef FILE_SHARE_NODE_H
+#define FILE_SHARE_NODE_H
+
+#include <windows.h>
+#include "m_HTTPServer.h"
+
+class CLShareUser {
+public:
+ CLShareUser(HANDLE hCon, in_addr stAdd);
+ virtual ~CLShareUser();
+ CLShareUser * pclNext;
+ in_addr stAddr;
+ DWORD dwCurrentDL;
+ DWORD dwTotalSize;
+ char szCurrentDLSrvPath[MAX_PATH];
+ virtual DWORD dwGetDownloadSpeed();
+ virtual bool bCloseTransfers() = NULL;
+ virtual const char * pszCustomInfo() = NULL;
+ void CloseSocket();
+protected:
+ HANDLE hConnection;
+ DWORD dwSpeed;
+};
+
+class CLFileShareNode {
+public://, DWORD dwAllowedIP, DWORD dwAllowedMask, int nMaxDownloads );
+ CLFileShareNode(char * pszSrvPath, char * pszRealPath);
+ CLFileShareNode(STFileShareInfo * pstInfo);
+ ~CLFileShareNode();
+ bool bSetPaths(char * pszSrvPath, char * pszRealPath);
+ bool bSetInfo(STFileShareInfo * pstInfo);
+ int nGetSrvPathLen() {
+ return st.dwMaxSrvPath -1;
+ }
+ bool bIsDirectory() {
+ return st.pszSrvPath[st.dwMaxSrvPath-2] == '/';
+ }
+
+ STFileShareInfo st;
+ char *pszOrigRealPath;
+ CLFileShareNode * pclNext;
+ //CLHttpUser * pclAddHttpUser( HANDLE hConnection, in_addr stAddr );
+ //bool bRemoveHttpUser( CLHttpUser * pclUser );
+ bool bAddUser(CLShareUser * pclUser);
+ bool bRemoveUser(CLShareUser * pclUser);
+ bool bAnyUsers() {
+ return pclCurrentUsers != 0;
+ }
+ void CloseAllTransfers();
+ CLShareUser *pclGetUsers() {
+ return pclCurrentUsers;
+ }
+private:
+ CLShareUser * pclCurrentUsers;
+
+};
+
+extern CLFileShareNode * pclFirstNode;
+extern CRITICAL_SECTION csFileShareListAccess;
+
+class CLFileShareListAccess {
+ bool bLocked;
+public:
+ CLFileShareListAccess() {
+ bLocked = false;
+ Lock();
+ }
+ ~CLFileShareListAccess() {
+ Unlock();
+ }
+ void Lock() {
+ if (bLocked)
+ return;
+ EnterCriticalSection(&csFileShareListAccess);
+ bLocked = true;
+ }
+ void Unlock() {
+ if (!bLocked)
+ return;
+ LeaveCriticalSection(&csFileShareListAccess);
+ bLocked = false;
+ }
+
+};
+
+#endif \ No newline at end of file
diff --git a/plugins/HTTPServer/src/Glob.h b/plugins/HTTPServer/src/Glob.h
new file mode 100644
index 0000000000..dbce7e44e2
--- /dev/null
+++ b/plugins/HTTPServer/src/Glob.h
@@ -0,0 +1,94 @@
+//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.
+
+#ifndef HTTP_SERVER_GLOB_H
+#define HTTP_SERVER_GLOB_H
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <windows.h>
+#include <commctrl.h>
+#include <process.h>
+#include <time.h>
+#include <stdio.h>
+#include <string>
+using namespace std;
+
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_clist.h>
+#include <m_skin.h>
+#include <m_langpack.h>
+#include <m_clui.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>
+
+#include "m_HTTPServer.h"
+
+#include "FileShareNode.h"
+#include "HttpUser.h"
+#include "GuiElements.h"
+#include "MimeHandling.h"
+#include "resource.h"
+#include "IndexCreation.h"
+
+
+#define SD_RECEIVE 0x00
+#define SD_SEND 0x01
+#define SD_BOTH 0x02
+
+#define MODULE "HTTPServer"
+#define MSG_BOX_TITEL _T("Miranda (HTTPServer.dll)")
+
+#define SplitIpAddress( p ) (BYTE)(p>>24),(BYTE)(p>>16),(BYTE)(p>>8),(BYTE)(p)
+
+extern HINSTANCE hInstance;
+
+extern HANDLE hNetlibUser;
+
+extern bool bShutdownInProgress;
+bool bWriteConfigurationFile();
+
+void LogEvent(const char * pszTitle, const char * pszLog);
+bool bOpenLogFile();
+
+extern char szPluginPath[MAX_PATH];
+extern int nPluginPathLen;
+
+extern DWORD dwLocalIpAddress;
+extern DWORD dwLocalPortUsed;
+extern DWORD dwExternalIpAddress;
+
+extern int nMaxUploadSpeed;
+extern int nMaxConnectionsTotal;
+extern int nMaxConnectionsPerUser;
+extern int nDefaultDownloadLimit;
+extern bool bIsOnline;
+extern bool bLimitOnlyWhenOnline;
+
+extern void* (*MirandaMalloc)(size_t);
+extern void (*MirandaFree)(void*);
+
+extern char * pszVersion;
+
+#endif \ No newline at end of file
diff --git a/plugins/HTTPServer/src/GuiElements.cpp b/plugins/HTTPServer/src/GuiElements.cpp
new file mode 100644
index 0000000000..e4c922fd6d
--- /dev/null
+++ b/plugins/HTTPServer/src/GuiElements.cpp
@@ -0,0 +1,1553 @@
+//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 MS_SHARE_NEW_FILE "HTTPServer/ShareNewFile"
+#define MS_SHOW_STATISTICS_VIEW "HTTPServer/ShowStatisticsView"
+
+#define WM_RELOAD_STATISTICS (WM_USER+10)
+
+static HANDLE hShareNewFileService = 0;
+static HANDLE hShowStatisticsViewService = 0;
+
+static HANDLE hShareNewFileMenuItem = 0;
+static HANDLE hShowStatisticsViewMenuItem = 0;
+
+static HANDLE hEventOptionsInitialize = 0;
+
+HWND hwndStatsticView = 0;
+bool bLastAutoRefress = false;
+HANDLE hMainThread;
+
+bool bShowPopups = true;
+
+#define szDefaultExternalSrvName "http://%ExternalIP%:%Port%%SrvPath%"
+
+#define szDefaultUrlAddress "http://checkip.dyndns.org"
+#define szDefaultPageKeyword "Current IP Address: "
+
+string sUrlAddress = szDefaultUrlAddress;
+string sPageKeyword = szDefaultPageKeyword;
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ReplaceAll
+// Type : Global
+// Parameters : sSrc - string to replace in
+// pszReplace - what to replace
+// sNew - the string to insert insted of pszReplace
+// Returns : void
+// Description : will replace all acurances of a string with another string
+// used to replace %user%, and other user
+// References : -
+// Remarks : -
+// Created : 020422, 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ReplaceAll(string &sSrc, const char * pszReplace, const string &sNew) {
+ string::size_type nCur = 0;
+ int nRepalceLen = strlen(pszReplace);
+ while ((nCur = sSrc.find(pszReplace, nCur)) != sSrc.npos) {
+ sSrc.replace(nCur, nRepalceLen, sNew);
+ nCur += sNew.size();
+ }
+}
+
+void ReplaceAll(string &sSrc, const char * pszReplace, const char * pszNew) {
+ string sNew = pszNew;
+ ReplaceAll(sSrc, pszReplace, sNew);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DBGetString
+// Type : Global
+// Parameters : hContact - ?
+// szModule - ?
+// szSetting - ?
+// pszError - ?
+// Returns : string
+// Description : Reads a string from the database
+// Just like those in database.h
+// References : -
+// Remarks : -
+// Created : 020422, 22 April 2002
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+string DBGetString(HANDLE hContact, const char *szModule, const char *szSetting, const char * pszError) {
+ string ret;
+ DBVARIANT dbv = {0};
+ if (! DBGetContactSetting(hContact, szModule, szSetting, &dbv)) {
+ if (dbv.type != DBVT_ASCIIZ) {
+ MessageBox(NULL, "DB: Attempt to get wrong type of value, string", MSG_BOX_TITEL, MB_OK);
+ ret = pszError;
+ } else {
+ ret = dbv.pszVal;
+ }
+ } else
+ ret = pszError;
+ DBFreeVariant(&dbv);
+ return ret;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : UpdateStatisticsView
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030904, 04 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void UpdateStatisticsView() {
+ if (hwndStatsticView) {
+ PostMessage(hwndStatsticView, WM_RELOAD_STATISTICS, 0, 0);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : GetExternIP
+// Type : Global
+// Parameters : szURL - The url of the page where IP is written
+// szPattern - The text before the IP in page (can be "")
+// Returns : External IP or 0 if error
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031113, 13 november 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+unsigned long GetExternIP(const char *szURL, const char *szPattern) {
+ HCURSOR hPrevCursor = ::SetCursor(::LoadCursor(0, IDC_WAIT));
+
+ NETLIBHTTPREQUEST nlhr;
+ ZeroMemory(&nlhr, sizeof(nlhr));
+ nlhr.cbSize = sizeof(nlhr);
+ nlhr.requestType = REQUEST_GET;
+ nlhr.flags = NLHRF_DUMPASTEXT;
+ nlhr.szUrl = (char*)szURL;
+
+ IN_ADDR externIP;
+ externIP.s_addr = 0;
+
+ NETLIBHTTPREQUEST *nlreply = (NETLIBHTTPREQUEST *) CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM) hNetlibUser, (LPARAM) & nlhr);
+ if (nlreply) {
+ if (nlreply->resultCode >= 200 && nlreply->resultCode < 300) {
+ nlreply->pData[nlreply->dataLength] = 0;// make sure its null terminated
+ char * pszIp = strstr(nlreply->pData, szPattern);
+ if (pszIp == NULL)
+ pszIp = nlreply->pData;
+ else
+ pszIp += strlen(szPattern);
+ while ((*pszIp < '0' || *pszIp > '9') && *pszIp)
+ pszIp++;
+
+ char * pszEnd = pszIp;
+ while ((*pszEnd >= '0' && *pszEnd <= '9') || *pszEnd == '.')
+ pszEnd++;
+ *pszEnd = NULL;
+
+ if ((externIP.s_addr = inet_addr(pszIp)) == INADDR_NONE)
+ externIP.s_addr = 0;
+ }
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM) nlreply);
+ }
+ ::SetCursor(hPrevCursor);
+ return ntohl(externIP.s_addr);
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : sCreateLink
+// Type : Global
+// Parameters : pszSrvPath - ?
+// pszIndexPath - ?
+// Returns : string
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030915, 15 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+string sCreateLink(const char * pszSrvPath) {
+ char szTemp[30];
+ string sLink = DBGetString(NULL, MODULE, "ExternalSrvName", szDefaultExternalSrvName);
+ _snprintf(szTemp, sizeof(szTemp), "%d.%d.%d.%d", SplitIpAddress(dwLocalIpAddress));
+ ReplaceAll(sLink, "%LocalIP%", szTemp);
+
+ if (sLink.find("%ExternalIP%") != sLink.npos) {
+ static DWORD dwExternalIpAddressGenerated = 0;
+
+ // Get the IP again after 10 minutes
+ if (! dwExternalIpAddress || GetTickCount() - dwExternalIpAddressGenerated > 10 * 60 * 1000) {
+ dwExternalIpAddress = GetExternIP(sUrlAddress.c_str(), sPageKeyword.c_str());
+
+ dwExternalIpAddressGenerated = GetTickCount();
+ }
+
+ _snprintf(szTemp, sizeof(szTemp), "%d.%d.%d.%d", SplitIpAddress(dwExternalIpAddress));
+ ReplaceAll(sLink, "%ExternalIP%", szTemp);
+ }
+
+ _snprintf(szTemp, sizeof(szTemp), "%d", dwLocalPortUsed, szTemp);
+ ReplaceAll(sLink, "%Port%", szTemp);
+
+ string sSrvPath = pszSrvPath;
+ ReplaceAll(sSrvPath, " ", "%20");
+ ReplaceAll(sLink, "%SrvPath%", sSrvPath);
+ return sLink;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ShareNewFileDialogHook
+// Type : Global
+// Parameters : hdlg - ?
+// uiMsg - ?
+// wParam - ?
+// parameter - ?
+// Returns : UINT_PTR CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030829, 29 august 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+UINT CALLBACK ShareNewFileDialogHook(
+ HWND hDlg, // handle to child dialog box
+ UINT uiMsg, // message identifier
+ WPARAM wParam, // message parameter
+ LPARAM lParam // message parameter
+) {
+ static const char* pszShareDirStr = Translate("Share Current Directory");
+
+ static int nInit = 0;
+
+ STFileShareInfo * pstShare = (STFileShareInfo *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ switch (uiMsg) {
+ case WM_INITDIALOG: {
+ pstShare = (STFileShareInfo *)((OPENFILENAME *)lParam)->lCustData;
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, (LPARAM)pstShare);
+
+ SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, pstShare->nMaxDownloads, true);
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IPADDRESS), IPM_SETADDRESS, 0, pstShare->dwAllowedIP);
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_SETADDRESS, 0, pstShare->dwAllowedMask);
+
+ if (*pstShare->pszSrvPath)
+ nInit = 2;
+ else
+ nInit = 1;
+
+ return false;
+ }
+
+ case WM_NOTIFY: {
+ OFNOTIFY * pNotify = (OFNOTIFY*)lParam;
+ switch (pNotify->hdr.code) {
+ case CDN_FOLDERCHANGE:
+ case CDN_SELCHANGE: {
+ static char szSelection[MAX_PATH] = "";
+ HWND hWndFileDlg = GetParent(hDlg);
+
+ *szSelection = '/';
+ CommDlg_OpenSave_GetSpec(hWndFileDlg, (LPARAM)(&szSelection[1]), _MAX_PATH);
+
+ HWND hFileName = GetDlgItem(hWndFileDlg, edt1);
+ char pszFileName[MAX_PATH];
+ SendMessage(hFileName, WM_GETTEXT, MAX_PATH, (LPARAM)pszFileName);
+
+ if (strcmp(pstShare->pszSrvPath, szSelection) &&
+ strcmp(pszFileName, pszShareDirStr)) {
+ // a file was selected
+
+ // only reenable windows / set default values when a folder was selected before
+ if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] == '/') {
+ pNotify->lpOFN->Flags |= OFN_FILEMUSTEXIST;
+ EnableWindow(hFileName, TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_MAX_DOWNLOADS), TRUE);
+ SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, nDefaultDownloadLimit, true);
+ }
+ } else {
+ // a directory was selected
+ pNotify->lpOFN->Flags &= ~OFN_FILEMUSTEXIST;
+ strcpy(pNotify->lpOFN->lpstrFile, pszShareDirStr);
+ CommDlg_OpenSave_SetControlText(hWndFileDlg, edt1, pszShareDirStr);
+ EnableWindow(hFileName, FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_MAX_DOWNLOADS), FALSE);
+ SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, (UINT)-1, true);
+
+ CommDlg_OpenSave_GetFolderPath(hWndFileDlg, szSelection, MAX_PATH);
+ char* pszFolder = szSelection;
+ char* pszTmp = szSelection;
+ while (*pszTmp != '\0') {
+ if (*pszTmp == '\\' && *(pszTmp + 1))
+ pszFolder = pszTmp + 1;
+ pszTmp++;
+ }
+
+ pszTmp = strchr(szSelection, ':');
+ if (pszTmp != NULL)
+ *pszTmp = '\0';
+
+ memmove(&szSelection[1], pszFolder, strlen(pszFolder) + 1);
+ szSelection[0] = '/';
+ if (szSelection[strlen(szSelection)-1] != '/')
+ strcat(szSelection, "/");
+
+ // only write to IDC_SHARE_NAME when a file / other folder was selected before
+ if (!strcmp(szSelection, pstShare->pszSrvPath))
+ return false;
+ }
+
+ if (nInit != 0) {
+ // when the dialog is created a CDN_FOLDERCHANGE and a CDN_SELCHANGE message
+ // is posted. When the dialog is used for editting make sure the right server
+ // path (not the auto generated) is written to IDC_SHARE_NAME
+ if (nInit == 2)
+ SetDlgItemText(hDlg, IDC_SHARE_NAME, pstShare->pszSrvPath);
+
+ nInit--;
+ } else {
+ SetDlgItemText(hDlg, IDC_SHARE_NAME, szSelection);
+ }
+
+ strcpy(pstShare->pszSrvPath, szSelection);
+
+ return false;
+ }
+
+ case CDN_FILEOK: {
+ GetDlgItemText(hDlg, IDC_SHARE_NAME, pstShare->pszSrvPath, _MAX_PATH);
+
+ char* pszTmp = strstr(pstShare->pszRealPath, pszShareDirStr);
+ if (pszTmp) {
+ *pszTmp = '\0';
+ if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] != '/')
+ strcat(pstShare->pszSrvPath, "/");
+ } else {
+ if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] == '/')
+ pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] = '\0';
+ }
+
+ BOOL bTranslated = false;
+ pstShare->nMaxDownloads = GetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, &bTranslated, true);
+ if (pstShare->nMaxDownloads <= 0 && pstShare->nMaxDownloads != -1)
+ bTranslated = false;
+
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IPADDRESS), IPM_GETADDRESS, 0, (LPARAM)&(pstShare->dwAllowedIP));
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_GETADDRESS, 0, (LPARAM)&(pstShare->dwAllowedMask));
+
+ //if( ! (pstShare->dwAllowedIP & pstShare->dwAllowedMask)
+
+ if (!bTranslated || (strlen(pstShare->pszSrvPath) <= 0)) {
+ SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 1);
+ return true;
+ }
+ return false;
+ }
+ }
+ break;
+ }
+
+ case WM_DROPFILES: {
+ HDROP hDrop = (HDROP)wParam;
+ char szDropedFile[MAX_PATH];
+ int nLen = DragQueryFile(hDrop, 0, szDropedFile, sizeof(szDropedFile));
+ if (nLen > 0) {
+ char * psz = strrchr(szDropedFile, '\\');
+ if (psz) {
+ char oldNext = psz[1];
+ psz[1] = '\0';
+ // Fill in the directory
+ SendMessage(GetParent(hDlg), CDM_SETCONTROLTEXT, edt1, (LPARAM)szDropedFile);
+ // click on the OK button. to move to dir
+ SendMessage(GetParent(hDlg), WM_COMMAND, IDOK, 0);
+ psz[1] = oldNext;
+ // Fill in the file name this will cause a call to the CDN_SELCHANGE
+ // and there by set the share name
+ SendMessage(GetParent(hDlg), CDM_SETCONTROLTEXT, edt1, (LPARAM)&psz[1]);
+ }
+ }
+ DragFinish(hDrop);
+ return 0;
+ }
+
+ case WM_COMMAND: {
+ switch (LOWORD(wParam)) {
+ case IDC_TOGGLE_MASK: {
+ DWORD dwCur;
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_GETADDRESS, 0, (LPARAM)&dwCur);
+ SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_SETADDRESS, 0, (LPARAM) dwCur == 0xFFFFFFFF ? 0 : 0xFFFFFFFF);
+ return TRUE;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bShowShareNewFileDlg
+// Type : Global
+// Parameters : pstNewShare - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031011, 11 oktober 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+bool bShowShareNewFileDlg(HWND hwndOwner, STFileShareInfo * pstNewShare) {
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0");
+
+ ofn.lpstrFile = pstNewShare->pszRealPath;
+ ofn.nMaxFile = pstNewShare->dwMaxRealPath;
+
+ char szInitialDir[MAX_PATH];
+ if (ofn.lpstrFile[strlen(ofn.lpstrFile)-1] == '\\') {
+ ofn.lpstrInitialDir = szInitialDir;
+ strcpy(szInitialDir, ofn.lpstrFile);
+ *ofn.lpstrFile = '\0';
+ }
+
+
+ ofn.Flags = /*OFN_DONTADDTORECENT |*/ OFN_NOREADONLYRETURN
+ | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLESIZING
+ | OFN_ALLOWMULTISELECT;
+ ofn.hwndOwner = hwndOwner;
+ ofn.hInstance = hInstance;
+ ofn.lpstrTitle = TranslateT("Specify a file to share");
+ ofn.lpTemplateName = MAKEINTRESOURCE(IDD_NEW_SHARE_PROPERTIES);
+ ofn.lpfnHook = (LPOFNHOOKPROC)ShareNewFileDialogHook;
+ ofn.lCustData = (LPARAM)pstNewShare;
+
+ if (!GetOpenFileName(&ofn)) {
+ DWORD dwError = CommDlgExtendedError();
+ if (dwError) {
+ char szTemp[200];
+ _snprintf(szTemp, sizeof(szTemp), "Failed to create File Open dialog the error returned was %d", dwError);
+ MessageBox(NULL, szTemp, MSG_BOX_TITEL, MB_OK);
+ }
+ return false;
+ }
+
+ if (strchr(pstNewShare->pszSrvPath, '"')) {
+ // multiple files selected
+ // Serverpath: "file1" "file2" "file3"
+ // move one after the other to front of string (in place)
+ // terminate it with \0 append to realpath and add the share
+ char* pszFileNamePos = pstNewShare->pszSrvPath;
+ char* szRealDirectoryEnd =
+ &pstNewShare->pszRealPath[strlen(pstNewShare->pszRealPath)];
+
+ *szRealDirectoryEnd = '\\';
+ szRealDirectoryEnd++;
+
+ while (pszFileNamePos && *pszFileNamePos) {
+ pszFileNamePos = strchr(pszFileNamePos, '"');
+ if (pszFileNamePos) {
+ pszFileNamePos++;
+ char* start = pszFileNamePos;
+ pszFileNamePos = strchr(pszFileNamePos, '"');
+ if (pszFileNamePos) {
+ char* end = pszFileNamePos;
+ memmove(pstNewShare->pszSrvPath+1, start, end - start);
+ *(end - (start - (pstNewShare->pszSrvPath+1)) ) = '\0';
+
+ int realPathLen = szRealDirectoryEnd - pstNewShare->pszRealPath;
+ strncpy(szRealDirectoryEnd, pstNewShare->pszSrvPath+1,
+ pstNewShare->dwMaxRealPath - realPathLen - 1);
+ pstNewShare->pszRealPath[pstNewShare->dwMaxRealPath] = '\0';
+
+ if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)pstNewShare)) {
+ MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK);
+ return false;
+ }
+ pszFileNamePos++;
+ }
+ }
+ }
+
+ } else {
+ if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)pstNewShare)) {
+ MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK);
+ return false;
+ }
+ }
+
+ UpdateStatisticsView();
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : UpdateStatisticView
+// Type : Global
+// Parameters : hwndDlg - ?
+// false - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030904, 04 september 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+void UpdateStatisticView(HWND hwndDlg, bool bRefressUsersOnly = false) {
+ HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS);
+ bool bShowHiddenShares = IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDDENSHARES) == BST_CHECKED;
+
+ if (! bRefressUsersOnly)
+ ListView_DeleteAllItems(hShareList);
+ ListView_DeleteAllItems(hUserList);
+
+ CLFileShareListAccess scCrit;
+
+ char szTmp[50];
+ in_addr stAddr;
+
+ bool bAutoRefress = false;
+
+ LVITEM sItem = { 0 };
+ int nShareNr = 0;
+ int nUserNr = 0;
+ for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) {
+ if (! bRefressUsersOnly &&
+ (bShowHiddenShares || !strstr(pclCur->st.pszRealPath, "\\@"))) {
+ sItem.mask = LVIF_TEXT /*| LVIF_PARAM | LVIF_IMAGE*/;
+ sItem.iItem = nShareNr;
+ sItem.iSubItem = 0;
+ sItem.pszText = pclCur->st.pszSrvPath;
+ ListView_InsertItem(hShareList, &sItem);
+
+
+ _snprintf(szTmp, sizeof(szTmp), "%d", pclCur->st.nMaxDownloads);
+ sItem.iSubItem = 1;
+ sItem.pszText = szTmp;
+ ListView_SetItem(hShareList, &sItem);
+
+ stAddr.S_un.S_addr = htonl(pclCur->st.dwAllowedIP);
+ sItem.iSubItem = 2;
+ sItem.pszText = inet_ntoa(stAddr);
+ ListView_SetItem(hShareList, &sItem);
+
+ stAddr.S_un.S_addr = htonl(pclCur->st.dwAllowedMask);
+ sItem.iSubItem = 3;
+ sItem.pszText = inet_ntoa(stAddr);
+ ListView_SetItem(hShareList, &sItem);
+
+ sItem.iSubItem = 4;
+ sItem.pszText = pclCur->st.pszRealPath;
+ ListView_SetItem(hShareList, &sItem);
+
+ nShareNr++;
+ }
+
+ for (CLShareUser * pclCurUser = pclCur->pclGetUsers() ; pclCurUser ; pclCurUser = pclCurUser->pclNext) {
+ bAutoRefress = true;
+
+ sItem.mask = LVIF_TEXT /*| LVIF_PARAM | LVIF_IMAGE*/;
+ sItem.iItem = nUserNr;
+ sItem.iSubItem = 0;
+ sItem.pszText = pclCurUser->szCurrentDLSrvPath; //pclCur->st.pszSrvPath;
+ ListView_InsertItem(hUserList, &sItem);
+
+ sItem.iSubItem = 1;
+ sItem.pszText = inet_ntoa(pclCurUser->stAddr);
+ ListView_SetItem(hUserList, &sItem);
+
+ sItem.iSubItem = 2;
+ sItem.pszText = (char*)pclCurUser->pszCustomInfo();
+ ListView_SetItem(hUserList, &sItem);
+
+ if (pclCurUser->dwTotalSize) {
+ _snprintf(szTmp, sizeof(szTmp), "%d %%", (pclCurUser->dwCurrentDL * 100) / pclCurUser->dwTotalSize);
+ } else {
+ strcpy(szTmp, "? %%");
+ }
+ sItem.iSubItem = 3;
+ sItem.pszText = szTmp;
+ ListView_SetItem(hUserList, &sItem);
+
+ DWORD dwSpeed = pclCurUser->dwGetDownloadSpeed();
+ if (dwSpeed > 10000) {
+ dwSpeed += 512; // make sure we round ot down correctly.
+ dwSpeed /= 1024;
+ _snprintf(szTmp, sizeof(szTmp), "%d KB/Sec", dwSpeed);
+ } else {
+ _snprintf(szTmp, sizeof(szTmp), "%d B/Sec", dwSpeed);
+ }
+ sItem.iSubItem = 4;
+ sItem.pszText = szTmp;
+ ListView_SetItem(hUserList, &sItem);
+
+ nUserNr++;
+ }
+ }
+
+ if (bLastAutoRefress != bAutoRefress) {
+ if (bAutoRefress)
+ SetTimer(hwndDlg, 0, 1000, NULL);
+ else
+ KillTimer(hwndDlg, 0);
+ bLastAutoRefress = bAutoRefress;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SetWindowsCtrls
+// Type : Global
+// Parameters : hwndDlg - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030904, 04 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void SetWindowsCtrls(HWND hwndDlg) {
+ RECT rNewSize;
+ GetClientRect(hwndDlg, &rNewSize);
+
+ const int nSpacing = 8;
+ int nCtrlHight = (rNewSize.bottom - (nSpacing * 3)) / 3 - 20;
+
+ SetWindowPos(GetDlgItem(hwndDlg, IDC_CURRENT_SHARES), 0 ,
+ nSpacing,
+ 35,
+ rNewSize.right - (nSpacing * 2) ,
+ nCtrlHight*2,
+ SWP_NOZORDER);
+
+ SetWindowPos(GetDlgItem(hwndDlg, IDC_CURRENT_USERS), 0 ,
+ nSpacing ,
+ (nSpacing * 2) + nCtrlHight*2 + 25,
+ rNewSize.right - (nSpacing * 2) ,
+ nCtrlHight + 35,
+ SWP_NOZORDER);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : DlgProcStatsticView
+// Type : Global
+// Parameters : hwndDlg - ?
+// msg - ?
+// wParam - ?
+// lParam - ?
+// Returns : static BOOL CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030904, 04 september 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+static INT_PTR CALLBACK DlgProcStatsticView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ switch (msg) {
+ case WM_INITDIALOG: {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG,
+ (LPARAM)LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)));
+
+ TranslateDialogDefault(hwndDlg);
+
+ HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS);
+
+ { // init adv. win styles
+ DWORD dw = ListView_GetExtendedListViewStyle(hShareList);
+ dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
+ ListView_SetExtendedListViewStyle(hShareList, dw /*| LVS_EX_LABELTIP*/);
+ }
+ { // init adv. win styles
+ DWORD dw = ListView_GetExtendedListViewStyle(hUserList);
+ dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
+ ListView_SetExtendedListViewStyle(hUserList, dw /*| LVS_EX_LABELTIP*/);
+ }
+
+ LVCOLUMN cCol = { 0 };
+ cCol.mask = LVCF_TEXT | LVCF_WIDTH;
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx1", 126);
+ cCol.pszText = TranslateT("Share name");
+ ListView_InsertColumn(hShareList, 0, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx2", 48);
+ cCol.pszText = TranslateT("Max Downloads");
+ ListView_InsertColumn(hShareList, 1, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx3", 96);
+ cCol.pszText = TranslateT("Allowed IP");
+ ListView_InsertColumn(hShareList, 2, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx4", 104);
+ cCol.pszText = TranslateT("Allowed Mask");
+ ListView_InsertColumn(hShareList, 3, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx5", 252);
+ cCol.pszText = TranslateT("Real path");
+ ListView_InsertColumn(hShareList, 4, &cCol);
+
+ cCol.mask = LVCF_TEXT | LVCF_WIDTH;
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx6", 142);
+ cCol.pszText = TranslateT("Share name");
+ ListView_InsertColumn(hUserList, 0, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx7", 111);
+ cCol.pszText = TranslateT("User");
+ ListView_InsertColumn(hUserList, 1, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx8", 100);
+ cCol.pszText = TranslateT("Agent");
+ ListView_InsertColumn(hUserList, 2, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx9", 100);
+ cCol.pszText = TranslateT("Completed");
+ ListView_InsertColumn(hUserList, 3, &cCol);
+ cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx10", 100);
+ cCol.pszText = TranslateT("Speed");
+ ListView_InsertColumn(hUserList, 4, &cCol);
+
+ bool b = db_get_b(NULL, MODULE, "StatWnd_ShowHidden", 0) != 0;
+ CheckDlgButton(hwndDlg, IDC_SHOWHIDDENSHARES, b ? BST_CHECKED : BST_UNCHECKED);
+
+ bLastAutoRefress = false;
+ UpdateStatisticView(hwndDlg);
+ Utils_RestoreWindowPosition(hwndDlg, 0, MODULE, "StatWnd_");
+ SetWindowsCtrls(hwndDlg);
+ return TRUE;
+ }
+
+ case WM_SIZE:
+ case WM_SIZING: {
+ SetWindowsCtrls(hwndDlg);
+ return TRUE;
+ }
+
+ case WM_TIMER: {
+ UpdateStatisticView(hwndDlg, true);
+ return TRUE;
+ }
+
+ case WM_RELOAD_STATISTICS: {
+ UpdateStatisticView(hwndDlg);
+ return TRUE;
+ }
+
+ case WM_DESTROY: {
+ hwndStatsticView = NULL;
+ return 0;
+ }
+
+ case WM_DROPFILES: {
+ HDROP hDrop = (HDROP)wParam;
+ char szDropedFile[MAX_PATH];
+ char szServPath[MAX_PATH] = {0};
+
+ int nLen = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
+ for (int i = 0; i < nLen; i++) {
+ DragQueryFile(hDrop, i, szDropedFile, sizeof(szDropedFile));
+
+ STFileShareInfo stNewShare = {0};
+ stNewShare.lStructSize = sizeof(STFileShareInfo);
+ stNewShare.nMaxDownloads = nDefaultDownloadLimit;
+ stNewShare.pszRealPath = szDropedFile;
+ stNewShare.dwMaxRealPath = sizeof(szDropedFile);
+ stNewShare.pszSrvPath = szServPath;
+ stNewShare.dwMaxSrvPath = sizeof(szServPath);
+
+ szServPath[0] = '/';
+ char* fileName = strrchr(szDropedFile, '\\');
+ if (fileName)
+ strncpy(&szServPath[1], fileName+1, MAX_PATH-2);
+
+ if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&stNewShare)) {
+ MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK);
+ return false;
+ }
+ }
+
+ UpdateStatisticsView();
+ DragFinish(hDrop);
+ return 0;
+ }
+
+ case WM_CONTEXTMENU: {
+ if (wParam != (WPARAM)GetDlgItem(hwndDlg, IDC_CURRENT_SHARES))
+ return FALSE;
+
+ HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ if (ListView_GetNextItem(hShareList, -1, LVIS_SELECTED) == -1)
+ return FALSE;
+
+ HMENU hMainMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
+ if (hMainMenu) {
+ HMENU hMenu = GetSubMenu(hMainMenu, 0);
+
+ POINT pt;
+ pt.x = (short)LOWORD(lParam);
+ pt.y = (short)HIWORD(lParam);
+ if (pt.x == -1 && pt.y == -1) {
+ HWND hMapUser = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ int nFirst = ListView_GetNextItem(hMapUser, -1, LVNI_FOCUSED);
+ if (nFirst >= 0) {
+ ListView_GetItemPosition(hMapUser, nFirst, &pt);
+ }
+
+ if (pt.y < 16)
+ pt.y = 16;
+ else {
+ RECT rUserList;
+ GetClientRect(hMapUser, &rUserList);
+ if (pt.y > rUserList.bottom - 16)
+ pt.y = rUserList.bottom - 16;
+ else
+ pt.y += 8;
+ }
+ pt.x = 8;
+ ClientToScreen(hMapUser, &pt);
+ }
+
+ TranslateMenu(hMenu);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON,
+ pt.x, pt.y, 0, hwndDlg, NULL);
+
+ DestroyMenu(hMainMenu);
+ }
+ return TRUE;
+ }
+
+ case WM_COMMAND: {
+ HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ char szTmp[MAX_PATH];
+ LVITEM sItem = { 0 };
+ sItem.mask = LVIF_TEXT;
+ sItem.pszText = szTmp;
+ sItem.cchTextMax = sizeof(szTmp);
+
+
+ switch (LOWORD(wParam)) {
+ case IDC_SHOWHIDDENSHARES: {
+ UpdateStatisticView(hwndDlg);
+ return TRUE;
+ }
+
+ case ID_SHARELIST_NEWSHARE: {
+ CallService(MS_SHARE_NEW_FILE, 0, (long)hwndDlg);
+ return TRUE;
+ }
+
+ case ID_SHARELIST_EDITSHARE:
+ case ID_SHARELIST_REMOVESHARE: {
+ STFileShareInfo stShareInfo = {0};
+ stShareInfo.lStructSize = sizeof(STFileShareInfo);
+ stShareInfo.pszSrvPath = szTmp;
+ stShareInfo.dwMaxSrvPath = sizeof(szTmp);
+
+ sItem.iItem = ListView_GetNextItem(hShareList, -1, LVIS_SELECTED);
+ while (sItem.iItem != -1) {
+ if (ListView_GetItem(hShareList, &sItem)) {
+ if (LOWORD(wParam) == ID_SHARELIST_REMOVESHARE) {
+ CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&stShareInfo);
+ } else {
+ char szRealPath[MAX_PATH];
+ stShareInfo.pszRealPath = szRealPath;
+ stShareInfo.dwMaxRealPath = sizeof(szRealPath);
+ CallService(MS_HTTP_GET_SHARE, 0, (LPARAM)&stShareInfo);
+ bShowShareNewFileDlg(hwndDlg, &stShareInfo);
+ }
+ }
+ sItem.iItem = ListView_GetNextItem(hShareList, sItem.iItem, LVIS_SELECTED);
+ }
+ UpdateStatisticView(hwndDlg);
+ return TRUE;
+ }
+
+ case ID_SHARELIST_OPEN:
+ case ID_SHARELIST_COPYLINK: {
+ sItem.iItem = ListView_GetNextItem(hShareList, -1, LVIS_SELECTED);
+ if (sItem.iItem != -1) {
+ if (ListView_GetItem(hShareList, &sItem)) {
+ string sLink = sCreateLink(sItem.pszText);
+ if (sLink.size() <= 0) {
+ MessageBox(hwndDlg, _T("Selected link size is 0"), MSG_BOX_TITEL, MB_OK);
+ return TRUE;
+ }
+
+ if (LOWORD(wParam) == ID_SHARELIST_COPYLINK) {
+ if (!OpenClipboard(hwndDlg)) {
+ MessageBox(hwndDlg, _T("Failed to get access to clipboard"), MSG_BOX_TITEL, MB_OK);
+ return TRUE;
+ }
+
+ if (!EmptyClipboard()) {
+ MessageBox(hwndDlg, _T("Failed to get close the clipboard"), MSG_BOX_TITEL, MB_OK);
+ return TRUE;
+ }
+
+ HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, sLink.size() + 1);
+ // Lock the handle and copy the text to the buffer.
+ char * lptstrCopy = (char *)GlobalLock(hglbCopy);
+ strcpy(lptstrCopy, sLink.c_str());
+ GlobalUnlock(hglbCopy);
+
+ // Place the handle on the clipboard.
+
+ HANDLE hMyData = SetClipboardData(CF_TEXT, hglbCopy);
+ if (! hMyData)
+ MessageBox(hwndDlg, _T("Failed to set clipboard data"), MSG_BOX_TITEL, MB_OK);
+
+ CloseClipboard();
+ } else {
+ CallService(MS_UTILS_OPENURL, 0, (LPARAM)(const char*)sLink.c_str());
+ }
+ } else {
+ MessageBox(hwndDlg, "ListView_GetItem failed", MSG_BOX_TITEL, MB_OK);
+ }
+ } else {
+ MessageBox(hwndDlg, Translate("No share selected"), MSG_BOX_TITEL, MB_OK);
+ }
+ return TRUE;
+ }
+ /*
+ case IDCANCEL:
+ case IDOK:
+ DestroyWindow(hwndDlg);
+ return TRUE;*/
+ }
+ break;
+ }
+
+ case WM_CLOSE: {
+ HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES);
+ HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS);
+
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx1", (WORD)ListView_GetColumnWidth(hShareList, 0));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx2", (WORD)ListView_GetColumnWidth(hShareList, 1));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx3", (WORD)ListView_GetColumnWidth(hShareList, 2));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx4", (WORD)ListView_GetColumnWidth(hShareList, 3));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx5", (WORD)ListView_GetColumnWidth(hShareList, 4));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx6", (WORD)ListView_GetColumnWidth(hUserList, 0));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx7", (WORD)ListView_GetColumnWidth(hUserList, 1));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx8", (WORD)ListView_GetColumnWidth(hUserList, 2));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx9", (WORD)ListView_GetColumnWidth(hUserList, 3));
+ DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx10", (WORD)ListView_GetColumnWidth(hUserList, 4));
+
+ bool b = IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDDENSHARES) == BST_CHECKED;
+ db_set_b(NULL, MODULE, "StatWnd_ShowHidden", b);
+
+ Utils_SaveWindowPosition(hwndDlg, 0, MODULE, "StatWnd_");
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+ //return DefDlgProc( hwndDlg, msg, wParam, lParam );
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SendLinkToUser
+// Type : Global
+// Parameters : wParam - (WPARAM)(HANDLE)hContact
+// lParam - ?
+// Returns : static int
+// Description : Send the link to the given contact
+//
+// References : -
+// Remarks : -
+// Created : 030826, 26 august 2003
+// Developer : Sérgio Rolanski
+/////////////////////////////////////////////////////////////////////
+
+void SendLinkToUser(WPARAM wParam, char *pszSrvPath) {
+ string sLink = sCreateLink(pszSrvPath);
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)wParam, (LPARAM)sLink.c_str());
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : nShareNewFile
+// Type : Global
+// Parameters : wParam - (WPARAM)(HANDLE)hContact
+// lParam - ?
+// Returns : static int
+
+// Description : Called when user selects my menu item
+//
+// References : -
+// Remarks : -
+// Created : 030826, 26 august 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+static INT_PTR nShareNewFile(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+
+ // used to be _MAX_PATH
+ // changed it since selecting multiple files requires a bigger buffer
+ char szNewFile[10000] = {0};
+ char szSrvPath[10000] = {0};
+
+ STFileShareInfo stNewShare = {0};
+ stNewShare.lStructSize = sizeof(STFileShareInfo);
+ stNewShare.nMaxDownloads = 1;
+ stNewShare.pszRealPath = szNewFile;
+ stNewShare.dwMaxRealPath = sizeof(szNewFile);
+ stNewShare.pszSrvPath = szSrvPath;
+ stNewShare.dwMaxSrvPath = sizeof(szSrvPath);
+
+ if (hContact) {
+ // Try to locate an IP address.
+ DBVARIANT dbv = {0};
+ if (! DBGetContactSetting(hContact, "Protocol", "p", &dbv)) {
+ if (dbv.type == DBVT_ASCIIZ) {
+ stNewShare.dwAllowedIP = db_get_dw(hContact, dbv.pszVal, "IP", 0);
+ if (! stNewShare.dwAllowedIP)
+ stNewShare.dwAllowedIP = db_get_dw(hContact, dbv.pszVal, "RealIP", 0);
+ if (! stNewShare.dwAllowedIP)
+ stNewShare.dwAllowedIP = db_get_dw(hContact, MODULE, "LastUsedIP", 0);
+ }
+ }
+ DBFreeVariant(&dbv);
+
+ stNewShare.dwAllowedMask = db_get_dw(hContact, MODULE, "LastUsedMask", 0);
+ }
+ if (! stNewShare.dwAllowedMask) {
+ if (stNewShare.dwAllowedIP)
+ stNewShare.dwAllowedMask = 0xFFFFFFFF;
+ else
+ stNewShare.dwAllowedMask = 0;
+ }
+
+ if (! bShowShareNewFileDlg((HWND)(lParam ? lParam : CallService(MS_CLUI_GETHWND, 0, 0)), &stNewShare))
+ return 0;
+
+ if (stNewShare.dwAllowedIP)
+ db_set_dw(hContact, MODULE, "LastUsedIP", stNewShare.dwAllowedIP);
+ else
+ db_unset(hContact, MODULE, "LastUsedIP");
+
+ if (stNewShare.dwAllowedMask && stNewShare.dwAllowedMask != 0xFFFFFFFF)
+ db_set_dw(hContact, MODULE, "LastUsedMask", stNewShare.dwAllowedMask);
+ else
+ db_unset(hContact, MODULE, "LastUsedMask");
+
+ SendLinkToUser((WPARAM)hContact, stNewShare.pszSrvPath);
+ return 0;
+}
+
+
+static INT_PTR nShowStatisticsView(WPARAM /*wParam*/, LPARAM /*lParam*/) {
+ if (hwndStatsticView) {
+ BringWindowToTop(hwndStatsticView);
+ return 0;
+ }
+ hwndStatsticView = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_STATISTICS_VIEW), NULL, DlgProcStatsticView, (LPARAM)NULL);
+ ShowWindow(hwndStatsticView, SW_SHOWNORMAL);
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : OptionsDlgProc
+// Type : Global
+// Parameters : hwndDlg - ?
+// msg - ?
+// wParam - ?
+// lParam - ?
+// Returns : static BOOL CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030911, 11 september 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ switch (msg) {
+ case WM_INITDIALOG: {
+ string sDefExt = DBGetString(NULL, MODULE, "ExternalSrvName", szDefaultExternalSrvName);
+ SetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, sDefExt.c_str());
+
+ bool b = db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0;
+ CheckDlgButton(hwndDlg, IDC_ADD_STATISTICS_MENU_ITEM, b ? BST_CHECKED : BST_UNCHECKED);
+
+ b = db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1) != 0;
+ CheckDlgButton(hwndDlg, IDC_ACCEPT_COM_MENU_ITEM, b ? BST_CHECKED : BST_UNCHECKED);
+
+ b = db_get_b(NULL, MODULE, "WriteLogFile", 0) != 0;
+ CheckDlgButton(hwndDlg, IDC_WRITE_LOG_FILE, b ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_SHOW_POPUPS, bShowPopups ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_LIMIT_ONLY_WHEN_ONLINE, bLimitOnlyWhenOnline ? BST_CHECKED : BST_UNCHECKED);
+
+
+ {// Url Address
+ SetDlgItemText(hwndDlg, IDC_URL_ADDRESS, sUrlAddress.c_str());
+ HWND hComboBox = GetDlgItem(hwndDlg, IDC_URL_ADDRESS);
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://checkip.dyndns.org"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://checkip.dyndns.org:8245/"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://dynamic.zoneedit.com/checkip.html"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://ipdetect.dnspark.com/"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://update.dynu.com/basic/ipcheck.asp"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://www.dnsart.com/myip.php"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://www.dnsart.com:7777/myip.php"));
+ }
+
+ {// Page keyword
+ SetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, sPageKeyword.c_str());
+ HWND hComboBox = GetDlgItem(hwndDlg, IDC_PAGE_KEYWORD);
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)"");
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("Current IP Address: "));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("Current Address: "));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("IP Adress: "));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("You are browsing from"));
+ SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("<HTML><BODY>"));
+ }
+
+ SetDlgItemInt(hwndDlg, IDC_MAX_SPEED, nMaxUploadSpeed >> 10, true);
+ SetDlgItemInt(hwndDlg, IDC_MAX_CONN_TOTAL, nMaxConnectionsTotal, true);
+ SetDlgItemInt(hwndDlg, IDC_MAX_CONN_PER_USER, nMaxConnectionsPerUser, true);
+ SetDlgItemInt(hwndDlg, IDC_DEFAULT_DOWNLOAD_LIMIT, nDefaultDownloadLimit, true);
+
+ indexCreationMode =
+ (eIndexCreationMode)db_get_b(NULL, MODULE, "IndexCreationMode", 3);
+
+ switch (indexCreationMode) {
+ case INDEX_CREATION_HTML:
+ CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_HTML);
+ break;
+ case INDEX_CREATION_XML:
+ CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_XML);
+ break;
+ case INDEX_CREATION_DETECT:
+ CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_DETECT);
+ break;
+ default: // INDEX_CREATION_DISABLE
+ CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_OFF);
+ break;
+ }
+
+ TranslateDialogDefault(hwndDlg);
+ return TRUE;
+ }
+ case WM_COMMAND: {
+ switch (LOWORD(wParam)) {
+ case IDC_MAX_SPEED:
+ case IDC_MAX_CONN_PER_USER:
+ case IDC_MAX_CONN_TOTAL:
+ case IDC_EXTERNAL_SRV_NAME: {
+ if (HIWORD(wParam) == EN_CHANGE)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ }
+ case IDC_URL_ADDRESS:
+ case IDC_PAGE_KEYWORD: {
+ /*if( !bWindowTextSet )
+ return TRUE;*/
+
+ if (HIWORD(wParam) == CBN_EDITUPDATE || HIWORD(wParam) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+
+ case IDC_INDEX_HTML:
+ case IDC_INDEX_OFF:
+ case IDC_INDEX_XML:
+ case IDC_INDEX_DETECT:
+ case IDC_LIMIT_ONLY_WHEN_ONLINE:
+ case IDC_SHOW_POPUPS:
+ case IDC_WRITE_LOG_FILE:
+ case IDC_ADD_STATISTICS_MENU_ITEM:
+ case IDC_ACCEPT_COM_MENU_ITEM: {
+ if (HIWORD(wParam) == BN_CLICKED) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case IDC_EXTERNAL_SRV_DEFAULT: {
+ if (HIWORD(wParam) == BN_CLICKED) {
+ SetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, szDefaultExternalSrvName);
+ SetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szDefaultUrlAddress);
+ SetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szDefaultPageKeyword);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ }
+ case IDC_OPEN_LOG: {
+ bOpenLogFile();
+ return TRUE;
+ }
+ case IDC_TEST_EXTERNALIP: {
+ char szUrl[ 500 ];
+ char szKeyWord[ 1000 ];
+ GetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szUrl, sizeof(szUrl));
+ GetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szKeyWord, sizeof(szKeyWord));
+ DWORD dwExternalIP = GetExternIP(szUrl, szKeyWord);
+
+ _snprintf(szKeyWord, sizeof(szKeyWord), Translate("You external ip was detected as %d.%d.%d.%d\r\nby: %s") ,
+ SplitIpAddress(dwExternalIP) ,
+ szUrl);
+ MessageBox(hwndDlg, szKeyWord, MSG_BOX_TITEL, MB_OK);
+ }
+ }
+ break;
+ }
+ case WM_NOTIFY: {
+ NMHDR * p = ((LPNMHDR)lParam);
+ switch (p->code) {
+ case PSN_APPLY: {
+ char szTemp[ 500 ];
+ if (GetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, szTemp, sizeof(szTemp)))
+ db_set_s(NULL, MODULE, "ExternalSrvName", szTemp);
+
+ bool b = db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0;
+ bool bNew = IsDlgButtonChecked(hwndDlg, IDC_ADD_STATISTICS_MENU_ITEM) == BST_CHECKED;
+ if (b != bNew) {
+ db_set_b(NULL, MODULE, "AddStatisticsMenuItem", bNew);
+ MessageBox(hwndDlg, TranslateT("You need to restart miranda to change the main menu"), MSG_BOX_TITEL, MB_OK);
+ }
+
+ b = db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1) != 0;
+ bNew = IsDlgButtonChecked(hwndDlg, IDC_ACCEPT_COM_MENU_ITEM) == BST_CHECKED;
+ if (b != bNew) {
+ db_set_b(NULL, MODULE, "AddAcceptConMenuItem", bNew);
+ MessageBox(hwndDlg, TranslateT("You need to restart miranda to change the main menu"), MSG_BOX_TITEL, MB_OK);
+ }
+
+ bNew = IsDlgButtonChecked(hwndDlg, IDC_WRITE_LOG_FILE) == BST_CHECKED;
+ db_set_b(NULL, MODULE, "WriteLogFile", bNew);
+
+ bShowPopups = IsDlgButtonChecked(hwndDlg, IDC_SHOW_POPUPS) == BST_CHECKED;
+ db_set_b(NULL, MODULE, "ShowPopups", bShowPopups);
+
+ GetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szTemp, sizeof(szTemp));
+ sUrlAddress = szTemp;
+ db_set_s(NULL, MODULE, "UrlAddress", sUrlAddress.c_str());
+
+ GetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szTemp, sizeof(szTemp));
+ sPageKeyword = szTemp;
+ db_set_s(NULL, MODULE, "PageKeyword", sPageKeyword.c_str());
+ dwExternalIpAddress = 0;
+
+ BOOL bTranslated = false;
+ int nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_SPEED, &bTranslated, true);
+ if (bTranslated) {
+ nMaxUploadSpeed = nTemp << 10;
+ db_set_dw(NULL, MODULE, "MaxUploadSpeed", nMaxUploadSpeed);
+ }
+
+ nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_CONN_TOTAL, &bTranslated, true);
+ if (bTranslated) {
+ nMaxConnectionsTotal = nTemp;
+ db_set_dw(NULL, MODULE, "MaxConnectionsTotal", nMaxConnectionsTotal);
+ }
+
+ nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_CONN_PER_USER, &bTranslated, true);
+ if (bTranslated) {
+ nMaxConnectionsPerUser = nTemp;
+ db_set_dw(NULL, MODULE, "MaxConnectionsPerUser", nMaxConnectionsPerUser);
+ }
+
+ nTemp = GetDlgItemInt(hwndDlg, IDC_DEFAULT_DOWNLOAD_LIMIT, &bTranslated, true);
+ if (bTranslated) {
+ nDefaultDownloadLimit = nTemp;
+ db_set_dw(NULL, MODULE, "DefaultDownloadLimit", nDefaultDownloadLimit);
+ }
+
+ bLimitOnlyWhenOnline = IsDlgButtonChecked(hwndDlg, IDC_LIMIT_ONLY_WHEN_ONLINE) == BST_CHECKED;
+ db_set_b(NULL, MODULE, "LimitOnlyWhenOnline", bLimitOnlyWhenOnline);
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_HTML) == BST_CHECKED ||
+ IsDlgButtonChecked(hwndDlg, IDC_INDEX_DETECT) == BST_CHECKED) {
+ if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_HTML) == BST_CHECKED)
+ indexCreationMode = INDEX_CREATION_HTML;
+ else
+ indexCreationMode = INDEX_CREATION_DETECT;
+
+ if (!LoadIndexHTMLTemplate()) {
+ CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_XML, IDC_INDEX_OFF);
+ indexCreationMode = INDEX_CREATION_DISABLE;
+ }
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_XML) == BST_CHECKED) {
+ FreeIndexHTMLTemplate();
+ indexCreationMode = INDEX_CREATION_XML;
+ } else {
+ FreeIndexHTMLTemplate();
+ indexCreationMode = INDEX_CREATION_DISABLE;
+ }
+
+ db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode);
+
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : OptionsInitialize
+// Type : Global
+// Parameters : wParam - ?
+// LPARAM - ?
+// Returns : int
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030911, 11 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+int OptionsInitialize(WPARAM wParam, LPARAM /*lParam*/) {
+ OPTIONSDIALOGPAGE odp;
+ /*
+ bWindowTextSet = FALSE;
+ bUnaplyedChanges = FALSE;
+ */
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 900000000;
+ odp.hInstance = hInstance;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_HTTP_SERVER);
+ odp.flags = ODPF_BOLDGROUPS|ODPF_TCHAR;
+ odp.ptszTitle = LPGENT("HTTP Server");
+ odp.ptszGroup = LPGENT("Network");
+ odp.pfnDlgProc = OptionsDlgProc;
+ Options_AddPage(wParam,&odp);
+ return 0;
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : MainThreadCallback
+// Type : Global
+// Parameters : dwParam - ?
+// Returns : void CALLBACK
+// Description : Called from main thread.
+// Because MS_POPUP_ADDPOPUP may only be called from that
+// ShowPopupWindow activates this method via APC
+// References : -
+// Remarks : -
+// Created : 030902, 02 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void CALLBACK MainThreadCallback(ULONG_PTR dwParam) {
+ POPUPDATA * pclData = (POPUPDATA *)dwParam;
+ if (db_get_b(NULL, MODULE, "WriteLogFile", 0) != 0) {
+ LogEvent(pclData->lpzContactName, pclData->lpzText);
+ }
+ CallService(MS_POPUP_ADDPOPUP, (WPARAM)pclData, 0);
+ delete pclData;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : PopupWindowProc
+// Type : Global
+// Parameters : hWnd - ?
+// message - ?
+// wParam - ?
+// lParam - ?
+// Returns : LRESULT CALLBACK
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031011, 11 oktober 2003
+// Developer : KN, Houdini
+/////////////////////////////////////////////////////////////////////
+
+void CALLBACK OpenStatisticViewFromPopupProc(ULONG_PTR /* dwParam */) {
+ nShowStatisticsView(0, 0);
+}
+
+LRESULT CALLBACK PopupWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ PUGetPluginData(hWnd);
+ //HANDLE hData = (HANDLE)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, (LPARAM)&hData);
+
+ switch (message) {
+ //case WM_LBUTTONUP:
+ //case WM_LBUTTONDBLCLK: // These don't work I can't undestande why !!
+ case WM_LBUTTONDOWN:
+
+ //nShowStatisticsView(0,0);
+ // has to be called from the right thread
+ //QueueUserAPC(OpenStatisticViewFromPopupProc, hMainThread, 0);
+
+ QueueUserAPC(OpenStatisticViewFromPopupProc, hMainThread, 0);
+ PUDeletePopUp( hWnd );
+ return 0;
+
+ case WM_CONTEXTMENU: {
+ PUDeletePopUp( hWnd );
+ return 0;
+ }
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : ShowPopupWindow
+// Type : Global
+// Parameters : pszText - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030831, 31 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void ShowPopupWindow(const char * pszName, const char * pszText, COLORREF ColorBack /*= 0*/) {
+ if (! bShowPopups)
+ return;
+
+ POPUPDATA * pclData = new POPUPDATA;
+ memset(pclData, 0, sizeof(POPUPDATA));
+ pclData->lchIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE));
+ strncpy(pclData->lpzContactName, pszName, sizeof(pclData->lpzContactName) - 1); // -1 so that there aways will be a null termination !!
+ strncpy(pclData->lpzText, pszText, sizeof(pclData->lpzText) - 1);
+ pclData->colorBack = ColorBack;
+ //ppd.colorText = colorText;
+ pclData->PluginWindowProc = PopupWindowProc;
+ //Now that every field has been filled, we want to see the popup.
+
+ //CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0);
+ QueueUserAPC(MainThreadCallback, hMainThread, (ULONG_PTR)pclData);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : InitGuiElements
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030902, 02 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void InitGuiElements() {
+ INITCOMMONCONTROLSEX stInitCom;
+ stInitCom.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ stInitCom.dwICC = ICC_INTERNET_CLASSES;
+ InitCommonControlsEx(&stInitCom);
+
+ //hMainThread = GetCurrentThread();
+ DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, FALSE, 0);
+
+
+ sUrlAddress = DBGetString(NULL, MODULE, "UrlAddress", szDefaultUrlAddress);
+ sPageKeyword = DBGetString(NULL, MODULE, "PageKeyword", szDefaultPageKeyword);
+
+ hShareNewFileService = CreateServiceFunction(MS_SHARE_NEW_FILE, nShareNewFile);
+ if (! hShareNewFileService) {
+ MessageBox(NULL, _T("Failed to CreateServiceFunction MS_SHARE_NEW_FILE"), MSG_BOX_TITEL, MB_OK);
+ return;
+ }
+
+ hShowStatisticsViewService = CreateServiceFunction(MS_SHOW_STATISTICS_VIEW, nShowStatisticsView);
+ if (! hShowStatisticsViewService) {
+ MessageBox(NULL, _T("Failed to CreateServiceFunction MS_SHOW_STATISTICS_VIEW"), MSG_BOX_TITEL, MB_OK);
+ return;
+ }
+
+ 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 = -2000019955;
+ mi.ptszName = LPGENT("HTTP Share new file");
+ mi.pszService = MS_SHARE_NEW_FILE;
+
+ hShareNewFileMenuItem = Menu_AddMainMenuItem(&mi);
+ if (!hShareNewFileMenuItem) {
+ MessageBox(NULL, _T("Failed to add contact menu item"), MSG_BOX_TITEL, MB_OK);
+ return;
+ }
+
+
+ if (db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0) {
+ mi.position = 1000085005;
+ mi.flags = CMIF_TCHAR;
+ //mi.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_SHARE_NEW_FILE));
+ mi.pszContactOwner = NULL;
+ mi.ptszName = LPGENT("Show HTTP server statistics");
+ mi.pszService = MS_SHOW_STATISTICS_VIEW;
+ hShowStatisticsViewMenuItem = Menu_AddMainMenuItem(&mi);
+ }
+
+
+ hEventOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OptionsInitialize);
+ if (!hEventOptionsInitialize)
+ MessageBox(NULL, _T("Failed to HookEvent ME_OPT_INITIALISE"), MSG_BOX_TITEL, MB_OK);
+
+ bShowPopups = db_get_b(NULL, MODULE, "ShowPopups", bShowPopups) != 0;
+ /*
+ #ifdef _DEBUG
+ nShowStatisticsView(0,0);
+ #endif*/
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : UninitGuiElements
+// Type : Global
+// Parameters : None
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031011, 11 oktober 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void UnInitGuiElements() {
+ CloseHandle(hMainThread);
+}
diff --git a/plugins/HTTPServer/src/GuiElements.h b/plugins/HTTPServer/src/GuiElements.h
new file mode 100644
index 0000000000..0ce1d11814
--- /dev/null
+++ b/plugins/HTTPServer/src/GuiElements.h
@@ -0,0 +1,29 @@
+//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.
+
+#ifndef GUI_ELEMENTS_H
+#define GUI_ELEMENTS_H
+
+#include <windows.h>
+
+void InitGuiElements();
+void UnInitGuiElements();
+void UpdateStatisticsView();
+void ShowPopupWindow(const char * pszName, const char * pszText, COLORREF ColorBack = 0);
+void SendLinkToUser(WPARAM wParam, char *pszSrvPath); // Add By Sergio Vieira Rolanski
+
+#endif \ No newline at end of file
diff --git a/plugins/HTTPServer/src/HttpUser.cpp b/plugins/HTTPServer/src/HttpUser.cpp
new file mode 100644
index 0000000000..fc0f24be3f
--- /dev/null
+++ b/plugins/HTTPServer/src/HttpUser.cpp
@@ -0,0 +1,888 @@
+//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"
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : FileTimeToUnixTime
+// Type : Global
+// Parameters : pft - ?
+// t - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030826, 26 august 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+void FileTimeToUnixTime(LPFILETIME pft, time_t* t) {
+ LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32;
+ ll = ll + pft->dwLowDateTime - 116444736000000000;
+ *t = (time_t)(ll / 10000000);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Function : nUnescapedURI
+// Type : Local
+// Parameters : pszURI - URI to convert buffer is modifyed !!
+// Returns : length of the Unescaped URI
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030911, 11 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+static int nUnescapedURI(char * pszURI) {
+ if (! pszURI)
+ return 0;
+
+ char * pszOrigURI = pszURI;
+ int sumb;
+ int more = -1;
+ char* pszCurInsert = pszURI;
+
+ for (; *pszURI && pszURI[0] != ' ' ; pszURI++) {
+ int nNewChar;
+ if (pszURI[0] == '%') {
+ // we need to unescape the char
+ if (pszURI[1] == NULL || pszURI[2] == NULL || pszURI[1] == ' ' || pszURI[2] == ' ')
+ break; // handles error like "%2 " or "%a"
+
+ if (sscanf(&pszURI[1], "%2X", &nNewChar) != 1) {
+ // can't convert to number
+ pszURI += 2;
+ continue; // we skip it !!!
+ }
+ pszURI += 2;
+ }
+ /*else if( pszURI[0] == '+' )
+ {
+ nNewChar = ' ';
+ }*/
+ else
+ nNewChar = (int)tolower(pszURI[0]); // also make the request lowercase
+
+ if (nNewChar == '\\')
+ nNewChar = '/';
+
+ if ((nNewChar & 0x80) == 0x00) { // 0xxxxxxx (yields 7 bits)
+ more = -1; // this is to avoid sequence like %C3k%A6 will end up beeing "kæ" insted it will be "k"
+ *pszCurInsert = (char)nNewChar;
+ pszCurInsert++;
+ continue;
+ }
+
+ if ((nNewChar & 0xc0) == 0x80) { // 10xxxxxx (continuation byte)
+ sumb = (sumb << 6) | (nNewChar & 0x3f) ; // Add 6 bits to sumb
+ more--;
+ if (more == 0) {
+ *pszCurInsert = (char)sumb; // here we just throw away all the fine UTF-8 encoding
+ pszCurInsert++;
+ }
+ } else if ((nNewChar & 0xe0) == 0xc0) { // 110xxxxx (yields 5 bits)
+ sumb = nNewChar & 0x1f;
+ more = 1; // Expect 1 more byte
+ } else if ((nNewChar & 0xf0) == 0xe0) { // 1110xxxx (yields 4 bits)
+ sumb = nNewChar & 0x0f;
+ more = 2; // Expect 2 more bytes
+ } else if ((nNewChar & 0xf8) == 0xf0) { // 11110xxx (yields 3 bits)
+ sumb = nNewChar & 0x07;
+ more = 3; // Expect 3 more bytes
+ } else if ((nNewChar & 0xfc) == 0xf8) { // 111110xx (yields 2 bits)
+ sumb = nNewChar & 0x03;
+ more = 4; // Expect 4 more bytes
+ } else /*if ((nNewChar & 0xfe) == 0xfc)*/
+ { // 1111110x (yields 1 bit)
+ sumb = nNewChar & 0x01;
+ more = 5; // Expect 5 more bytes
+ }
+ }
+ return (pszCurInsert - pszOrigURI);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CLHttpUser
+// Type : Private / Public / Protected
+// Parameters : hCon - ?
+// stAdd - ?
+// pcl - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030918, 18 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLHttpUser::CLHttpUser(HANDLE hCon, in_addr stAdd) : CLShareUser(hCon, stAdd) {
+ memset(apszParam, 0, sizeof(apszParam));
+ hFile = INVALID_HANDLE_VALUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : CLHttpUser
+// Type : Private / Public / Protected
+// Parameters : None
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031124, 24 november 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+CLHttpUser::~CLHttpUser() {
+ if (hFile != INVALID_HANDLE_VALUE)
+ CloseHandle(hFile);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bReadGetParameters
+// Type : Private / Public / Protected
+// Parameters : pszRequest - ?
+// Returns : Returns true if
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030928, 28 september 2003
+// Developer : KN
+/////////////////////////////////////////////////////////////////////
+
+bool CLHttpUser::bReadGetParameters(char * pszRequest) {
+ bool bRet = true;
+ for (; *pszRequest ; pszRequest++) {
+ if (pszRequest[0] != '\n') {
+ if (pszRequest[0] == '\r')
+ pszRequest[0] = 0;
+ continue;
+ }
+ pszRequest[0] = 0;
+ pszRequest++;
+ for (int nCur = 0; nCur < eLastParam ; nCur++) {
+ int nLen = strlen(szParmStr[nCur]);
+ if (strncmp(pszRequest, szParmStr[nCur], nLen) == 0) {
+ if (apszParam[nCur]) {
+ bRet = false;
+ // already set !!
+ } else {
+ pszRequest += nLen;
+ apszParam[nCur] = pszRequest;
+ pszRequest += strcspn(pszRequest, "\r\n") - 1;
+ char * psz = pszRequest;
+ while (*psz == ' ') {
+ psz[0] = 0;// owerwrite ' ' or '\r' or '\n'
+ psz--;
+ }
+ }
+ break;
+ }
+ }
+ }
+ return bRet;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SendError
+// Type : Private / Public / Protected
+// Parameters : iErrorCode - ?
+// pszError - ?
+// pszDescription - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 031124, 24 november 2003
+// Developer : KN, Houdini
+// Changed : 21 January 2006 by Vampik
+/////////////////////////////////////////////////////////////////////
+
+void CLHttpUser::SendError(int iErrorCode, const char * pszError, const char * pszDescription) {
+ char szCurTime[ 100 ];
+ time_t ltime;
+ time(&ltime);
+ strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
+
+ if (!pszDescription)
+ pszDescription = pszError;
+
+ char szBuf[1000];
+ DWORD dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf) ,
+ "HTTP/1.1 %i %s\r\n"
+ "Date: %s\r\n"
+ "Server: MirandaWeb/%s\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n"
+ "\r\n"
+ "10f\r\n"
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
+ "<HTML><HEAD>\n"
+ "<TITLE>%i %s</TITLE>\n"
+ "</HEAD><BODY>\n"
+ "<H1>%s</H1>\n"
+ "%s<P>\n"
+ "<HR>\n"
+ "<ADDRESS>MirandaWeb/%s</ADDRESS>\n"
+ "</BODY></HTML>\n"
+ "\r\n"
+ "\r\n",
+ iErrorCode, pszError, szCurTime, pszVersion, iErrorCode, pszError, pszError, pszDescription, pszVersion);
+
+ Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : SendRedir
+// Type : Private / Public / Protected
+// Parameters : iErrorCode - ?
+// pszError - ?
+// pszDescription - ?
+// pszRedirect - ?
+// Returns : void
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 21 january 2006
+// Developer : KN, Houdini, Vampik
+/////////////////////////////////////////////////////////////////////
+
+void CLHttpUser::SendRedir(int iErrorCode, const char * pszError, const char * pszDescription, const char * pszRedirect) {
+ char szCurrTime[ 100 ];
+ time_t ltime;
+ time(&ltime);
+ strftime(szCurrTime, sizeof(szCurrTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
+
+ if (!pszDescription)
+ pszDescription = pszError;
+
+ char szBuff[1000];
+ DWORD dwBytesToWrite = _snprintf(szBuff, sizeof(szBuff) ,
+ "HTTP/1.1 %i %s\r\n"
+ "Date: %s\r\n"
+ "Server: MirandaWeb/%s\r\n"
+ "Location: %s/\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n"
+ "\r\n"
+ "10f\r\n"
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
+ "<HTML><HEAD>\n"
+ "<TITLE>%i %s</TITLE>\n"
+ "</HEAD><BODY>\n"
+ "<H1>%s</H1>\n"
+ "%s<P>\n"
+ "<HR>\n"
+ "<ADDRESS>MirandaWeb/%s</ADDRESS>\n"
+ "</BODY></HTML>\n"
+ "\r\n"
+ "\r\n",
+ iErrorCode, pszError, szCurrTime, pszVersion, pszRedirect, iErrorCode, pszError, pszError, pszDescription, pszVersion);
+
+ Netlib_Send(hConnection, szBuff, dwBytesToWrite, 0);
+}
+
+/////////////////////////////////////////////////////////////////////
+// Function : strmcat
+// Type : Local
+// Parameters : pszDest - ?
+// pszSrc - ?
+// MaxLength - ?
+// Returns :
+// Description : Fills pszDest until it is MaxLength long or
+// pszSrc is finished - always appends a \0
+// References : -
+// Remarks : -
+// Created :
+// Developer : Houdini
+/////////////////////////////////////////////////////////////////////
+
+static void strmcat(char* pszDest, const char* pszSrc, int iMaxLength) {
+ int iLength = 0;
+ while (*pszDest != '\0') {
+ pszDest++;
+ iLength++;
+ }
+
+ while (iLength < iMaxLength - 1 && *pszSrc != '\0') {
+ *pszDest = *pszSrc;
+ pszDest++;
+ pszSrc++;
+ iLength++;
+ }
+
+ *pszDest = '\0';
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bProcessGetRequest
+// Type : Global
+// Parameters : hNewConnection - ?
+// dwRemoteIP - ?
+// pszRequest - ?
+// Returns : Returns true if a file was send
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 030813, 13 august 2003
+// Developer : KN, Houdini
+// Changed : 27 January 2005 by Vampik
+// Changed : 21 January 2006 by Vampik
+/////////////////////////////////////////////////////////////////////
+
+bool CLHttpUser::bProcessGetRequest(char * pszRequest, bool bIsGetCommand) {
+ //LogEvent("Request", pszRequest);
+
+ int nUriLength = nUnescapedURI(pszRequest);
+ if (nUriLength <= 0)
+ return false;
+
+ CLFileShareListAccess clCritSection;
+
+ if (bShutdownInProgress)
+ return false;
+
+ static char szTempfile[MAX_PATH+1];
+ szTempfile[0] = '\0';
+
+ if (!bReadGetParameters(pszRequest)) {
+ SendError(400, "Bad Request");
+ return false;
+ }
+
+ DWORD dwRemoteIP = ntohl(stAddr.S_un.S_addr);
+ for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) {
+ if ((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask)
+ continue; // Not an allowed IP address
+
+ if (!pclCur->bIsDirectory() && pclCur->nGetSrvPathLen() != nUriLength)
+ continue; // not the right length, quickly move on to the next.
+
+ if (pclCur->bIsDirectory() ?
+ (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen() - 1) == 0) :
+ (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen()) == 0)) {
+ /*OutputDebugString( "Request for file OK : ");
+ OutputDebugString( pclCur->st.pszSrvPath );
+ OutputDebugString( "\n" );*/
+
+ static char szSrvPath[MAX_PATH+1];
+ static char szRealPath[MAX_PATH+1];
+ char* pszSrvPath = pclCur->st.pszSrvPath;
+ char* pszRealPath = pclCur->st.pszRealPath;
+
+ if (pclCur->bIsDirectory()) {
+ strcpy(szRealPath, pclCur->st.pszRealPath);
+ strcpy(szSrvPath, pclCur->st.pszSrvPath);
+ pszRealPath = szRealPath;
+ pszSrvPath = szSrvPath;
+
+ if (nUriLength > MAX_PATH)
+ nUriLength = MAX_PATH;
+
+ pszRequest[nUriLength] = '\0';
+
+ if (pclCur->nGetSrvPathLen() - nUriLength == 1) {
+ SendRedir(302, "Found", "The document has moved", pszRequest);
+ return false;
+ } else {
+ strmcat(pszRealPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH);
+ strmcat(pszSrvPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH);
+ }
+ pszRequest[nUriLength] = ' ';
+
+ // hacker protection - should be removed by the browser
+ if (strstr(pszRealPath, "..")) {
+ SendError(404, "Not Found", "The requested URL was not found on this server.");
+ return false;
+ }
+
+ char* pszTmp = pszRealPath;
+ while (pszTmp = strchr(pszTmp, '/'))
+ * pszTmp = '\\';
+
+ hFile = CreateFile(pszRealPath, GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ if (pszSrvPath[strlen(pszSrvPath)-1] != '/') {
+ strmcat(pszRealPath, "\\", MAX_PATH);
+ strmcat(pszSrvPath, "/", MAX_PATH);
+ }
+
+ // a directory with index.htm
+ strmcat(szRealPath, "index.htm", MAX_PATH);
+
+ hFile = CreateFile(pszRealPath, GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ // a directory with index.html
+ strmcat(szRealPath, "l", MAX_PATH);
+
+ hFile = CreateFile(pszRealPath, GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ // generate directory index in temporary file
+ if (*szTempfile == '\0') {
+ GetTempPath(MAX_PATH, szTempfile);
+ strmcat(szTempfile, "\\HttpServerTemp", MAX_PATH);
+ strmcat(szTempfile, pszSrvPath, MAX_PATH);
+ char* pszTmp = szTempfile;
+ while (pszTmp = strchr(pszTmp, '/'))
+ * pszTmp = '~';
+ }
+ pszRealPath[strlen(pszRealPath) - 10] = '\0';
+
+ // detecting browser function removed
+ // every browser should support it by now
+ bool BrowserSupportsXML = true;
+ //(apszParam[eUserAgent] != NULL) &&
+ // (strstr(apszParam[eUserAgent], "Firefox") ||
+ // (strstr(apszParam[eUserAgent], "MSIE") && !strstr(apszParam[eUserAgent], "Opera")));
+
+ if ((indexCreationMode == INDEX_CREATION_XML ||
+ (indexCreationMode == INDEX_CREATION_DETECT && BrowserSupportsXML)) &&
+ bCreateIndexXML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) {
+ hFile = CreateFile(szTempfile, GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ strcpy(szRealPath, "a.xml"); // restore .xml for mime type
+ } else if ((indexCreationMode == INDEX_CREATION_HTML ||
+ indexCreationMode == INDEX_CREATION_DETECT) &&
+ bCreateIndexHTML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) {
+ hFile = CreateFile(szTempfile, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ strcpy(szRealPath, "a.html"); // restore .html for mime type
+ } else {
+ continue;
+ }
+ } else {
+ strmcat(pszSrvPath, "index.html", MAX_PATH);
+ szTempfile[0] = '\0';
+ }
+ } else {
+ strmcat(pszSrvPath, "index.htm", MAX_PATH);
+ szTempfile[0] = '\0';
+ }
+ } else {
+ szTempfile[0] = '\0';
+ }
+ } else {
+ hFile = CreateFile(pszRealPath, GENERIC_READ ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ SendError(404, "Not Found", "HTTP server failed to open local file");
+ return false;
+ }
+ }
+
+ strcpy(this->szCurrentDLSrvPath, pszSrvPath);
+
+ DWORD nDataSize = GetFileSize(hFile, NULL);
+ dwTotalSize = nDataSize;
+
+ FILETIME stFileTime;
+ GetFileTime(hFile, NULL, NULL, &stFileTime);
+
+ char szCurTime[ 100 ];
+ time_t ltime;
+ time(&ltime);
+ strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
+
+ char szFileTime[ 100 ];
+ FileTimeToUnixTime(&stFileTime, &ltime);
+ strftime(szFileTime, sizeof(szFileTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
+
+ if (apszParam[eIfModifiedSince] && strcmp(apszParam[eIfModifiedSince], szFileTime) == 0) {
+ SendError(304, "Not Modified" );
+ return true;
+ }
+
+ // we found match send file !!
+ if (bIsGetCommand) {
+ if (! pclCur->bAddUser(this)) {
+ SendError(403, "Forbidden", "Access has been denied because there are too many connections");
+ return false;
+ }
+ }
+
+ if (*(ULONG*)(&stAddr) != 0x0100007F && // do not show popup of 127.0.0.1
+ strstr(pszRealPath, "\\@") == NULL) { // and of shares which start with an @
+ ShowPopupWindow(inet_ntoa(stAddr), pszSrvPath);
+ }
+
+ clCritSection.Unlock();
+
+ DWORD dwFileStart = 0;
+ DWORD dwDataToSend = nDataSize;
+
+ char szETag[ 50 ];
+ {
+ int nETagLen = _snprintf(szETag, sizeof(szETag), "\"%x-%x-%x\"",
+ nDataSize, stFileTime.dwHighDateTime, stFileTime.dwLowDateTime);
+
+ if (!apszParam[eIfRange] || (strncmp(szETag, apszParam[eIfRange], nETagLen) == 0)) {
+ char * pszRange = apszParam[eRange];
+ if (pszRange) {
+ if (strncmp(pszRange, "bytes=", 6) == 0) {
+ pszRange += 6;
+ // Do resume !!!
+ char *pszEnd;
+ if (pszRange[0] == '-') {
+ // its a suffix-byte-range-spec
+ DWORD dwLen = strtol(pszRange + 1, &pszEnd, 10);
+ if (dwLen < nDataSize)
+ dwFileStart = nDataSize - dwLen;
+ } else {
+ DWORD dwLen = strtol(pszRange, &pszEnd, 10);
+ if (*pszEnd == '-' && dwLen < nDataSize) {
+ dwFileStart = dwLen;
+ pszRange = pszEnd + 1;
+ if (*pszRange != 0) {
+ dwLen = strtol(pszEnd + 1, &pszEnd, 10);
+ if (dwLen > dwFileStart)
+ dwDataToSend = (dwLen + 1) - dwFileStart;
+ else
+ dwFileStart = 0;
+ }
+ } else {
+ SendError(400, "Bad Request");
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (dwFileStart >= nDataSize)
+ dwFileStart = 0;
+
+ if (dwFileStart + dwDataToSend >= nDataSize)
+ dwDataToSend = nDataSize - dwFileStart;
+
+
+ DWORD dwBytesToWrite = 0;
+ // To optimize send speed it it ideal to always send larges size packages
+ // But this size depended on network media but on Ethernet it is 1518 bytes.
+ // Ethernet, IP and TCP headers use some of this space and leaves 1460 bytes
+ // for data transfer.
+ // We will use a multiply of this to always send optimal sized packages.
+ char szBuf[1460 * 4];
+
+ if (dwFileStart > 0 || dwDataToSend != nDataSize) {
+ if (SetFilePointer(hFile, dwFileStart, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ SendError(416, "Requested Range Not Satisfiable");
+ return true;
+ }
+
+ const char szHttpPartial[] = "HTTP/1.1 206 Partial Content\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Date: %s\r\n"
+ "Server: MirandaWeb/%s\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "ETag: %s\r\n"
+ "Content-Length: %d\r\n"
+ "Content-Type: %s\r\n"
+ "Content-Range: bytes %d-%d/%d\r\n"
+ "Last-Modified: %s\r\n"
+ "\r\n";
+
+ dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpPartial ,
+ szCurTime ,
+ pszVersion,
+ szETag ,
+ dwDataToSend ,
+ pszGetMimeType(pszRealPath),
+ dwFileStart,
+ (dwFileStart + dwDataToSend - 1),
+ nDataSize,
+ szFileTime);
+ } else {
+ const char szHttpOk[] = "HTTP/1.1 200 OK\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Date: %s\r\n"
+ "Server: MirandaWeb/%s\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "ETag: %s\r\n"
+ "Content-Length: %d\r\n"
+ "Content-Type: %s\r\n"
+ "Last-Modified: %s\r\n"
+ "\r\n";
+
+ dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpOk ,
+ szCurTime ,
+ pszVersion,
+ szETag ,
+ nDataSize ,
+ pszGetMimeType(pszRealPath),
+ szFileTime);
+ }
+
+ Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0);
+
+ if (bIsGetCommand) {
+ static int nThreadCount = 0;
+ nThreadCount++;
+
+ DWORD dwLastUpdate = GetTickCount();
+ DWORD dwLastCurrentDL = 0;
+ /*
+
+ dwLastDLSTickCount = dwCurTick;
+ dwCurrentDL;*/
+
+ //DWORD dwMaxSpeed = 8192;// Byte pr Sek
+ //DWORD dwMaxSpeed = 20000;// Byte pr Sek
+ //DWORD dwMaxSpeed = 163840;// Byte pr Sek
+ //DWORD dwMaxSpeed = 4096;// Byte pr Sek
+
+ DWORD dwLastResetTime = GetTickCount();
+ int nMaxBytesToSend = nMaxUploadSpeed / nThreadCount;
+
+ for (;;) {
+ {
+ DWORD dwCurTick = GetTickCount();
+ if (dwCurTick - dwLastUpdate >= 1000) {/*
+ char szTmp[200];
+ _snprintf( szTmp, sizeof( szTmp ), "Bytes tr %d Time %d Tick %d\n", dwCurrentDL - dwLastCurrentDL, dwCurTick - dwLastUpdate, dwCurTick );
+ OutputDebugString( szTmp );
+ */
+ dwSpeed = ((dwCurrentDL - dwLastCurrentDL) * 1000) / (dwCurTick - dwLastUpdate);
+ dwLastUpdate = dwCurTick;
+ dwLastCurrentDL = dwCurrentDL;
+ }
+ }
+
+ if (nMaxUploadSpeed == 0) {
+ Sleep(1000);
+ continue;
+ }
+
+ bool bSpeedLimit = (nMaxUploadSpeed >= 0) && (bIsOnline || !bLimitOnlyWhenOnline);
+
+ DWORD dwCurOpr = sizeof(szBuf);
+ if (bSpeedLimit)
+ dwCurOpr = min(nMaxBytesToSend, sizeof(szBuf));
+
+ if (!ReadFile(hFile, szBuf, dwCurOpr, &dwBytesToWrite, NULL))
+ break;
+
+ if (dwBytesToWrite <= 0)
+ break;
+
+ if (dwCurrentDL + dwBytesToWrite > dwDataToSend)
+ dwBytesToWrite = dwDataToSend - dwCurrentDL;
+
+ if (bSpeedLimit)
+ nMaxBytesToSend -= dwBytesToWrite;
+
+ DWORD dwSend = Netlib_Send(hConnection, szBuf, dwBytesToWrite, MSG_NODUMP);
+ if (dwSend == SOCKET_ERROR)
+ break;
+ dwCurrentDL += dwSend;
+ if (dwSend != dwBytesToWrite)
+ break;
+
+ if (dwCurrentDL >= dwDataToSend)
+ break;
+
+ if (bSpeedLimit && nMaxBytesToSend <= 0) {
+ // we have reached the limmit
+ DWORD dwTimeUsed = GetTickCount() - dwLastResetTime;
+ if (dwTimeUsed < 1000)
+ Sleep(1000 - dwTimeUsed);
+ dwLastResetTime = GetTickCount();
+ nMaxBytesToSend = nMaxUploadSpeed / nThreadCount;
+ }
+ /*
+ char szTmp[200];
+ _snprintf( szTmp, sizeof( szTmp ), "Current status : %d %% pos %d size %d\n", (dwCurrentDL * 100) / dwTotalSize, dwCurrentDL , dwTotalSize );
+ OutputDebugString( szTmp );
+ */
+ }
+
+ // file is always closed in destructor
+ if (szTempfile[0] != '\0') {
+ // and here - since it is a temporary index which as to be deleted
+ CloseHandle(hFile);
+ hFile = INVALID_HANDLE_VALUE;
+
+ DeleteFile(szTempfile);
+ }
+ /*
+ {
+ char szBuf[200];
+ _snprintf( szBuf, sizeof( szBuf ), "File Transfer stoped %d transfer complete %d\n", GetTickCount(), dwCurrentDL == nDataSize);
+ OutputDebugString( szBuf );
+ }
+ */
+ clCritSection.Lock();
+ nThreadCount--;
+
+ bool bNeedToWriteConfig = false;
+
+ if (dwCurrentDL == nDataSize) {
+ if (pclCur->st.nMaxDownloads > 0) {
+ pclCur->st.nMaxDownloads--;
+ bNeedToWriteConfig = true;
+ }
+ }
+
+ pclCur->bRemoveUser(this);
+
+ // nMaxDownloads can have been decreesed by another thread.
+ // Therefore we test it even if we did'en decreese it
+ if (pclCur->st.nMaxDownloads == 0 && !pclCur->bAnyUsers()) {
+ CLFileShareNode **pclPrev = &pclFirstNode;
+ for (CLFileShareNode * pcl = pclFirstNode ; pcl ; pcl = pcl->pclNext) {
+ if (pcl == pclCur) {
+ *pclPrev = pclCur->pclNext;
+ ShowPopupWindow(Translate("Share removed"), pclCur->st.pszSrvPath, RGB(255, 189, 189));
+ delete pclCur;
+ bNeedToWriteConfig = true;
+ break;
+ }
+ pclPrev = &pcl->pclNext;
+ }
+ }
+
+ if (bNeedToWriteConfig) {
+ bWriteConfigurationFile();
+ }
+ }
+
+ return true;
+ }
+ }
+
+
+#ifdef _DEBUG
+ OutputDebugString("########### Request Failed ###########\n");
+ OutputDebugString(pszRequest);
+#endif
+
+ pszRequest[nUriLength] = 0;
+
+ if ((nUriLength != 12 || strncmp(pszRequest, "/favicon.ico", nUriLength)) && // do not show popup of favicon.ico
+ *(ULONG*)(&stAddr) != 0x0100007F) { // do not show popup of 127.0.0.1
+ ShowPopupWindow(inet_ntoa(stAddr), pszRequest, RGB(255, 189, 189));
+ }
+
+ SendError(404, "Not Found", "The requested URL was not found on this server.");
+
+ return false;
+}
+
+
+void CLHttpUser::HandleNewConnection() {
+
+/*
+ {
+ SOCKET s = CallService(MS_NETLIB_GETSOCKET, (WPARAM) hConnection, 0);
+ sockaddr_in MyAddr;
+ int nSize = sizeof( MyAddr );
+ getsockname( s, (sockaddr*)&MyAddr, &nSize );
+ ShowPopupWindow( "My IP address", inet_ntoa( MyAddr.sin_addr ) );
+ //OutputDebugString( );
+ }*/
+ /*
+ {
+ LINGER li;
+ int nLenght = sizeof( li );
+ int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght );
+ if( ret )
+ {
+ DWORD error = WSAGetLastError();
+ if( error
+ WSANOTINITIALISED
+ WSAENETDOWN The network subsystem has failed.
+ WSAEFAULT One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small.
+ WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
+ WSAEINVAL The level parameter is unknown or invalid.
+ WSAENOPROTOOPT The option is unknown or unsupported by the indicated protocol family.
+ WSAENOTSOCK
+ }
+ nLenght = sizeof( li );
+ li.l_onoff = 1;
+ li.l_linger = 0;// time is default
+ ret = setsockopt( s, IPPROTO_TCP, SO_LINGER, (const char *)&li, nLenght );
+ if( ret )
+ {
+ // error
+ }
+ int nLenght = sizeof( li );
+ int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght );
+ }
+ */
+
+ char szBuf[1000];
+ int nCurPos = 0;
+ while (sizeof(szBuf) - nCurPos > 10 && !bShutdownInProgress) {
+ int nBytesRead = Netlib_Recv(hConnection, &szBuf[nCurPos], sizeof(szBuf) - nCurPos, 0);
+ if (! nBytesRead) {
+ // socket closed gracefully
+ break;
+ }
+ if (nBytesRead == SOCKET_ERROR) {
+ // socket closed with error
+ // WSAGetLastError();
+ break;
+ }
+ int nOldCurPos = nCurPos;
+ nCurPos += nBytesRead;
+ if (nCurPos <= 5)
+ continue;
+
+ bool bIsGetCommand = memcmp(szBuf, "GET ", 4) == 0;
+ if (!bIsGetCommand && memcmp(szBuf, "HEAD ", 5) != 0) {
+ SendError(501, "Not Implemented");
+ break; // We only support GET and HEAD commands !!
+ }
+
+ if (nOldCurPos < 4)
+ nOldCurPos = 4; // scan forward from end of "GET " to locate the next space ' '
+
+ bool bBreakWhile = false;
+ for (; nOldCurPos < nCurPos; nOldCurPos++) {
+ if (szBuf[nOldCurPos-2] == '\n' && szBuf[nOldCurPos-1] == '\r' && szBuf[nOldCurPos] == '\n') {
+ // we have a walid request !!! scan to see if we have this file
+ szBuf[nOldCurPos] = NULL;
+ bProcessGetRequest(&szBuf[bIsGetCommand?4:5], bIsGetCommand);
+
+ bBreakWhile = true;
+ break;
+ }
+ }
+ if (bBreakWhile)
+ break;
+ }
+}
diff --git a/plugins/HTTPServer/src/HttpUser.h b/plugins/HTTPServer/src/HttpUser.h
new file mode 100644
index 0000000000..00b43a76eb
--- /dev/null
+++ b/plugins/HTTPServer/src/HttpUser.h
@@ -0,0 +1,70 @@
+//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.
+
+#ifndef HTTP_USER_H
+#define HTTP_USER_H
+
+#include <windows.h>
+#include "m_HTTPServer.h"
+#include "FileShareNode.h"
+
+enum ENParamTypes {
+ eFirstParam = 0,
+ eRange = 0,
+ eIfRange,
+ eUnlessModifiedSince,
+ eIfModifiedSince,
+ eUserAgent,
+ eHost,
+ eLastParam
+};
+
+static char * szParmStr[eLastParam] = {
+ "Range: ",
+ "If-Range: ",
+ "Unless-Modified-Since: ",
+ "If-Modified-Since: ",
+ "User-Agent: ",
+ "Host: "
+};
+
+
+class CLHttpUser : public CLShareUser {
+public:
+ CLHttpUser(HANDLE hCon, in_addr stAdd);
+ virtual ~CLHttpUser();
+
+ bool bReadGetParameters(char * pszRequest);
+
+ //bool bSendFile( HANDLE hFile ,
+ bool bCloseTransfers() {
+ return true;
+ }
+ bool bProcessGetRequest(char * pszRequest, bool bIsGetCommand);
+ const char * pszCustomInfo() {
+ return apszParam[eUserAgent];
+ }
+ void HandleNewConnection();
+private:
+ HANDLE hFile;
+ char *apszParam[eLastParam];
+
+ void SendError(int iErrorCode, const char * pszError, const char * pszDescription = NULL);
+ void SendRedir(int iErrorCode, const char * pszError, const char * pszDescription = NULL, const char * pszRedirect = NULL);
+};
+
+#endif \ No newline at end of file
diff --git a/plugins/HTTPServer/src/IndexCreation.h b/plugins/HTTPServer/src/IndexCreation.h
new file mode 100644
index 0000000000..c3892c4308
--- /dev/null
+++ b/plugins/HTTPServer/src/IndexCreation.h
@@ -0,0 +1,42 @@
+
+//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.
+
+#ifndef HTTP_INDEXCREATION_H
+#define HTTP_INDEXCREATION_H
+
+#include <windows.h>
+#include "m_HTTPServer.h"
+#include "FileShareNode.h"
+
+const char szIndexHTMLTemplateFile[] = "HTTPServerIndex.html";
+
+enum eIndexCreationMode {
+ INDEX_CREATION_DISABLE = 0,
+ INDEX_CREATION_HTML = 1,
+ INDEX_CREATION_XML = 2,
+ INDEX_CREATION_DETECT = 4
+};
+
+extern eIndexCreationMode indexCreationMode;
+
+bool bCreateIndexXML(const char * pszRealPath, const char * pszIndexPath, const char * pszSrvPath, DWORD dwRemoteIP);
+bool bCreateIndexHTML(const char * pszRealPath, const char * pszIndexPath, const char * pszSrvPath, DWORD dwRemoteIP);
+void FreeIndexHTMLTemplate();
+bool LoadIndexHTMLTemplate();
+
+#endif \ No newline at end of file
diff --git a/plugins/HTTPServer/src/IndexHTML.cpp b/plugins/HTTPServer/src/IndexHTML.cpp
new file mode 100644
index 0000000000..2a5f70f341
--- /dev/null
+++ b/plugins/HTTPServer/src/IndexHTML.cpp
@@ -0,0 +1,527 @@
+//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"
+
+eIndexCreationMode indexCreationMode;
+
+static char* szIndexHTMLTemplate = NULL;
+static const int MAX_PARAM_LENGTH = 5;
+
+// signs below 32 are not used anyway
+enum Symbol {
+ SY_END = 15,
+ SY_FOR_DIRS,
+ SY_DIR_URL,
+ SY_DIR_NAME,
+ SY_FOR_FILES,
+ SY_FILE_URL,
+ SY_FILE_NAME,
+ SY_FILE_SIZE,
+ SY_FILE_CREATE_TIME,
+ SY_FILE_MODIFY_TIME,
+ SY_IS_EVEN,
+ SY_IS_ODD,
+ SY_IS_FILE_TYPE
+};
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : LoadIndexHTMLTemplate
+// Type : Global
+// Parameters : -
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050901, 05 august 2005
+// Developer : Houdini
+/////////////////////////////////////////////////////////////////////
+
+bool LoadIndexHTMLTemplate() {
+ if (szIndexHTMLTemplate != NULL)
+ return true;
+
+ char szBuf[10000];
+ char* pszBuf = szBuf;
+
+ char szDestBuf[10000];
+ char* pszDestBuf = szDestBuf;
+
+ strcpy(pszBuf, szPluginPath);
+ strcat(pszBuf, szIndexHTMLTemplateFile);
+
+ HANDLE hFile = CreateFile(pszBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ MessageBox(NULL, "HTTPServerIndex.html not found in Plugin Path", MSG_BOX_TITEL, MB_OK);
+ return false;
+ }
+
+ DWORD dwBytesRead = 0;
+ if (ReadFile(hFile, pszBuf, sizeof(szBuf), &dwBytesRead, NULL) || dwBytesRead <= 0) {
+ while (dwBytesRead > (DWORD)(pszBuf - szBuf)) {
+ if (*pszBuf == '[') {
+ char* pszKeywordBegin = pszBuf + 1;
+ bool bHasParameters = false;
+
+ do {
+ pszBuf++;
+ } while (*pszBuf != ']' && *pszBuf != '\0' && *pszBuf != '=');
+
+ if (*pszBuf == '\0')
+ break;
+
+ if (*pszBuf == '=')
+ bHasParameters = true;
+
+ *pszBuf = '\0';
+ *pszDestBuf = '#';
+
+ // signs below 32 are not used anyway
+ if (!strcmp(pszKeywordBegin, "End")) *pszDestBuf = SY_END;
+ else if (!strcmp(pszKeywordBegin, "ForDirectoriesDo")) *pszDestBuf = SY_FOR_DIRS;
+ else if (!strcmp(pszKeywordBegin, "DirectoryUrl")) *pszDestBuf = SY_DIR_URL;
+ else if (!strcmp(pszKeywordBegin, "DirectoryName")) *pszDestBuf = SY_DIR_NAME;
+ else if (!strcmp(pszKeywordBegin, "ForFilesDo")) *pszDestBuf = SY_FOR_FILES;
+ else if (!strcmp(pszKeywordBegin, "FileUrl")) *pszDestBuf = SY_FILE_URL;
+ else if (!strcmp(pszKeywordBegin, "FileName")) *pszDestBuf = SY_FILE_NAME;
+ else if (!strcmp(pszKeywordBegin, "FileSize")) *pszDestBuf = SY_FILE_SIZE;
+ else if (!strcmp(pszKeywordBegin, "FileCreated")) *pszDestBuf = SY_FILE_CREATE_TIME;
+ else if (!strcmp(pszKeywordBegin, "FileModified")) *pszDestBuf = SY_FILE_MODIFY_TIME;
+ else if (!strcmp(pszKeywordBegin, "IsEven")) *pszDestBuf = SY_IS_EVEN;
+ else if (!strcmp(pszKeywordBegin, "IsOdd")) *pszDestBuf = SY_IS_ODD;
+ else if (!strcmp(pszKeywordBegin, "IsFileType")) *pszDestBuf = SY_IS_FILE_TYPE;
+ else {
+ LogEvent("Error in index template", "Unknown Tag");
+ // unknown tag
+ }
+
+ // remove some useless returns
+ if (*pszDestBuf == SY_END)
+ while (*(pszBuf + 1) == '\r' || *(pszBuf + 1) == '\n')
+ pszBuf++;
+
+ pszDestBuf++;
+
+ // these tags require an End - reserve space for relative jump address (2 byte)
+ switch (*(pszDestBuf - 1)) {
+ case SY_FOR_DIRS:
+ case SY_FOR_FILES:
+ case SY_IS_EVEN:
+ case SY_IS_ODD:
+ case SY_IS_FILE_TYPE: {
+ *((WORD*)(pszDestBuf)) = 0x7070;
+ pszDestBuf += 2;
+ }
+ }
+
+ if (bHasParameters) {
+ // max MAX_PARAM_LENGTH chars per param (terminated with : when shorter than MAX_PARAM_LENGTH)
+ byte iParamCount = 1;
+ char* pcParamCount = (pszDestBuf++);
+ char* pszParameterBegin = pszBuf + 1;
+
+ do {
+ if (*pszBuf == ',') {
+ *pszBuf = ':';
+ strncpy(pszDestBuf, pszParameterBegin, MAX_PARAM_LENGTH);
+ pszDestBuf += MAX_PARAM_LENGTH;
+
+ pszParameterBegin = pszBuf + 1;
+ iParamCount++;
+ }
+ pszBuf++;
+ } while (*pszBuf != ']' && *pszBuf != '\0');
+
+ if (*pszBuf == '\0')
+ break;
+
+ *pszBuf = ':';
+ strncpy(pszDestBuf, pszParameterBegin, MAX_PARAM_LENGTH);
+ pszDestBuf += MAX_PARAM_LENGTH;
+
+ *pcParamCount = iParamCount;
+ }
+ } else {
+ *(pszDestBuf++) = *pszBuf;
+ }
+
+ pszBuf++;
+ }
+
+ *(pszDestBuf) = '\0';
+
+ pszBuf = szDestBuf;
+
+ while (*pszBuf != '\0') {
+ byte iLevel = 0;
+ switch (*pszBuf) {
+ // these tags require an End - precalculate address of End
+ case SY_FOR_DIRS:
+ case SY_FOR_FILES:
+ case SY_IS_EVEN:
+ case SY_IS_ODD:
+ case SY_IS_FILE_TYPE:
+ iLevel++;
+ break;
+ }
+
+ pszBuf++;
+
+ // begin of iLevel - find End of iLevel
+ if (iLevel > 0) {
+ char* pszLevelEnd = pszBuf + 2; // skip for address reserved bytes
+
+ // skip parameters of IsFileType
+ if (*(pszBuf - 1) == SY_IS_FILE_TYPE) {
+ pszLevelEnd++;
+ pszLevelEnd += *(pszLevelEnd - 1) * MAX_PARAM_LENGTH;
+ }
+
+ while (*pszLevelEnd != '\0' && iLevel > 0) {
+ switch (*pszLevelEnd) {
+ case SY_FOR_DIRS:
+ case SY_FOR_FILES:
+ case SY_IS_EVEN:
+ case SY_IS_ODD:
+ iLevel++;
+ pszLevelEnd += 2;
+ break;
+
+ case SY_IS_FILE_TYPE:
+ iLevel++;
+ pszLevelEnd += 2;
+ pszLevelEnd += 1;
+ pszLevelEnd += *(pszLevelEnd) * MAX_PARAM_LENGTH;
+ break;
+
+ case SY_END:
+ iLevel--;
+ break;
+ }
+
+ pszLevelEnd++;
+ }
+
+ if (*pszLevelEnd == '\0') {
+ LogEvent("Error in index template", "End is missing");
+ break; // Error - End missing
+ }
+
+ //char Temp[100];
+ //sprintf(Temp, "Tag: %i Begin: %i End: %i", *(pszBuf-1), pszBuf-szDestBuf, pszBuf-szDestBuf+pszLevelEnd-pszBuf);
+ //LogEvent("Jump", Temp);
+
+ // write jump address
+ *((WORD*)(pszBuf)) = (WORD)((pszLevelEnd - pszBuf - 1) | 0x8000);
+ pszBuf += 2;
+ }
+ }
+
+ *(pszBuf) = '\0';
+
+ //LogEvent("Template", szDestBuf);
+
+ szIndexHTMLTemplate = new char[strlen(szDestBuf)+1];
+ strcpy(szIndexHTMLTemplate, szDestBuf);
+ }
+
+ CloseHandle(hFile);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : FreeIndexHTMLTemplate
+// Type : Global
+// Parameters : -
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050901, 05 august 2005
+// Developer : Houdini
+/////////////////////////////////////////////////////////////////////
+
+void FreeIndexHTMLTemplate() {
+ if (szIndexHTMLTemplate != NULL) {
+ delete[] szIndexHTMLTemplate;
+ szIndexHTMLTemplate = NULL;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bCreateIndexHTML
+// Type : Global
+// Parameters : pszRealPath - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050821, 05 august 2005
+// Developer : Houdini
+/////////////////////////////////////////////////////////////////////
+
+bool bCreateIndexHTML(const char * pszRealPath, const char * pszIndexPath,
+ const char * pszSrvPath, DWORD /* dwRemoteIP */) {
+#define RelativeJump(begin) { pszPos += *((WORD*)(begin+1)) & 0x7FFF; }
+
+ if (szIndexHTMLTemplate == NULL)
+ return false;
+
+ // check if directory exists
+ char szMask[MAX_PATH];
+ strcpy(szMask, pszRealPath);
+ strcat(szMask, "*");
+
+ WIN32_FIND_DATAA fdFindFileData;
+ HANDLE hFind = FindFirstFile(szMask, &fdFindFileData);
+
+ if (hFind == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ FindClose(hFind);
+ hFind = 0;
+
+ HANDLE hFile = CreateFile(pszIndexPath, GENERIC_WRITE, FILE_SHARE_READ ,
+ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ char szBuffer[10000];
+ char* pszBuffer = szBuffer;
+ DWORD dwBytesWritten = 0;
+
+ char* pszPos = szIndexHTMLTemplate;
+
+ byte iCurrentAction = 0;
+ char* pszLevelBegin[50];
+ byte iLevel = 0;
+
+ char szName[1000] = "";
+ char szURL[1000] = "";
+ int iFileSize = 0;
+ FILETIME ftFileCreateTime;
+ FILETIME ftFileModifyTime;
+ bool bEvenOdd = 0;
+ bool bKnownFileType = false;
+
+ strcpy(szBuffer, pszSrvPath);
+ char* pszTemp = strrchr(szBuffer, '/');
+ if (pszTemp)
+ *pszTemp = '\0';
+
+ pszTemp = strrchr(szBuffer, '/');
+ if (pszTemp)
+ strcpy(szName, pszTemp + 1);
+
+ if (strlen(szName) == 0)
+ strcpy(szName, "my Miranda Webserver");
+
+ do {
+ switch (*pszPos) {
+ case SY_FOR_FILES:
+ case SY_FOR_DIRS: {
+ if (hFind == 0) {
+ pszLevelBegin[iLevel++] = pszPos;
+ iCurrentAction = *pszPos;
+
+ hFind = FindFirstFile(szMask, &fdFindFileData);
+ if (hFind == 0) {
+ iCurrentAction = 0;
+ RelativeJump(pszLevelBegin[iLevel-1]);
+ break;
+ }
+ } else {
+ if (!FindNextFile(hFind, &fdFindFileData)) {
+ FindClose(hFind);
+ hFind = 0;
+ iCurrentAction = 0;
+ RelativeJump(pszLevelBegin[iLevel-1]);
+ break;
+ }
+ }
+
+ while (!strcmp(fdFindFileData.cFileName, ".") ||
+ !strncmp(fdFindFileData.cFileName, "@", 1) ||
+ (!strcmp(fdFindFileData.cFileName, "..") && !strcmp(pszSrvPath, "/")) || // hide .. in root
+ ((*pszPos == 19) == ((fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0))) {
+ if (!FindNextFile(hFind, &fdFindFileData)) {
+ FindClose(hFind);
+ hFind = 0;
+ iCurrentAction = 0;
+ RelativeJump(pszLevelBegin[iLevel-1]);
+ break;
+ }
+ }
+
+ if (hFind) {
+ strcpy(szName, fdFindFileData.cFileName);
+ strcpy(szURL, fdFindFileData.cFileName);
+ /*char* pszTmp = szURL;
+ while(pszTmp = strchr(pszTmp, ' '))
+ *pszTmp = '+';*/
+
+ if (*pszPos == SY_FOR_DIRS) { // For Directories
+ strcat(szURL, "/");
+ } else { // For Files
+ iFileSize = fdFindFileData.nFileSizeLow;
+ ftFileCreateTime = fdFindFileData.ftCreationTime;
+ ftFileModifyTime = fdFindFileData.ftLastWriteTime;
+ }
+
+ bKnownFileType = false;
+ bEvenOdd = !bEvenOdd;
+ pszPos += 2;
+ }
+
+ break;
+ }
+
+ case SY_END: { // End
+ if (iLevel <= 0)
+ break; // Error
+
+ if (iCurrentAction == SY_FOR_DIRS || iCurrentAction == SY_FOR_FILES) { // For loops
+ pszPos = pszLevelBegin[iLevel-1] - 1; // jump to begin
+ } else {
+ iLevel--;
+ if (iLevel > 0)
+ iCurrentAction = *pszLevelBegin[iLevel-1];
+ else
+ iCurrentAction = 0;
+ }
+
+ break;
+ }
+
+ case SY_FILE_NAME:
+ case SY_DIR_NAME: {
+ pszBuffer += _snprintf(pszBuffer, 250, "%s", szName);
+ break;
+ }
+
+ case SY_DIR_URL: {
+ case SY_FILE_URL:
+ pszBuffer += _snprintf(pszBuffer, 250, "%s", szURL);
+ break;
+ }
+
+ case SY_FILE_CREATE_TIME:
+ case SY_FILE_MODIFY_TIME: {
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime(
+ (*pszPos == SY_FILE_CREATE_TIME) ? &ftFileCreateTime : &ftFileModifyTime,
+ &systemTime);
+
+ pszBuffer += _snprintf(pszBuffer, 100, "%i/%02i/%02i %i:%02i:%02i",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
+ systemTime.wMinute, systemTime.wSecond);
+ break;
+ }
+
+ case SY_FILE_SIZE: {
+ if ((iFileSize >> 10) == 0)
+ pszBuffer += _snprintf(pszBuffer, 100, "%i Byte", iFileSize);
+ else if ((iFileSize >> 20) == 0)
+ pszBuffer += _snprintf(pszBuffer, 100, "%.1f KB", (float)(iFileSize) / 1024.0f);
+ else
+ pszBuffer += _snprintf(pszBuffer, 100, "%.1f MB", (float)(iFileSize) / (1024.0f * 1024.0f));
+ break;
+ }
+
+ case SY_IS_EVEN:
+ case SY_IS_ODD: {
+ pszLevelBegin[iLevel++] = pszPos;
+ iCurrentAction = *pszPos;
+
+ if (bEvenOdd != (*pszPos - SY_IS_EVEN == 1)) { // SY_IS_EVEN+1 == SY_IS_ODD
+ RelativeJump(pszLevelBegin[iLevel-1]);
+ } else {
+ pszPos += 2;
+ }
+ break;
+ }
+
+ case SY_IS_FILE_TYPE: {
+ pszLevelBegin[iLevel++] = pszPos;
+ iCurrentAction = *pszPos;
+
+ byte iParamCount = *(pszPos + 3);
+ char* pszParam = pszPos + 4;
+ bool bSkip = true;
+
+ if (bKnownFileType == false) {
+ if (*pszParam == '*') {
+ bSkip = false;
+ } else {
+ for (byte i = 0; i < iParamCount; i++) {
+ char szParam[MAX_PARAM_LENGTH+1];
+ strncpy(szParam, pszParam, MAX_PARAM_LENGTH);
+ szParam[MAX_PARAM_LENGTH] = '\0';
+ char* pszTmp = strchr(szParam, ':');
+ if (pszTmp)
+ *pszTmp = '\0';
+
+ char* pszExt = strrchr(szName, '.');
+
+ if (pszExt && !_stricmp(pszExt + 1, szParam)) {
+ bSkip = false;
+ break;
+ }
+ pszParam += MAX_PARAM_LENGTH;
+ }
+ }
+ }
+
+ if (bSkip) {
+ RelativeJump(pszLevelBegin[iLevel-1]);
+ } else {
+ bKnownFileType = true;
+ pszPos += 2;
+ pszPos += 1;
+ pszPos += *(pszPos) * MAX_PARAM_LENGTH;
+ }
+ break;
+ }
+
+ default: {
+ *(pszBuffer++) = *pszPos;
+ }
+ }
+
+ pszPos++;
+
+ // flush the buffer from time to time
+ if (*pszPos == '\0' || pszBuffer - szBuffer > 8000) {
+ if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
+ break;
+
+ pszBuffer = szBuffer;
+ }
+ } while (*pszPos != '\0');
+
+ if (hFind != 0)
+ FindClose(hFind);
+
+ SetEndOfFile(hFile);
+ CloseHandle(hFile);
+ return TRUE;
+} \ No newline at end of file
diff --git a/plugins/HTTPServer/src/IndexXML.cpp b/plugins/HTTPServer/src/IndexXML.cpp
new file mode 100644
index 0000000000..15c86c5c40
--- /dev/null
+++ b/plugins/HTTPServer/src/IndexXML.cpp
@@ -0,0 +1,255 @@
+//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"
+
+static const char szXmlHeader1[] = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
+ "<?xml-stylesheet type=\"text/xsl\" href=\"";
+
+static const char szXmlHeader2[] = "\"?>\r\n"
+ "<config>\r\n";
+
+static const char szXmlTail[] = "</config>";
+
+
+static void ReplaceSign(char* pszSrc, int MaxLength, const char pszReplace,
+ const char * pszNew) {
+ static char szBuffer[1024];
+ char* pszSign = strchr(pszSrc, pszReplace);
+
+ if (pszSign) {
+ strcpy(szBuffer, pszSrc);
+
+ do {
+ strcpy(szBuffer + (pszSign - pszSrc), pszNew);
+ strcpy(szBuffer + (pszSign - pszSrc) + strlen(pszNew), pszSign + 1);
+ *pszSign = ' ';
+
+ } while (pszSign = strchr(pszSrc, pszReplace));
+
+ strncpy(pszSrc, szBuffer, MaxLength);
+
+ pszSrc[MaxLength-1] = '\0';
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Member Function : bCreateIndexXML
+// Type : Global
+// Parameters : pszRealPath - ?
+// Returns :
+// Description :
+//
+// References : -
+// Remarks : -
+// Created : 050821, 05 august 2005
+// Developer : Houdini
+/////////////////////////////////////////////////////////////////////
+
+bool bCreateIndexXML(const char * pszRealPath, const char * pszIndexPath,
+ const char * pszSrvPath, DWORD dwRemoteIP) {
+ char szMask[MAX_PATH+1];
+ strcpy(szMask, pszRealPath);
+ strcat(szMask, "*");
+
+ WIN32_FIND_DATAA fdFindFileData;
+ HANDLE hFind = FindFirstFile(szMask, &fdFindFileData);
+
+ if (hFind == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ HANDLE hFile = CreateFile(pszIndexPath, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ FindClose(hFind);
+ return FALSE;
+ }
+
+ const int BUFFER_SIZE = 1000;
+ char szBuffer[BUFFER_SIZE+1];
+ char* pszBuffer = szBuffer;
+ char szFileName[MAX_PATH+1] = "";
+ char* pszExt;
+ DWORD dwBytesWritten = 0;
+
+ // Generate Dirname
+ strcpy(szBuffer, pszSrvPath);
+ char* pszTemp = strrchr(szBuffer, '/');
+ if (pszTemp)
+ *pszTemp = '\0';
+
+ pszTemp = strrchr(szBuffer, '/');
+ if (pszTemp)
+ strcpy(szFileName, pszTemp + 1);
+
+ // Write Header
+ WriteFile(hFile, szXmlHeader1, sizeof(szXmlHeader1) - 1, &dwBytesWritten, NULL);
+
+ // check if a index.xsl exists in the same directory otherwise use the global
+ strcpy(szMask, pszRealPath);
+ strcat(szMask, "index.xsl");
+
+ HANDLE hFileExists = CreateFile(szMask, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hFileExists == INVALID_HANDLE_VALUE) {
+ strcpy(szBuffer, "/index.xsl");
+ } else {
+ CloseHandle(hFileExists);
+ strcpy(szBuffer, "index.xsl");
+ }
+
+ WriteFile(hFile, szBuffer, strlen(szBuffer), &dwBytesWritten, NULL);
+
+ WriteFile(hFile, szXmlHeader2, sizeof(szXmlHeader2) - 1, &dwBytesWritten, NULL);
+
+ // Write dirname
+ ReplaceSign(szFileName, MAX_PATH, '&', "&amp;");
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ " <dirname>%s</dirname>\r\n", szFileName);
+ WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL);
+
+ // Find files and directories
+ do {
+ if (strcmp(fdFindFileData.cFileName, ".") &&
+ strncmp(fdFindFileData.cFileName, "@", 1) &&
+ (strcmp(fdFindFileData.cFileName, "..") || strcmp(pszSrvPath, "/"))) { // hide .. in root
+ pszBuffer = szBuffer;
+
+ strcpy(szFileName, fdFindFileData.cFileName);
+ ReplaceSign(szFileName, MAX_PATH, '&', "&amp;");
+
+ if (fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ " <item name=\"%s\" isdir=\"true\"/>\r\n", szFileName);
+ } else {
+ pszExt = strrchr(szFileName, '.');
+
+ if (pszExt != NULL) {
+ *pszExt = '\0';
+ pszExt++;
+ }
+
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ " <item name=\"%s\" ext=\"%s\" size=\"%i\" ",
+ szFileName, (pszExt == NULL) ? "" : pszExt, fdFindFileData.nFileSizeLow);
+
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime(&fdFindFileData.ftCreationTime, &systemTime);
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "created=\"%i/%02i/%02i %i:%02i:%02i\" ",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
+ systemTime.wMinute, systemTime.wSecond);
+
+ FileTimeToSystemTime(&fdFindFileData.ftLastWriteTime, &systemTime);
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "modified=\"%i/%02i/%02i %i:%02i:%02i\" ",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
+ systemTime.wMinute, systemTime.wSecond);
+
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "/>\r\n");
+ }
+
+ if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
+ break;
+ }
+
+ } while (FindNextFile(hFind, &fdFindFileData));
+
+ if (hFind != 0)
+ FindClose(hFind);
+
+ // Add other shared files & directories
+ for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) {
+ if (!((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask) && // hide inaccessible shares
+ (size_t)(pclCur->nGetSrvPathLen()) > strlen(pszSrvPath) &&
+ !strstr(pclCur->st.pszRealPath, "\\@") &&
+ !strncmp(pclCur->st.pszSrvPath, pszSrvPath, strlen(pszSrvPath))) {
+ pszBuffer = szBuffer;
+
+ strcpy(szFileName, &pclCur->st.pszSrvPath[strlen(pszSrvPath)]);
+ ReplaceSign(szFileName, MAX_PATH, '&', "&amp;");
+
+ if (pclCur->bIsDirectory()) {
+ szFileName[strlen(szFileName)-1] = '\0';
+ if (!strchr(szFileName, '/')) { // only one level deeper
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ " <item name=\"%s\" isdir=\"true\"/>\r\n", szFileName);
+
+ if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
+ break;
+ }
+ } else {
+ if (!strchr(szFileName, '/') && // only one level deeper
+ strncmp(pszRealPath, pclCur->st.pszRealPath, strlen(pszRealPath))) { // no duplicates
+ pszExt = strrchr(szFileName, '.');
+
+ if (pszExt != NULL) {
+ *pszExt = '\0';
+ pszExt++;
+ }
+
+ DWORD dwFileSize = 0;
+ FILETIME ftFileCreateTime;
+ FILETIME ftFileAccessTime;
+ FILETIME ftFileModifyTime;
+ HANDLE hFileS = CreateFile(pclCur->st.pszRealPath, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFileS != INVALID_HANDLE_VALUE) {
+ dwFileSize = GetFileSize(hFileS, NULL);
+ GetFileTime(hFileS, &ftFileCreateTime, &ftFileAccessTime, &ftFileModifyTime);
+ CloseHandle(hFileS);
+ }
+
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ " <item name=\"%s\" ext=\"%s\" size=\"%i\" ",
+ szFileName, (pszExt == NULL) ? "" : pszExt, dwFileSize);
+
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime(&ftFileCreateTime, &systemTime);
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "created=\"%i/%02i/%02i %i:%02i:%02i\" ",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
+ systemTime.wMinute, systemTime.wSecond);
+
+ FileTimeToSystemTime(&ftFileModifyTime, &systemTime);
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "modified=\"%i/%02i/%02i %i:%02i:%02i\" ",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
+ systemTime.wMinute, systemTime.wSecond);
+
+ pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer),
+ "/>\r\n");
+
+ if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
+ break;
+ }
+ }
+ }
+ }
+
+ WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWritten, NULL);
+
+ SetEndOfFile(hFile);
+ CloseHandle(hFile);
+
+ return TRUE;
+} \ No newline at end of file
diff --git a/plugins/HTTPServer/src/MimeHandling.cpp b/plugins/HTTPServer/src/MimeHandling.cpp
new file mode 100644
index 0000000000..42964bfeb3
--- /dev/null
+++ b/plugins/HTTPServer/src/MimeHandling.cpp
@@ -0,0 +1,147 @@
+#include "Glob.h"
+
+/* MIME type/ext map */
+ContentTypeDB MIME = NULL;
+/* Default Mime type when recognition fails */
+char DefaultMime[] = "application/octet-stream";
+
+int bInitMimeHandling() {
+ FILE *mimeDB;
+ char line[LINE_MAX_SIZE];
+ char *tok = NULL;
+ int lenght;
+ ContentType *pDBCell = NULL;
+ ContentTypeDB pDB = NULL;
+ ExtensionList extListCur = NULL;
+ ExtensionListCell *pExtCell = NULL;
+ char szBuf[10000];
+
+ strcpy(szBuf, szPluginPath);
+ strcat(szBuf, szMimeTypeConfigFile);
+ mimeDB = fopen(szBuf, "r");
+
+ if (mimeDB != NULL) {
+ while (fgets(line, LINE_MAX_SIZE, mimeDB)) {
+ /*filter junk lines assuming Mime type start with letter
+ (convention ?) */
+ if ((line[0] <= 'z' && line[0] >= 'a')
+ || (line[0] <= 'Z' && line[0] >= 'A')) {
+ /*remove comments trailing comments*/
+ tok = strrchr(line, '#');
+ if (tok != NULL) {
+ *tok = '\0';
+ }
+ /* remove trailing \n */
+ lenght = strlen(line);
+ if (lenght > 0 && line[lenght - 1] == '\n') {
+ line[lenght - 1] = '\0';
+ }
+ /* first token = mime type */
+ tok = (char*)strtok(line, " \t");
+ /*create and fill a cell*/
+ pDBCell = (ContentType*)malloc(sizeof(ContentType));
+ pDBCell->mimeType = (char*)malloc(strlen(tok) + 1);
+ strcpy(pDBCell->mimeType, tok);
+ pDBCell->extList = NULL;
+ pDBCell->next = NULL;
+ /* looking for extensions */
+ tok = (char*)strtok(NULL, " \t");
+ while (tok != NULL) {
+ /*create and fill a cell*/
+ pExtCell = (ExtensionListCell*)malloc(sizeof(ExtensionListCell));
+ pExtCell->ext = (char*)malloc(strlen(tok) + 1);
+ strcpy(pExtCell->ext, tok);
+ pExtCell->next = NULL;
+ /*link*/
+ if (pDBCell->extList == NULL) {
+ pDBCell->extList = pExtCell;
+ } else {
+ extListCur->next = pExtCell;
+ }
+ extListCur = pExtCell;
+ tok = (char*)strtok(NULL, " \t");
+ }
+ /* link */
+ if (pDBCell->extList != NULL) { /*extension(s) found*/
+ if (MIME == NULL) {
+ MIME = pDBCell;
+ } else {
+ pDB->next = pDBCell;
+ }
+ pDB = pDBCell;
+ } else { /*no extension found, freeing memory*/
+ free(pDBCell->mimeType);
+ free(pDBCell);
+ }
+ }
+ }
+
+ fclose(mimeDB);
+ }
+ if (MIME == NULL) {
+ return 0;
+ }
+ return 1;
+}
+
+const char * pszGetMimeType(const char * pszFileName) {
+ ContentTypeDB courMIME;
+ ExtensionList courEXT;
+ const char* ext;
+
+ ext = strrchr(pszFileName, '.');
+
+ if (ext != NULL) {
+ if (ext[1] == '\0') {
+ /*empty extension */
+ return DefaultMime;
+ } else {
+ /*remove the "."*/
+ ext = ext + 1;
+ }
+
+ courMIME = MIME;
+ while (courMIME != NULL) {
+ courEXT = courMIME->extList;
+ while (courEXT != NULL) {
+ if (!_stricmp(courEXT->ext, ext)) {
+ return courMIME->mimeType;
+ }
+ courEXT = courEXT->next;
+ }
+ courMIME = courMIME->next;
+ }
+ /*extension unknown*/
+ return DefaultMime;
+ } else {
+ /*no extension*/
+ return DefaultMime;
+ }
+}
+
+
+#ifdef TEST
+void printDB() {
+ ContentTypeDB courMIME;
+ ExtensionList courEXT;
+
+ courMIME = MIME;
+ while (courMIME != NULL) {
+ printf("%s", courMIME->mimeType);
+ courEXT = courMIME->extList;
+ while (courEXT != NULL) {
+ printf(" %s", courEXT->ext);
+ courEXT = courEXT->next;
+ }
+ courMIME = courMIME->next;
+ printf("\n");
+ }
+}
+
+int main(int argc, char* argv[]) {
+ bInitMimeHandling();
+ printDB();
+ printf("%s\n", pszGetMimeType(argv[1]));
+ return 0;
+}
+#endif
diff --git a/plugins/HTTPServer/src/MimeHandling.h b/plugins/HTTPServer/src/MimeHandling.h
new file mode 100644
index 0000000000..f40fdf94c8
--- /dev/null
+++ b/plugins/HTTPServer/src/MimeHandling.h
@@ -0,0 +1,52 @@
+#define LINE_MAX_SIZE 512
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define szMimeTypeConfigFile "HTTPMimeTypes"
+
+ /* MIME DB Data structure
+
+ ---------- ----------
+ | mimeType | | mimeType |
+ |----------| |----------|
+ ----| next -----------------| next |
+ |----------| |----------|
+ | extList --- | extList ---
+ ---------- | ---------- |
+ --|--- --|---
+ | ext | | ext |
+ |------| |------|
+ | next | | next |
+ --|--- ------
+ --|---
+ | ext |
+ |------|
+ | next |
+ ------
+ */
+
+ typedef struct _ExtensionListCell {
+ char* ext;
+ struct _ExtensionListCell* next;
+ } ExtensionListCell ;
+
+
+ typedef struct _ContentType {
+ char* mimeType;
+ ExtensionListCell* extList;
+ struct _ContentType* next;
+ } ContentType ;
+
+ typedef ContentType* ContentTypeDB;
+ typedef ExtensionListCell* ExtensionList;
+
+
+
+ extern int bInitMimeHandling();
+ extern const char * pszGetMimeType(const char * pszFileName);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/plugins/HTTPServer/src/m_HTTPServer.h b/plugins/HTTPServer/src/m_HTTPServer.h
new file mode 100644
index 0000000000..6cb6549ee0
--- /dev/null
+++ b/plugins/HTTPServer/src/m_HTTPServer.h
@@ -0,0 +1,105 @@
+//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.
+
+
+#ifndef M_HTTP_SERVER_H
+#define M_HTTP_SERVER_H
+
+
+#define OPT_SEND_LINK 0x1
+
+
+typedef struct {
+ DWORD lStructSize; // Set to sizeof(STFileShareInfo)
+ char * pszSrvPath; // Server path
+ DWORD dwMaxSrvPath; // Buffer allocated for Server path only used when information is requested from HTTP server.
+ char * pszRealPath; // Real path can be relative or complete
+ DWORD dwMaxRealPath;// Buffer allocated for Real path only used when information is requested from HTTP server.
+ DWORD dwAllowedIP; // The IP address which is allowed to access this share
+ DWORD dwAllowedMask; // A mask which is applied to IP address to allow other IP addresses
+ int nMaxDownloads; // The maximum number of download which can be made on this share.
+ DWORD dwOptions; // Use OPT_SEND_LINK to open a message window with the link to file
+} STFileShareInfo, * LPSTFileShareInfo;
+
+// dwMaxSrvPath Specifies the size, in chars, of the buffer pointed to by pszSrvPath.
+// The buffer must be large enough to store the path and file name string,
+// including the terminating null character.
+
+
+/////////////////////////////////////////////
+/// Service MS_HTTP_ADD_CHANGE_REMOVE ///
+/////////////////////////////////////////////
+//
+// wParam = (WPARAM)0
+// lParam = (LPARAM)LPSTFileShareInfo;
+// Server path is the key when working with FileShareInfo.
+// Two files can not be shared with the same "Server path" in the HTTP server.
+// If the server path does not exists it will be added.
+// If it does exists the action depends on what real path is.
+// If real path is empty the entity will be removed else it
+// will just be updated with the new settings.
+
+//
+// returns 0 on success, nonzero on failure
+#define MS_HTTP_ADD_CHANGE_REMOVE "HTTPServer/AddChangeRemove"
+
+
+/////////////////////////////////////////////
+////// Service MS_HTTP_GET_SHARE //////
+/////////////////////////////////////////////
+//
+// wParam = (WPARAM)0;
+// lParam = (LPARAM)LPSTFileShareInfo;
+// Returns the information for a share
+// Server path must be set the the share you wish information for.
+//
+// returns 0 on success, nonzero on failure
+
+#define MS_HTTP_GET_SHARE "HTTPServer/GetShare"
+
+
+
+/////////////////////////////////////////////
+/// Service MS_HTTP_ACCEPT_CONNECTIONS ///
+/////////////////////////////////////////////
+//
+// wParam = (WPARAM)boolean(true/false);
+// lParam = (LPARAM)0;
+// Toggles the HTTP server state if wParam is FALSE
+// Force enable HTTP server if wParam is TRUE
+// returns 0 on success, nonzero on failure
+
+#define MS_HTTP_ACCEPT_CONNECTIONS "HTTPServer/AcceptConnections"
+
+/////////////////////////////////////////////
+//// Service MS_HTTP_GET_ALL_SHARES /////
+/////////////////////////////////////////////
+//
+// wParam = (WPARAM)0;
+// lParam = (LPARAM)&LPSTFileShareInfo;
+// Returns an array of all currently shared files in the HTTP Server
+// LPSTFileShareInfo points to the first share.
+// You must free the memory returned by using the miranda MS_SYSTEM_GET_MMI
+// and calling MM_INTERFACE->free( LPSTFileShareInfo )
+//
+// returns the count of shares in the buffer pointed to by LPSTFileShareInfo
+
+#define MS_HTTP_GET_ALL_SHARES "HTTPServer/GetAllShares"
+
+
+
+#endif
diff --git a/plugins/HTTPServer/src/main.cpp b/plugins/HTTPServer/src/main.cpp
new file mode 100644
index 0000000000..44ff4279c8
--- /dev/null
+++ b/plugins/HTTPServer/src/main.cpp
@@ -0,0 +1,974 @@
+//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[] = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
+ "<?xml-stylesheet type=\"text/xsl\" href=\"HTTPServer.xsl\"?>\r\n"
+ "<config>\r\n";
+
+const char szXmlData[] = "\t<share>\r\n"
+ "\t\t<name>%s</name>\r\n"
+ "\t\t<file>%s</file>\r\n"
+ "\t\t<max_downloads>%d</max_downloads>\r\n"
+ "\t\t<ip_address>%d.%d.%d.%d</ip_address>\r\n"
+ "\t\t<ip_mask>%d.%d.%d.%d</ip_mask>\r\n"
+ "\t</share>\r\n";
+
+const char szXmlTail[] = "</config>";
+
+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;
+
+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;
+
+bool bShutdownInProgress = false;
+
+int hLangpack = 0;
+
+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://addons.miranda-im.org/details.php?action=viewfile&id=2304",
+ 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 = 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, _T("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, _T("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 = 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, _T("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, "<share>")) != 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];
+ 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, _T("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, _T("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, _T("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, _T("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 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[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 (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 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(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) {
+ //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);
+ /*
+ 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
+/////////////////////////////////////////////////////////////////////
+
+INT_PTR 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)) {
+ Netlib_LogfT(hNetlibUser, _T("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), _T("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.ptszName = LPGENT("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.ptszName = LPGENT("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)
+ 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*/) {
+ /*
+ 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_TCHAR;
+ nlu.szSettingsModule = MODULE;
+ nlu.ptszDescriptiveName = _T("HTTP Server");
+ hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu);
+ if (!hNetlibUser) {
+ MessageBox(NULL, _T("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*/) {
+ if (hEventProtoAck)
+ UnhookEvent(hEventProtoAck);
+
+ while (pclFirstNode) {
+ CLFileShareNode * pclCur = pclFirstNode;
+ pclFirstNode = pclFirstNode->pclNext;
+ delete pclCur;
+ }
+ pclFirstNode = NULL;
+
+ if (hEventSystemInit) {
+ UnhookEvent(hEventSystemInit);
+ hEventSystemInit = 0;
+ }
+ UnInitGuiElements();
+
+ db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode);
+ FreeIndexHTMLTemplate();
+
+ return 0;
+}
+
+ /////////////////////////////////////////////////////////////////////
+ // Member Function : MirandaPluginInfoEx & MirandaPluginInterfaces
+ // 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);
+ InitializeCriticalSection(&csFileShareListAccess);
+
+ hHttpAcceptConnectionsService = CreateServiceFunction(MS_HTTP_ACCEPT_CONNECTIONS, nToggelAcceptConnections);
+ if (! hHttpAcceptConnectionsService) {
+ MessageBox(NULL, _T("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, _T("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, _T("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, _T("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, _T("Failed to HookEvent ME_SYSTEM_MODULESLOADED"), MSG_BOX_TITEL, MB_OK);
+ return 0;
+ }
+
+ hPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+ if (!hPreShutdown) {
+ MessageBox(NULL, _T("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
+ db_set_s(NULL, "Uninstall", "HTTPServer", MODULE);
+
+ 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)) {
+ CLISTMENUITEM mi;
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIF_TCHAR;
+ mi.pszContactOwner = NULL; //all contacts
+ mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE));
+ mi.position = 1000085000;
+ mi.pszName = LPGENT("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);
+ return 0;
+ } \ No newline at end of file
diff --git a/plugins/HTTPServer/src/resource.h b/plugins/HTTPServer/src/resource.h
new file mode 100644
index 0000000000..940253e98e
--- /dev/null
+++ b/plugins/HTTPServer/src/resource.h
@@ -0,0 +1,56 @@
+//{{NO_DEPENDENCIES}}
+// Âêëþ÷àåìûé ôàéë, ñîçäàííûé â Microsoft Visual C++.
+// Èñïîëüçóåòñÿ D:\MNG_orig\plugins\HTTPServer\res\resource.rc
+//
+#define IDD_NEW_SHARE_PROPERTIES 101
+#define IDI_DISABLE_SERVER 101
+#define IDI_SHARE_NEW_FILE 102
+#define IDD_STATISTICS_VIEW 123
+#define IDR_MENU1 124
+#define IDD_OPT_HTTP_SERVER 999
+#define IDC_SPELL_TEXT 1066
+#define IDC_MAX_DOWNLOADS 1067
+#define IDC_ALLOWED_IPADDRESS 1068
+#define IDC_ALLOWED_IP_MASK 1069
+#define IDC_SHARE_NAME 1070
+#define IDC_CURRENT_SHARES 1071
+#define IDC_CURRENT_USERS 1072
+#define IDC_EXTERNAL_SRV_NAME 1073
+#define IDC_ADD_STATISTICS_MENU_ITEM 1074
+#define IDC_EXTERNAL_SRV_DEFAULT 1075
+#define IDC_WRITE_LOG_FILE 1076
+#define IDC_ACCEPT_COM_MENU_ITEM 1078
+#define IDC_TOGGLE_MASK 1080
+#define IDC_OPEN_LOG 1081
+#define IDC_SHOW_POPUPS 1082
+#define IDC_URL_ADDRESS 1085
+#define IDC_PAGE_KEYWORD 1087
+#define IDC_TEST_EXTERNALIP 1088
+#define IDC_MAX_SPEED 1090
+#define IDC_LIMIT_ONLY_WHEN_ONLINE 1091
+#define IDC_BUTTON1 1092
+#define IDC_MAX_SPEED2 1092
+#define IDC_DEFAULT_DOWNLOAD_LIMIT 1092
+#define IDC_SHOWHIDDENSHARES 1093
+#define IDC_INDEX_OFF 1094
+#define IDC_INDEX_HTML 1095
+#define IDC_INDEX_XML 1096
+#define IDC_INDEX_DETECT 1097
+#define IDC_MAX_CONN_TOTAL 1098
+#define IDC_MAX_CONN_PER_USER 1099
+#define ID_SHARELIST_OPEN 40004
+#define ID_SHARELIST_REMOVESHARE 40005
+#define ID_SHARELIST_COPYLINK 40006
+#define ID_SHARELIST_NEWSHARE 40007
+#define ID_SHARELIST_EDITSHARE 40008
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 126
+#define _APS_NEXT_COMMAND_VALUE 40009
+#define _APS_NEXT_CONTROL_VALUE 1095
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif