From 7980e2c9af0e1c1bf6f53d0d14df8872752f7e17 Mon Sep 17 00:00:00 2001
From: gaebor
Date: Sat, 10 Mar 2018 09:44:25 +0100
Subject: [PATCH 1/7] snprintf
---
httppil.h | 4 ++--
processpil.c | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/httppil.h b/httppil.h
index e829a87..2be1c5c 100644
--- a/httppil.h
+++ b/httppil.h
@@ -18,7 +18,6 @@
#ifdef WINCE
#include
#include
-#define snprintf _snprintf
#elif defined(WIN32)
#include
@@ -26,8 +25,9 @@
#include
#include
+#if _MSC_VER < 1900
#define snprintf _snprintf
-
+#endif
#else
#include
#include
diff --git a/processpil.c b/processpil.c
index d10b80b..67bc9eb 100644
--- a/processpil.c
+++ b/processpil.c
@@ -7,7 +7,9 @@
#ifdef WIN32
#include
#include
+#if _MSC_VER < 1900
#define snprintf _snprintf
+#endif
#else
#include
#include
From b86f393c89ac60dc8cc7d63ef3c19d8d10c203be Mon Sep 17 00:00:00 2001
From: gaebor
Date: Sat, 10 Mar 2018 09:46:43 +0100
Subject: [PATCH 2/7] dynamic plugin system
---
Makefile.mak | 52 +++++++++++++++++
Plugin.md | 39 +++++++++++++
loadplugin.c | 124 +++++++++++++++++++++++++++++++++++++++++
loadplugin.h | 17 ++++++
miniweb.c | 64 ++++++++++++---------
plugin/plugin.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 414 insertions(+), 27 deletions(-)
create mode 100644 Makefile.mak
create mode 100644 Plugin.md
create mode 100644 loadplugin.c
create mode 100644 loadplugin.h
create mode 100644 plugin/plugin.c
diff --git a/Makefile.mak b/Makefile.mak
new file mode 100644
index 0000000..715a284
--- /dev/null
+++ b/Makefile.mak
@@ -0,0 +1,52 @@
+CC=cl
+LD=link
+ALLFLAGS=/O2 /W3 /Ilibctb/include /nologo /MT /DNDEBUG
+CFLAGS=$(ALLFLAGS) /TC
+CPPFLAGS=$(ALLFLAGS) /TP /EHsc
+HTTPOBJ=httppil.obj http.obj httpxml.obj httphandler.obj httppost.obj httpauth.obj loadplugin.obj
+HEADERS=httpint.h httpapi.h httpxml.h
+
+OUTDIR=bin\\
+
+DEFINES= /D_CRT_SECURE_NO_DEPRECATE /DNDEBUG /DNODEBUG /DWIN32
+LDFLAGS= WSock32.Lib shell32.lib Iphlpapi.lib
+
+!ifdef ENABLE_SERIAL
+HTTPOBJ=$(HTTPOBJ) httpserial.obj libctb/src/fifo.obj libctb/src/serportx.obj
+HEADERS=$(HEADERS) httpserial.h
+DEFINES=$(DEFINES) /Ilibctb/include
+!endif
+
+default: miniweb
+
+miniweb: miniweb.exe
+
+min: $(HTTPOBJ) httpmin.obj
+ $(LD) $(LDFLAGS) $(HTTPOBJ) httpmin.obj /OUT:$(OUTDIR)httpmin.exe
+
+miniweb.exe: $(HTTPOBJ) miniweb.obj
+ $(LD) $(LDFLAGS) $(HTTPOBJ) miniweb.obj /OUT:$(OUTDIR)miniweb.exe
+
+all : miniweb postfile plugin
+
+must_build:
+
+postfile : must_build
+ $(CC) $(CFLAGS) $(DEFINES) /Ipostfile postfile/*.c /link $(LDFLAGS) /OUT:$(OUTDIR)postfile.exe
+
+plugin : must_build
+ $(CC) $(CFLAGS) /I. $(DEFINES) plugin/plugin.c /link $(LDFLAGS) /DLL /OUT:$(OUTDIR)plugin.dll
+
+.c.obj::
+ $(CC) $(DEFINES) $(CFLAGS) $<
+
+.cpp.obj::
+ $(CC) $(DEFINES) $(CPPFLAGS) $<
+
+clean:
+ del /Q *.obj
+ del /Q $(OUTDIR)*.exe
+ del /Q $(OUTDIR)*.obj
+ del /Q $(OUTDIR)*.dll
+ del /Q $(OUTDIR)*.lib
+
diff --git a/Plugin.md b/Plugin.md
new file mode 100644
index 0000000..14431ba
--- /dev/null
+++ b/Plugin.md
@@ -0,0 +1,39 @@
+# Miniweb plugin sytem
+To add a plugin just use a C dynamic library interface.
+See `plugin.c`
+
+## How to write plugin
+Compile your plugin in a separate binary.
+
+The C interface:
+
+ int YourUrlHandler(UrlHandlerParam* param); // PFNURLCALLBACK
+ int YourUrlHandlerEvent(MW_EVENT msg, int argi, void* argp) // PFNEVENTHANDLER
+
+The second is optional.
+
+See `plugin`
+
+ nmake /F Makefile.mak plugin
+
+## Usage
+From command line:
+
+ bin\miniweb.exe -c "myplugin:bin\plugin.dll:MyUrlHandler|MyUrlHandlerEvent"
+
+This start the default `miniweb` but loads your plugin.
+You can have many `-c` arguments. See `miniweb -h`
+
+The plugin is registered with prefix `myplugin` which means that you can access it at http://localhost/myplugin
+
+### func1
+An other simple plugin example:
+
+ bin\miniweb.exe -c "func:bin\plugin.dll:func1"
+
+Go to http://localhost/func?v=dQw4w9WgXcQ
+
+This will parse and print the http request parameters.
+
+ [624] request path: func1?v=ZgQMW4eVrzw
+ v: "ZgQMW4eVrzw"
diff --git a/loadplugin.c b/loadplugin.c
new file mode 100644
index 0000000..27d9128
--- /dev/null
+++ b/loadplugin.c
@@ -0,0 +1,124 @@
+#include "loadplugin.h"
+
+#ifdef _MSC_VER
+# include
+#else
+# include
+#endif // _MSC_VER
+
+void* LoadDll(const char* arg)
+{
+#ifdef _MSC_VER
+ return LoadLibraryA(arg);
+#else
+ return dlopen(arg, RTLD_LAZY);
+#endif // _MSC_VER
+}
+
+int FreeDll(void* handle)
+{
+#ifdef _MSC_VER
+ return FreeLibrary((HANDLE)handle);
+#else
+ return dlclose(handle);
+#endif // _MSC_VER
+}
+
+const char* GetError()
+{
+#ifdef _MSC_VER
+ static char error[10];
+ sprintf_s(error, 10, "%d", GetLastError());
+ return error;
+#else
+ return dlerror();
+#endif // _MSC_VER
+}
+
+#ifdef _MSC_VER
+# define GetSymbol GetProcAddress
+#else
+# define GetSymbol dlsym
+#endif // _MSC_VER
+
+int get_handler_list_length(UrlHandler* urlHandlerList)
+{
+ int n = 0;
+ if (urlHandlerList)
+ for (n = 0; urlHandlerList[n].pchUrlPrefix; n++)
+ ;
+ return n;
+}
+
+void add_handler(UrlHandler** urlHandlerList, const char* prefix, PFNURLCALLBACK uhf, PFNEVENTHANDLER ehf)
+{
+ int n, length;
+ length = get_handler_list_length(*urlHandlerList);
+ UrlHandler* new_list = (UrlHandler*)calloc(length + 2, sizeof(UrlHandler));
+ if (new_list)
+ {
+ for (n = 0; n < length; ++n)
+ {
+ new_list[n] = (*urlHandlerList)[n];
+ }
+ new_list[n].pchUrlPrefix = prefix;
+ new_list[n].pfnUrlHandler = uhf;
+ new_list[n].pfnEventHandler = ehf;
+ new_list[n].p_sys = NULL;
+
+ new_list[n + 1].pchUrlPrefix = NULL;
+
+ free(*urlHandlerList);
+ *urlHandlerList = new_list;
+ }
+}
+
+void add_handler_from_dll(UrlHandler** urlHandlerList, const char* arg)
+{
+ char* name, *function_name, *prefix, *tmp, *event_handler_name;
+ void* library;
+ PFNEVENTHANDLER ehf = NULL;
+ PFNURLCALLBACK uhf;
+
+ name = malloc(strlen(arg) + 1);
+ strcpy(name, arg);
+ function_name = strrchr(name, ':');
+ prefix = strchr(name, ':');
+
+ if (prefix != NULL && function_name > prefix + 1)
+ {
+ *function_name = '\0';
+ ++function_name;
+ *prefix = '\0';
+ if (*function_name)
+ {
+ ++prefix;
+ tmp = prefix;
+ prefix = name;
+ name = tmp;
+ fprintf(stderr, "Loading handler... prefix: %s, dll: %s, function: %s\n", prefix, name, function_name);
+ library = LoadDll(name);
+ if (library)
+ {
+ event_handler_name = strrchr(function_name, '|');
+ if (event_handler_name)
+ *event_handler_name++ = '\0';
+ ehf = (PFNEVENTHANDLER)GetSymbol(library, event_handler_name);
+ uhf = (PFNURLCALLBACK)GetSymbol(library, function_name);
+ if (uhf)
+ add_handler(urlHandlerList, prefix, uhf, ehf);
+ else
+ {
+ fprintf(stderr, "couldn't load %s (Error: %s)!\n", function_name, GetError());
+ FreeDll(library);
+ }
+ }
+ else
+ fprintf(stderr, "couldn't load \"%s\" (Error: %s)!\n", name, GetError());
+ }
+ else
+ fprintf(stderr, "function name shouldn't be empty in \"%s\"!\n", arg);
+ }
+ else
+ fprintf(stderr, "Two colons should be in \"%s\"!\n", arg);
+}
diff --git a/loadplugin.h b/loadplugin.h
new file mode 100644
index 0000000..c6a12e2
--- /dev/null
+++ b/loadplugin.h
@@ -0,0 +1,17 @@
+#ifndef _LOADPLUGIN_H_
+#define _LOADPLUGIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "httpapi.h"
+
+void add_handler(UrlHandler** urlHandlerList, const char* prefix, PFNURLCALLBACK uhf, PFNEVENTHANDLER ehf);
+void add_handler_from_dll(UrlHandler** urlHandlerList, const char* arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/miniweb.c b/miniweb.c
index 3c92a81..5d86f09 100644
--- a/miniweb.c
+++ b/miniweb.c
@@ -11,6 +11,7 @@
#include
#include "httppil.h"
#include "httpapi.h"
+#include "loadplugin.h"
#include "revision.h"
#ifdef MEDIA_SERVER
#include "mediaserver.h"
@@ -39,33 +40,6 @@ int uhAsyncDataTest(UrlHandlerParam* param);
int uhRTSP(UrlHandlerParam* param);
int uhSerial(UrlHandlerParam* param);
-UrlHandler urlHandlerList[]={
- {"stats", uhStats, NULL},
-#ifdef ENABLE_SERIAL
- {"serial", uhSerial, NULL},
-#endif
-#ifdef HAVE_THREAD
- {"async", uhAsyncDataTest, NULL},
-#endif
-#ifdef MEDIA_SERVER
- {"test.sdp", uhRTSP, NULL},
- {"MediaServer/VideoItems/", uhMediaItemsTranscode, ehMediaItemsEvent},
-#endif
-#ifdef _7Z
- {"7z", uh7Zip, NULL},
-#endif
-#ifdef _MPD
- {"mpd", uhMpd, ehMpd},
-#endif
-#ifdef _VOD
- {"vodstream", uhVodStream,NULL},
- {"vodlib", uhLib,0},
- {"vodplay", uhVod,ehVod},
- {"stream", uhStream,NULL},
-#endif
- {NULL},
-};
-
#ifndef DISABLE_BASIC_WWWAUTH
AuthHandler authHandlerList[]={
{"stats", "user", "pass", "group=admin", ""},
@@ -289,8 +263,34 @@ static int print_interfaces(const char *prefix, int port)
#endif
+UrlHandler* urlHandlerList = NULL;
+
int cc_main(int argc,char* argv[])
{
+ add_handler(&urlHandlerList, "stats", uhStats, NULL);
+#ifdef ENABLE_SERIAL
+ add_handler(&urlHandlerList, "serial", uhSerial, NULL);
+#endif
+#ifdef HAVE_THREAD
+ add_handler(&urlHandlerList, "async", uhAsyncDataTest, NULL);
+#endif
+#ifdef MEDIA_SERVER
+ add_handler(&urlHandlerList, "test.sdp", uhRTSP, NULL);
+ add_handler(&urlHandlerList, "MediaServer/VideoItems/", uhMediaItemsTranscode, ehMediaItemsEvent);
+#endif
+#ifdef _7Z
+ add_handler(&urlHandlerList, "7z", uh7Zip, NULL);
+#endif
+#ifdef _MPD
+ add_handler(&urlHandlerList, "mpd", uhMpd, ehMpd);
+#endif
+#ifdef _VOD
+ add_handler(&urlHandlerList, "vodstream", uhVodStream, NULL);
+ add_handler(&urlHandlerList, "vodlib", uhLib, 0);
+ add_handler(&urlHandlerList, "vodplay", uhVod, ehVod);
+ add_handler(&urlHandlerList, "stream", uhStream, NULL);
+#endif
+
fprintf(stderr,"%s https://github.com/avih/miniweb (built on %s)\n"
"Originally: (C)2005-2013 Written by Stanley Huang \n\n",
APP_NAME, __DATE__);
@@ -341,6 +341,9 @@ int cc_main(int argc,char* argv[])
" -s : specifiy download speed limit in KB/s [default: none]\n"
" -n : disallow multi-part download [default: allow]\n"
" -d : disallow directory listing [default: allow]\n\n"
+ " -c : register callback for urlHandler\n"
+ " : format is the following \"prefix:dll:urlhandler|eventhandler\"\n"
+ " : event handler is optional, prefix may be empty\n"
);
fflush(stderr);
exit(1);
@@ -373,6 +376,13 @@ int cc_main(int argc,char* argv[])
case 'd':
httpParam.flags &= ~FLAG_DIR_LISTING;
break;
+ case 'c':
+ if ((++i) < argc)
+ {
+ add_handler_from_dll(&urlHandlerList, argv[i]);
+ httpParam.pxUrlHandler = urlHandlerList;
+ }
+ break;
}
}
}
diff --git a/plugin/plugin.c b/plugin/plugin.c
new file mode 100644
index 0000000..f3c8451
--- /dev/null
+++ b/plugin/plugin.c
@@ -0,0 +1,145 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include "httpapi.h"
+
+#define DLL_EXPORT __declspec(dllexport)
+
+char* mwGetVarValue(HttpVariables* vars, const char *varname, const char *defval)
+{
+ int i;
+ if (vars && varname) {
+ for (i = 0; (vars + i)->name; i++) {
+ if (!strcmp((vars + i)->name, varname)) {
+ return (vars + i)->value;
+ }
+ }
+ }
+ return (char*)defval;
+}
+
+DLL_EXPORT int func1(UrlHandlerParam* hp)
+{
+ int ret = 0;
+ int i;
+ for (i = 0; i < hp->iVarCount; ++i)
+ printf("%s: \"%s\"\n", hp->pxVars[i].name, hp->pxVars[i].value);
+ return ret;
+}
+
+static HttpParam httpParam;
+
+static int fdStream;
+
+DLL_EXPORT int StreamHandlerEvent(MW_EVENT msg, int argi, void* argp)
+{
+ switch (msg) {
+ case MW_INIT:
+ fdStream = _open("test.txt", _O_BINARY | _O_RDONLY);
+ break;
+ case MW_UNINIT:
+ _close(fdStream);
+ break;
+ }
+ return 0;
+}
+
+DLL_EXPORT int StreamHandler(UrlHandlerParam* param)
+{
+ param->dataBytes = _read(fdStream, param->pucBuffer, param->dataBytes);
+ param->fileType = HTTPFILETYPE_TEXT;
+ return FLAG_DATA_STREAM | FLAG_CONN_CLOSE;
+}
+
+struct {
+ int ethif;
+ char ip[16];
+ int mode;
+ char tvmode[4];
+} cfgdata;
+
+DLL_EXPORT int MyUrlHandlerEvent(MW_EVENT msg, int argi, void* argp)
+{
+ switch (msg) {
+ case MW_INIT:
+ memset(&cfgdata, 0, sizeof(cfgdata));
+ strcpy(cfgdata.ip, "192.168.0.100");
+ cfgdata.tvmode[0] = 1;
+ cfgdata.tvmode[1] = 1;
+ break;
+ case MW_UNINIT:
+ //nothing to uninit
+ break;
+ }
+ return 0; //0 on success, -1 on failure
+}
+
+DLL_EXPORT int MyUrlHandler(UrlHandlerParam* param)
+{
+ static const char *html_head = "STB Configuration
";
+ static const char *html_form_start = "
";
+ static const char *html_mode[] = {
+ "Startup Mode:
" };
+ static const char *html_tvmode[] = {
+ "TV Mode Supported: PAL ",
+ "NTSC ",
+ "720p ",
+ "1080i
" };
+ static const char *html_form_end = "
";
+ static const char *html_tail = "";
+ static const char *tvmodes[] = { "PAL", "NTSC", "720p", "1080i" };
+ char *p = param->pucBuffer, *v;
+ int i;
+
+ if (param->pxVars) {
+ // processing settings
+ if ((v = mwGetVarValue(param->pxVars, "if", 0)))
+ cfgdata.ethif = atoi(v);
+ if ((v = mwGetVarValue(param->pxVars, "mode", 0)))
+ cfgdata.mode = atoi(v);
+ if ((v = mwGetVarValue(param->pxVars, "ip", 0)))
+ strcpy(cfgdata.ip, v);
+ for (i = 0; i < 4; i++) {
+ char buf[4];
+ sprintf(buf, "m%d", i);
+ cfgdata.tvmode[i] = mwGetVarValue(param->pxVars, buf, 0) ? 1 : 0;
+ }
+ // print new settings in console
+ printf("\n--- Configuration ---\nNetwork Interface: %d\n", cfgdata.ethif);
+ if (cfgdata.ethif == 2) printf("IP: %s\n", cfgdata.ip);
+ printf("Startup Mode: %d\nTV Modes:", cfgdata.mode);
+ for (i = 0; i < 4; i++) {
+ if (cfgdata.tvmode[i]) printf(" %s", tvmodes[i]);
+ }
+ printf("\n---------------------\n\n");
+ }
+
+ p += sprintf(p, "%s%s", html_head, html_form_start);
+ for (i = 0; i < 3; i++) {
+ p += sprintf(p, html_ethif[i], (cfgdata.ethif == i) ? " checked" : "");
+ }
+ p += sprintf(p, html_ip, cfgdata.ip);
+ for (i = 0; i < 3; i++) {
+ p += sprintf(p, html_mode[i], (cfgdata.mode == i) ? " selected" : "");
+ }
+ for (i = 0; i < 4; i++) {
+ p += sprintf(p, html_tvmode[i], cfgdata.tvmode[i] ? " checked" : "");
+ }
+ p += sprintf(p, "%s%s%s", html_form_end, param->pxVars ? "New settings applied
" : "", html_tail);
+ param->dataBytes = (int)p - (int)(param->pucBuffer);
+ param->fileType = HTTPFILETYPE_HTML;
+ return FLAG_DATA_RAW;
+}
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
From 2da99dcba2b941dea24bff2e2f9d7c990f7de620 Mon Sep 17 00:00:00 2001
From: gaebor
Date: Sat, 10 Mar 2018 09:49:30 +0100
Subject: [PATCH 3/7] vc15 sln
---
miniweb.vcxproj | 17 +++---
miniweb_vc11.sln | 20 -------
miniweb_vc15.sln | 34 ++++++++++++
plugin/plugin.vcxproj | 98 +++++++++++++++++++++++++++++++++++
plugin/plugin.vcxproj.filters | 22 ++++++++
plugin/plugin.vcxproj.user | 4 ++
6 files changed, 168 insertions(+), 27 deletions(-)
delete mode 100644 miniweb_vc11.sln
create mode 100644 miniweb_vc15.sln
create mode 100644 plugin/plugin.vcxproj
create mode 100644 plugin/plugin.vcxproj.filters
create mode 100644 plugin/plugin.vcxproj.user
diff --git a/miniweb.vcxproj b/miniweb.vcxproj
index c3d1a35..0310f07 100644
--- a/miniweb.vcxproj
+++ b/miniweb.vcxproj
@@ -1,5 +1,5 @@
-
+
Debug
@@ -14,17 +14,18 @@
{06E5025D-53D7-4B39-8D4C-D06E39A3023A}
miniweb
Win32Proj
+ 10.0.15063.0
Application
MultiByte
- v100
+ v141
Application
MultiByte
- v100
+ v141
@@ -41,11 +42,11 @@
<_ProjectFileVersion>10.0.30319.1
$(SolutionDir)bin\
- $(TEMP)\$(Platform)\$(ProjectName)\$(Configuration)\
+ $(Platform)\$(Configuration)\
true
false
$(SolutionDir)bin\
- $(TEMP)\$(Platform)\$(ProjectName)\$(Configuration)\
+ $(Platform)\$(Configuration)\
false
@@ -62,7 +63,7 @@
libctb/include
- WSock32.Lib;%(AdditionalDependencies)
+ Iphlpapi.lib;WSock32.Lib;%(AdditionalDependencies)
$(OutDir)$(TargetFileName)
%(IgnoreSpecificDefaultLibraries)
true
@@ -93,7 +94,7 @@
OldStyle
- WSock32.Lib;%(AdditionalDependencies)
+ Iphlpapi.lib;WSock32.Lib;%(AdditionalDependencies)
$(OutDir)$(TargetFileName)
%(IgnoreSpecificDefaultLibraries)
true
@@ -117,6 +118,7 @@
+
@@ -126,6 +128,7 @@
+
diff --git a/miniweb_vc11.sln b/miniweb_vc11.sln
deleted file mode 100644
index 153eda1..0000000
--- a/miniweb_vc11.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniweb", "miniweb.vcxproj", "{06E5025D-53D7-4B39-8D4C-D06E39A3023A}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Debug|Win32.ActiveCfg = Debug|Win32
- {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Debug|Win32.Build.0 = Debug|Win32
- {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Release|Win32.ActiveCfg = Release|Win32
- {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/miniweb_vc15.sln b/miniweb_vc15.sln
new file mode 100644
index 0000000..c6e1220
--- /dev/null
+++ b/miniweb_vc15.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27428.2002
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniweb", "miniweb.vcxproj", "{06E5025D-53D7-4B39-8D4C-D06E39A3023A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin", "plugin\plugin.vcxproj", "{5802AFF8-6E80-4974-A7BB-D2BB73021327}"
+ ProjectSection(ProjectDependencies) = postProject
+ {06E5025D-53D7-4B39-8D4C-D06E39A3023A} = {06E5025D-53D7-4B39-8D4C-D06E39A3023A}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Debug|Win32.Build.0 = Debug|Win32
+ {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Release|Win32.ActiveCfg = Release|Win32
+ {06E5025D-53D7-4B39-8D4C-D06E39A3023A}.Release|Win32.Build.0 = Release|Win32
+ {5802AFF8-6E80-4974-A7BB-D2BB73021327}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5802AFF8-6E80-4974-A7BB-D2BB73021327}.Debug|Win32.Build.0 = Debug|Win32
+ {5802AFF8-6E80-4974-A7BB-D2BB73021327}.Release|Win32.ActiveCfg = Release|Win32
+ {5802AFF8-6E80-4974-A7BB-D2BB73021327}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C5895650-EE96-4807-9DAB-A8173760D906}
+ EndGlobalSection
+EndGlobal
diff --git a/plugin/plugin.vcxproj b/plugin/plugin.vcxproj
new file mode 100644
index 0000000..4ecd438
--- /dev/null
+++ b/plugin/plugin.vcxproj
@@ -0,0 +1,98 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+
+
+
+ 15.0
+ {5802AFF8-6E80-4974-A7BB-D2BB73021327}
+ Win32Proj
+ plugin
+ 10.0.16299.0
+
+
+
+ DynamicLibrary
+ true
+ v141
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)$bin
+ $(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)$bin
+ $(Platform)\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ _CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;PLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ CompileAsC
+ $(SolutionDir);C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ _CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;PLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ CompileAsC
+ $(SolutionDir);C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugin/plugin.vcxproj.filters b/plugin/plugin.vcxproj.filters
new file mode 100644
index 0000000..bb3c188
--- /dev/null
+++ b/plugin/plugin.vcxproj.filters
@@ -0,0 +1,22 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/plugin/plugin.vcxproj.user b/plugin/plugin.vcxproj.user
new file mode 100644
index 0000000..6e2aec7
--- /dev/null
+++ b/plugin/plugin.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
From d9ee34fda70a0046302bf3ce4eec97bf5fa249b3 Mon Sep 17 00:00:00 2001
From: gaebor
Date: Tue, 13 Mar 2018 19:45:36 +0100
Subject: [PATCH 4/7] type-o
---
bin/htdocs/demodyn.htm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/htdocs/demodyn.htm b/bin/htdocs/demodyn.htm
index 4939ff8..f003234 100644
--- a/bin/htdocs/demodyn.htm
+++ b/bin/htdocs/demodyn.htm
@@ -8,7 +8,7 @@ MiniWeb Demo Page
-
+