... | ... |
@@ -66,6 +66,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libclamunrar_iface", "libcl |
66 | 66 |
EndProject |
67 | 67 |
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clamav-for-windows", "clamav-for-windows.vcxproj", "{127CBFE6-B8AE-4422-AFFB-61F80A7C8D18}" |
68 | 68 |
EndProject |
69 |
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freshclamwrap", "freshclamwrap.vcxproj", "{366C2DCE-777A-43EE-96DC-C530E67E7B32}" |
|
70 |
+EndProject |
|
69 | 71 |
Global |
70 | 72 |
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
71 | 73 |
Debug|Win32 = Debug|Win32 |
... | ... |
@@ -198,6 +200,10 @@ Global |
198 | 198 |
{127CBFE6-B8AE-4422-AFFB-61F80A7C8D18}.Debug|x64.ActiveCfg = Debug|x64 |
199 | 199 |
{127CBFE6-B8AE-4422-AFFB-61F80A7C8D18}.Release|Win32.ActiveCfg = Release|Win32 |
200 | 200 |
{127CBFE6-B8AE-4422-AFFB-61F80A7C8D18}.Release|x64.ActiveCfg = Release|x64 |
201 |
+ {366C2DCE-777A-43EE-96DC-C530E67E7B32}.Debug|Win32.ActiveCfg = Debug|Win32 |
|
202 |
+ {366C2DCE-777A-43EE-96DC-C530E67E7B32}.Debug|x64.ActiveCfg = Debug|Win32 |
|
203 |
+ {366C2DCE-777A-43EE-96DC-C530E67E7B32}.Release|Win32.ActiveCfg = Release|Win32 |
|
204 |
+ {366C2DCE-777A-43EE-96DC-C530E67E7B32}.Release|x64.ActiveCfg = Release|Win32 |
|
201 | 205 |
EndGlobalSection |
202 | 206 |
GlobalSection(SolutionProperties) = preSolution |
203 | 207 |
HideSolutionNode = FALSE |
204 | 208 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,101 @@ |
0 |
+<?xml version="1.0" encoding="utf-8"?> |
|
1 |
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
2 |
+ <ItemGroup Label="ProjectConfigurations"> |
|
3 |
+ <ProjectConfiguration Include="Debug|Win32"> |
|
4 |
+ <Configuration>Debug</Configuration> |
|
5 |
+ <Platform>Win32</Platform> |
|
6 |
+ </ProjectConfiguration> |
|
7 |
+ <ProjectConfiguration Include="Release|Win32"> |
|
8 |
+ <Configuration>Release</Configuration> |
|
9 |
+ <Platform>Win32</Platform> |
|
10 |
+ </ProjectConfiguration> |
|
11 |
+ </ItemGroup> |
|
12 |
+ <ItemGroup> |
|
13 |
+ <ClCompile Include="freshclamwrap\flog.c" /> |
|
14 |
+ <ClCompile Include="freshclamwrap\freshclamwrap.c" /> |
|
15 |
+ </ItemGroup> |
|
16 |
+ <PropertyGroup Label="Globals"> |
|
17 |
+ <ProjectGuid>{366C2DCE-777A-43EE-96DC-C530E67E7B32}</ProjectGuid> |
|
18 |
+ <Keyword>Win32Proj</Keyword> |
|
19 |
+ <RootNamespace>freshclamwrap</RootNamespace> |
|
20 |
+ </PropertyGroup> |
|
21 |
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
|
22 |
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
|
23 |
+ <ConfigurationType>Application</ConfigurationType> |
|
24 |
+ <UseDebugLibraries>true</UseDebugLibraries> |
|
25 |
+ <CharacterSet>MultiByte</CharacterSet> |
|
26 |
+ </PropertyGroup> |
|
27 |
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
|
28 |
+ <ConfigurationType>Application</ConfigurationType> |
|
29 |
+ <UseDebugLibraries>false</UseDebugLibraries> |
|
30 |
+ <WholeProgramOptimization>true</WholeProgramOptimization> |
|
31 |
+ <CharacterSet>MultiByte</CharacterSet> |
|
32 |
+ </PropertyGroup> |
|
33 |
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
|
34 |
+ <ImportGroup Label="ExtensionSettings"> |
|
35 |
+ </ImportGroup> |
|
36 |
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
|
37 |
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
|
38 |
+ </ImportGroup> |
|
39 |
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
|
40 |
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
|
41 |
+ </ImportGroup> |
|
42 |
+ <PropertyGroup Label="UserMacros" /> |
|
43 |
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
|
44 |
+ <LinkIncremental>true</LinkIncremental> |
|
45 |
+ <OutDir>$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir> |
|
46 |
+ <IntDir>$(SolutionDir)build\$(PlatformName)\$(ProjectName)\$(Configuration)\</IntDir> |
|
47 |
+ </PropertyGroup> |
|
48 |
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
|
49 |
+ <LinkIncremental>false</LinkIncremental> |
|
50 |
+ <OutDir>$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir> |
|
51 |
+ <IntDir>$(SolutionDir)build\$(PlatformName)\$(ProjectName)\$(Configuration)\</IntDir> |
|
52 |
+ </PropertyGroup> |
|
53 |
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
|
54 |
+ <ClCompile> |
|
55 |
+ <PrecompiledHeader>NotUsing</PrecompiledHeader> |
|
56 |
+ <WarningLevel>Level3</WarningLevel> |
|
57 |
+ <Optimization>Disabled</Optimization> |
|
58 |
+ <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
|
59 |
+ <PrecompiledHeaderFile> |
|
60 |
+ </PrecompiledHeaderFile> |
|
61 |
+ <PrecompiledHeaderOutputFile> |
|
62 |
+ </PrecompiledHeaderOutputFile> |
|
63 |
+ <AdditionalIncludeDirectories>"$(SolutionDir)";"$(SolutionDir)..\libclamav";"$(SolutionDir)compat";"$(SolutionDir).."</AdditionalIncludeDirectories> |
|
64 |
+ <CompileAs>CompileAsC</CompileAs> |
|
65 |
+ <DisableSpecificWarnings>4996</DisableSpecificWarnings> |
|
66 |
+ </ClCompile> |
|
67 |
+ <Link> |
|
68 |
+ <SubSystem>Windows</SubSystem> |
|
69 |
+ <GenerateDebugInformation>true</GenerateDebugInformation> |
|
70 |
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
|
71 |
+ </Link> |
|
72 |
+ </ItemDefinitionGroup> |
|
73 |
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
|
74 |
+ <ClCompile> |
|
75 |
+ <WarningLevel>Level3</WarningLevel> |
|
76 |
+ <PrecompiledHeader>NotUsing</PrecompiledHeader> |
|
77 |
+ <Optimization>MaxSpeed</Optimization> |
|
78 |
+ <FunctionLevelLinking>true</FunctionLevelLinking> |
|
79 |
+ <IntrinsicFunctions>true</IntrinsicFunctions> |
|
80 |
+ <PreprocessorDefinitions>WIN32;WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
|
81 |
+ <PrecompiledHeaderFile> |
|
82 |
+ </PrecompiledHeaderFile> |
|
83 |
+ <PrecompiledHeaderOutputFile> |
|
84 |
+ </PrecompiledHeaderOutputFile> |
|
85 |
+ <AdditionalIncludeDirectories>"$(SolutionDir)";"$(SolutionDir)..\libclamav";"$(SolutionDir)compat";"$(SolutionDir).."</AdditionalIncludeDirectories> |
|
86 |
+ <CompileAs>CompileAsC</CompileAs> |
|
87 |
+ <DisableSpecificWarnings>4996</DisableSpecificWarnings> |
|
88 |
+ </ClCompile> |
|
89 |
+ <Link> |
|
90 |
+ <SubSystem>Windows</SubSystem> |
|
91 |
+ <GenerateDebugInformation>true</GenerateDebugInformation> |
|
92 |
+ <EnableCOMDATFolding>true</EnableCOMDATFolding> |
|
93 |
+ <OptimizeReferences>true</OptimizeReferences> |
|
94 |
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
|
95 |
+ </Link> |
|
96 |
+ </ItemDefinitionGroup> |
|
97 |
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
|
98 |
+ <ImportGroup Label="ExtensionTargets"> |
|
99 |
+ </ImportGroup> |
|
100 |
+</Project> |
|
0 | 101 |
\ No newline at end of file |
1 | 102 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,49 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
2 |
+ * Authors: aCaB <acab@clamav.net> |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License version 2.1 as published by the Free Software Foundation. |
|
7 |
+ * |
|
8 |
+ * This library is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with this library; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
|
16 |
+ * USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#ifndef _CLUPDATE_H |
|
20 |
+#define _CLUPDATE_H |
|
21 |
+ |
|
22 |
+// Possible states during update |
|
23 |
+typedef enum _AV_UPD_STATE |
|
24 |
+{ |
|
25 |
+ UPD_CHECK, |
|
26 |
+ UPD_NEWER_FOUND, |
|
27 |
+ UPD_NONE, |
|
28 |
+ UPD_DOWNLOAD_BEGIN, |
|
29 |
+ UPD_DOWNLOAD_COMPLETE, |
|
30 |
+ UPD_PAUSE, |
|
31 |
+ UPD_ABORT, |
|
32 |
+ UPD_DONE, |
|
33 |
+ UPD_INSTALL_BEGIN, |
|
34 |
+ UPD_INSTALL_COMPLETE, |
|
35 |
+ UPD_FILE_BEGIN, |
|
36 |
+ UPD_FILE_COMPLETE, |
|
37 |
+}AV_UPD_STATE; |
|
38 |
+ |
|
39 |
+typedef struct _AV_UPD_STATUS |
|
40 |
+{ |
|
41 |
+ int state; // AV_UPD_STATE |
|
42 |
+ int status; // 0 -> Success, anything else failure |
|
43 |
+ int totalSize; // total bytes to download |
|
44 |
+ int downloadedSize; // bytes downloaded so far |
|
45 |
+ int totalFiles; // incase there update happens with multiple files |
|
46 |
+}AV_UPD_STATUS, *PAV_UPD_STATUS; |
|
47 |
+ |
|
48 |
+#endif /* _CLUPDATE_H */ |
0 | 49 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,52 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
2 |
+ * Authors: aCaB <acab@clamav.net> |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License version 2.1 as published by the Free Software Foundation. |
|
7 |
+ * |
|
8 |
+ * This library is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with this library; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
|
16 |
+ * USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#include <windows.h> |
|
20 |
+#include <stdio.h> |
|
21 |
+ |
|
22 |
+#include "flog.h" |
|
23 |
+ |
|
24 |
+static HANDLE logh; |
|
25 |
+ |
|
26 |
+void flog_open(const char *path) { |
|
27 |
+ logh = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
|
28 |
+ SetFilePointer(logh, 0, NULL, FILE_END); |
|
29 |
+ flog("Log file initialized"); |
|
30 |
+} |
|
31 |
+ |
|
32 |
+void flog(const char *fmt, ...) { |
|
33 |
+ char buf[4096]; |
|
34 |
+ SYSTEMTIME t; |
|
35 |
+ DWORD x; |
|
36 |
+ va_list ap; |
|
37 |
+ |
|
38 |
+ GetLocalTime(&t); |
|
39 |
+ _snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u - ", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); |
|
40 |
+ WriteFile(logh, buf, strlen(buf), &x, NULL); |
|
41 |
+ va_start(ap, fmt); |
|
42 |
+ vsnprintf(buf, sizeof(buf), fmt, ap); |
|
43 |
+ va_end(ap); |
|
44 |
+ WriteFile(logh, buf, strlen(buf), &x, NULL); |
|
45 |
+ WriteFile(logh, "\r\n", 2, &x, NULL); |
|
46 |
+} |
|
47 |
+ |
|
48 |
+void flog_close(void) { |
|
49 |
+ flog("Log file closed"); |
|
50 |
+ CloseHandle(logh); |
|
51 |
+} |
0 | 52 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,27 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
2 |
+ * Authors: aCaB <acab@clamav.net> |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License version 2.1 as published by the Free Software Foundation. |
|
7 |
+ * |
|
8 |
+ * This library is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with this library; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
|
16 |
+ * USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#ifndef __FLOG_H |
|
20 |
+#define __FLOG_H |
|
21 |
+ |
|
22 |
+void flog_open(path); |
|
23 |
+void flog(const char *fmt, ...); |
|
24 |
+void flog_close(void); |
|
25 |
+ |
|
26 |
+#endif |
0 | 27 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,286 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
2 |
+ * Authors: aCaB <acab@clamav.net> |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License version 2.1 as published by the Free Software Foundation. |
|
7 |
+ * |
|
8 |
+ * This library is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with this library; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
|
16 |
+ * USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#include <windows.h> |
|
20 |
+#include <string.h> |
|
21 |
+#include <stdio.h> |
|
22 |
+ |
|
23 |
+#include "clupdate.h" |
|
24 |
+#include "flog.h" |
|
25 |
+ |
|
26 |
+struct my_f { |
|
27 |
+ HANDLE h; |
|
28 |
+ char buf[1024]; |
|
29 |
+ char *next; |
|
30 |
+ unsigned int len; |
|
31 |
+}; |
|
32 |
+ |
|
33 |
+static void init_myf(struct my_f *f, HANDLE h) { |
|
34 |
+ f->next = f->buf; |
|
35 |
+ f->len = 0; |
|
36 |
+ f->h = h; |
|
37 |
+} |
|
38 |
+ |
|
39 |
+static char *my_fgets(struct my_f *f) { |
|
40 |
+ int stripping = 0; |
|
41 |
+ char *cur = f->next; |
|
42 |
+ while(1) { |
|
43 |
+ if(!f->len) { |
|
44 |
+ if(f->next == &f->buf[sizeof(f->buf)-1]) { |
|
45 |
+ if(cur == f->buf) { |
|
46 |
+ *f->next = '\0'; |
|
47 |
+ f->next = f->buf; |
|
48 |
+ return f->buf; |
|
49 |
+ } |
|
50 |
+ memmove(f->buf, cur, f->next - cur); |
|
51 |
+ f->next -= cur - f->buf; |
|
52 |
+ cur = f->buf; |
|
53 |
+ } |
|
54 |
+ if(!ReadFile(f->h, f->next, sizeof(f->buf) - 1 - (f->next - f->buf), &f->len, NULL)) |
|
55 |
+ return NULL; |
|
56 |
+ if(!f->len) { |
|
57 |
+ *f->next = '\0'; |
|
58 |
+ return cur != f->next ? cur : NULL; |
|
59 |
+ } |
|
60 |
+ continue; |
|
61 |
+ } |
|
62 |
+ if(*f->next == '\n' || *f->next == '\r') { |
|
63 |
+ *f->next = '\0'; |
|
64 |
+ stripping = 1; |
|
65 |
+ } else if(stripping) |
|
66 |
+ return cur; |
|
67 |
+ f->len--; |
|
68 |
+ f->next++; |
|
69 |
+ } |
|
70 |
+} |
|
71 |
+ |
|
72 |
+ |
|
73 |
+static void send_pipe(HANDLE pipe, AV_UPD_STATUS *updstatus, int state, int fail) { |
|
74 |
+ DWORD got; |
|
75 |
+ |
|
76 |
+const char *phases[] = { |
|
77 |
+ "UPD_CHECK", |
|
78 |
+ "UPD_NEWER_FOUND", |
|
79 |
+ "UPD_NONE", |
|
80 |
+ "UPD_DOWNLOAD_BEGIN", |
|
81 |
+ "UPD_DOWNLOAD_COMPLETE", |
|
82 |
+ "UPD_PAUSE", |
|
83 |
+ "UPD_ABORT", |
|
84 |
+ "UPD_DONE", |
|
85 |
+ "UPD_INSTALL_BEGIN", |
|
86 |
+ "UPD_INSTALL_COMPLETE", |
|
87 |
+ "UPD_FILE_BEGIN", |
|
88 |
+ "UPD_FILE_COMPLETE" |
|
89 |
+ }; |
|
90 |
+ |
|
91 |
+ flog("SEND: state: %s - status: %s", (unsigned int)state < sizeof(phases) / sizeof(*phases) ? phases[state] : "INVALID", fail ? "fail" : "success"); |
|
92 |
+ updstatus->state = state; |
|
93 |
+ updstatus->status = fail; |
|
94 |
+ if(!WriteFile(pipe, updstatus, sizeof(*updstatus), &got, NULL)) |
|
95 |
+ flog("WARNING: cannot write to pipe"); |
|
96 |
+} |
|
97 |
+ |
|
98 |
+#define SENDFAIL_AND_QUIT(phase) \ |
|
99 |
+ do { \ |
|
100 |
+ send_pipe(updpipe, &st, (phase), 1);\ |
|
101 |
+ CloseHandle(updpipe); \ |
|
102 |
+ flog_close(); \ |
|
103 |
+ return 1; \ |
|
104 |
+ } while(0) |
|
105 |
+ |
|
106 |
+#define SENDOK(phase) \ |
|
107 |
+ do { \ |
|
108 |
+ send_pipe(updpipe, &st, (phase), 0);\ |
|
109 |
+ } while(0) |
|
110 |
+ |
|
111 |
+enum fresh_states { |
|
112 |
+ FRESH_PRE, |
|
113 |
+ FRESH_IDLE, |
|
114 |
+ FRESH_DOWN |
|
115 |
+}; |
|
116 |
+ |
|
117 |
+const char *fstates[] = { |
|
118 |
+ "FRESH_PRE", |
|
119 |
+ "FRESH_IDLE", |
|
120 |
+ "FRESH_DOWN" |
|
121 |
+}; |
|
122 |
+ |
|
123 |
+static void log_state(enum fresh_states s) { |
|
124 |
+ flog("state is now: %s", (s < FRESH_PRE || s > FRESH_DOWN) ? "INVALID" : fstates[s]); |
|
125 |
+} |
|
126 |
+ |
|
127 |
+#define FRESH_PRE_START_S "ClamAV update process started at " |
|
128 |
+#define FRESH_DOWN_S "Downloading " |
|
129 |
+#define FRESH_UPDATED_S " updated (version: " |
|
130 |
+#define FRESH_UPTODATE_S " is up to date " |
|
131 |
+#define FRESH_DONE_S "Database updated " |
|
132 |
+ |
|
133 |
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { |
|
134 |
+ HANDLE cld_r, cld_w2, cld_w, updpipe; |
|
135 |
+ PROCESS_INFORMATION pinfo; |
|
136 |
+ STARTUPINFO sinfo; |
|
137 |
+ enum fresh_states fstate = FRESH_PRE; |
|
138 |
+ AV_UPD_STATUS st = {UPD_CHECK, 0, 100, 0, 3}; |
|
139 |
+ DWORD dw; |
|
140 |
+ struct my_f spam; |
|
141 |
+ char buf[4096], command[8192], *ptr; |
|
142 |
+ int updated_files = 0; |
|
143 |
+ wchar_t *cmdl = GetCommandLineW(); |
|
144 |
+ |
|
145 |
+// DebugBreak(); |
|
146 |
+ |
|
147 |
+ /* Locate myself */ |
|
148 |
+ dw = GetModuleFileName(NULL, buf, sizeof(buf)); |
|
149 |
+ if(!dw || dw >= sizeof(buf)-2) |
|
150 |
+ return 1; |
|
151 |
+ ptr = strrchr(buf, '\\'); |
|
152 |
+ if(!ptr) |
|
153 |
+ return 1; |
|
154 |
+ *ptr = '\0'; |
|
155 |
+ |
|
156 |
+ /* Log file */ |
|
157 |
+ _snprintf(command, sizeof(command)-1, "%s\\update.log", buf); |
|
158 |
+ command[sizeof(command)-1] = '\0'; |
|
159 |
+ flog_open(command); |
|
160 |
+ |
|
161 |
+ _snprintf(command, sizeof(command)-1, "freshclam.exe --stdout --config-file=\"%s\\freshclam.conf\" --datadir=\"%s\"", buf, buf); |
|
162 |
+ command[sizeof(command)-1] = '\0'; |
|
163 |
+ |
|
164 |
+ /* Connect to master */ |
|
165 |
+ updpipe = CreateFile("\\\\.\\pipe\\IMMUNET_AVUPDATE", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); |
|
166 |
+ if(updpipe == INVALID_HANDLE_VALUE) { |
|
167 |
+ flog("ERROR: failed to connect pipe"); |
|
168 |
+ flog_close(); |
|
169 |
+ return 1; |
|
170 |
+ } |
|
171 |
+ dw = PIPE_READMODE_MESSAGE; |
|
172 |
+ if(!SetNamedPipeHandleState(updpipe, &dw, NULL, NULL)) { |
|
173 |
+ CloseHandle(updpipe); |
|
174 |
+ flog("ERROR: failed to set pipe to message mode"); |
|
175 |
+ flog_close(); |
|
176 |
+ return 1; |
|
177 |
+ } |
|
178 |
+ |
|
179 |
+ /* Make pipe for freshclam stdio */ |
|
180 |
+ if(!CreatePipe(&cld_r, &cld_w, NULL, 0)) { |
|
181 |
+ flog("ERROR: failed to create pipe"); |
|
182 |
+ SENDFAIL_AND_QUIT(UPD_CHECK); |
|
183 |
+ } |
|
184 |
+ |
|
185 |
+ if(!DuplicateHandle(GetCurrentProcess(), cld_w, GetCurrentProcess(), &cld_w2, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
|
186 |
+ CloseHandle(cld_r); |
|
187 |
+ CloseHandle(cld_w); |
|
188 |
+ flog("ERROR: failed to duplicate pipe"); |
|
189 |
+ SENDFAIL_AND_QUIT(UPD_CHECK); |
|
190 |
+ } |
|
191 |
+ CloseHandle(cld_w); |
|
192 |
+ |
|
193 |
+ /* init my_fgets */ |
|
194 |
+ init_myf(&spam, cld_r); |
|
195 |
+ |
|
196 |
+ /* Redir freshclam stdio */ |
|
197 |
+ memset(&sinfo, 0, sizeof(sinfo)); |
|
198 |
+ sinfo.cb = sizeof(sinfo); |
|
199 |
+ sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); |
|
200 |
+ sinfo.hStdOutput = cld_w2; |
|
201 |
+ sinfo.hStdError = cld_w2; |
|
202 |
+ sinfo.dwFlags = STARTF_FORCEOFFFEEDBACK|STARTF_USESTDHANDLES; |
|
203 |
+ if(!CreateProcess(NULL, command, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, buf, &sinfo, &pinfo)) { |
|
204 |
+ CloseHandle(cld_w2); |
|
205 |
+ CloseHandle(cld_r); |
|
206 |
+ flog("ERROR: failed to execute '%s'", command); |
|
207 |
+ SENDFAIL_AND_QUIT(UPD_CHECK); |
|
208 |
+ } |
|
209 |
+ CloseHandle(pinfo.hThread); |
|
210 |
+ CloseHandle(cld_w2); |
|
211 |
+ |
|
212 |
+ flog("Executing '%s'", command); |
|
213 |
+ log_state(fstate); |
|
214 |
+ /* Spam parsing */ |
|
215 |
+ while(1) { |
|
216 |
+ char *buf; |
|
217 |
+ buf = my_fgets(&spam); |
|
218 |
+ flog("GOT: %s", buf); |
|
219 |
+ if(!buf) |
|
220 |
+ break; |
|
221 |
+ if(!strncmp(buf, "WARNING: ", 9)) |
|
222 |
+ continue; |
|
223 |
+ if(fstate == FRESH_PRE && !strncmp(buf, FRESH_PRE_START_S, sizeof(FRESH_PRE_START_S)-1)) { |
|
224 |
+ SENDOK(UPD_CHECK); |
|
225 |
+ fstate = FRESH_IDLE; |
|
226 |
+ log_state(fstate); |
|
227 |
+ continue; |
|
228 |
+ } |
|
229 |
+ if(fstate == FRESH_IDLE) { |
|
230 |
+ if(!strncmp(buf, FRESH_DOWN_S, sizeof(FRESH_DOWN_S)-1)) { |
|
231 |
+ if(!updated_files) { |
|
232 |
+ SENDOK(UPD_NEWER_FOUND); |
|
233 |
+ SENDOK(UPD_DOWNLOAD_BEGIN); |
|
234 |
+ } |
|
235 |
+ updated_files++; |
|
236 |
+ SENDOK(UPD_FILE_BEGIN); |
|
237 |
+ fstate = FRESH_DOWN; |
|
238 |
+ log_state(fstate); |
|
239 |
+ continue; |
|
240 |
+ } |
|
241 |
+ if(strstr(buf, FRESH_UPTODATE_S)) |
|
242 |
+ continue; |
|
243 |
+ if(!strncmp(buf, FRESH_DONE_S, sizeof(FRESH_DONE_S) - 1)) |
|
244 |
+ continue; |
|
245 |
+ } |
|
246 |
+ if(fstate == FRESH_DOWN) { |
|
247 |
+ if(strstr(buf, FRESH_UPDATED_S)) { |
|
248 |
+ SENDOK(UPD_FILE_COMPLETE); |
|
249 |
+ fstate = FRESH_IDLE; |
|
250 |
+ log_state(fstate); |
|
251 |
+ continue; |
|
252 |
+ } |
|
253 |
+ if(strlen(buf) > sizeof(FRESH_DOWN_S)-1 && strstr(buf, FRESH_DOWN_S)) |
|
254 |
+ continue; |
|
255 |
+ } |
|
256 |
+ break; |
|
257 |
+ } |
|
258 |
+ CloseHandle(cld_r); |
|
259 |
+ WaitForSingleObject(pinfo.hProcess, 30*1000); |
|
260 |
+ if(!GetExitCodeProcess(pinfo.hProcess, &dw)) { |
|
261 |
+ CloseHandle(pinfo.hProcess); |
|
262 |
+ flog("ERROR: failed to retrieve freshclam return code"); |
|
263 |
+ SENDFAIL_AND_QUIT(st.state); |
|
264 |
+ } |
|
265 |
+ CloseHandle(pinfo.hProcess); |
|
266 |
+ if(dw) { |
|
267 |
+ flog("ERROR: freshclam exitted with %u\n", dw); |
|
268 |
+ SENDFAIL_AND_QUIT(st.state); |
|
269 |
+ } |
|
270 |
+ if(fstate != FRESH_IDLE) { |
|
271 |
+ flog("ERROR: freshclam exited with %u\n", dw); |
|
272 |
+ SENDFAIL_AND_QUIT(st.state); |
|
273 |
+ } |
|
274 |
+ |
|
275 |
+ /* Send complete fin seq */ |
|
276 |
+ if(updated_files) { |
|
277 |
+ SENDOK(UPD_DOWNLOAD_COMPLETE); |
|
278 |
+ SENDOK(UPD_INSTALL_BEGIN); |
|
279 |
+ SENDOK(UPD_INSTALL_COMPLETE); |
|
280 |
+ SENDOK(UPD_DONE); |
|
281 |
+ } else |
|
282 |
+ SENDOK(UPD_NONE); |
|
283 |
+ flog_close(); |
|
284 |
+ return 0; |
|
285 |
+} |