... | ... |
@@ -188,14 +188,15 @@ CL_CLEAN = File is scanned |
188 | 188 |
CL_BREAK = Whitelisted by callback - file is skipped and marked as clean |
189 | 189 |
CL_VIRUS = Blacklisted by callback - file is skipped and marked as infected |
190 | 190 |
*/ |
191 |
-extern void cl_engine_set_clcb_pre_scan(struct cl_engine *engine, clcb_pre_scan callback, void *context); |
|
191 |
+extern void cl_engine_set_clcb_pre_scan(struct cl_engine *engine, clcb_pre_scan callback); |
|
192 | 192 |
|
193 | 193 |
|
194 |
-typedef cl_error_t (*clcb_post_scan)(int fd, int result, void *context); |
|
194 |
+typedef cl_error_t (*clcb_post_scan)(int fd, int result, const char *virname, void *context); |
|
195 | 195 |
/* POST-SCAN |
196 | 196 |
Input: |
197 | 197 |
fd = File descriptor which is was scanned |
198 | 198 |
result = The scan result for the file |
199 |
+virname = Virus name if infected |
|
199 | 200 |
context = Opaque application provided data |
200 | 201 |
|
201 | 202 |
Output: |
... | ... |
@@ -203,7 +204,7 @@ CL_CLEAN = Scan result is not overridden |
203 | 203 |
CL_BREAK = Whitelisted by callback - scan result is set to CL_CLEAN |
204 | 204 |
CL_VIRUS = Blacklisted by callback - scan result is set to CL_VIRUS |
205 | 205 |
*/ |
206 |
-extern void cl_engine_set_clcb_post_scan(struct cl_engine *engine, clcb_post_scan callback, void *context); |
|
206 |
+extern void cl_engine_set_clcb_post_scan(struct cl_engine *engine, clcb_post_scan callback); |
|
207 | 207 |
|
208 | 208 |
|
209 | 209 |
typedef int (*clcb_sigload)(const char *type, const char *name, void *context); |
... | ... |
@@ -241,6 +242,7 @@ struct cl_cvd { /* field no. */ |
241 | 241 |
|
242 | 242 |
/* file scanning */ |
243 | 243 |
extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions); |
244 |
+extern int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context); |
|
244 | 245 |
|
245 | 246 |
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions); |
246 | 247 |
|
... | ... |
@@ -1009,14 +1009,12 @@ int cli_bitset_test(bitset_t *bs, unsigned long bit_offset) |
1009 | 1009 |
return (bs->bitset[char_offset] & ((unsigned char)1 << bit_offset)); |
1010 | 1010 |
} |
1011 | 1011 |
|
1012 |
-void cl_engine_set_clcb_pre_scan(struct cl_engine *engine, clcb_pre_scan callback, void *context) { |
|
1012 |
+void cl_engine_set_clcb_pre_scan(struct cl_engine *engine, clcb_pre_scan callback) { |
|
1013 | 1013 |
engine->cb_pre_scan = callback; |
1014 |
- engine->cb_pre_scan_ctx = callback ? context : NULL; |
|
1015 | 1014 |
} |
1016 | 1015 |
|
1017 |
-void cl_engine_set_clcb_post_scan(struct cl_engine *engine, clcb_post_scan callback, void *context) { |
|
1016 |
+void cl_engine_set_clcb_post_scan(struct cl_engine *engine, clcb_post_scan callback) { |
|
1018 | 1017 |
engine->cb_post_scan = callback; |
1019 |
- engine->cb_post_scan_ctx = callback ? context : NULL; |
|
1020 | 1018 |
} |
1021 | 1019 |
|
1022 | 1020 |
void cl_engine_set_clcb_sigload(struct cl_engine *engine, clcb_sigload callback, void *context) { |
... | ... |
@@ -125,6 +125,7 @@ typedef struct cli_ctx_tag { |
125 | 125 |
struct cli_dconf *dconf; |
126 | 126 |
fmap_t **fmap; |
127 | 127 |
bitset_t* hook_lsig_matches; |
128 |
+ void *cb_ctx; |
|
128 | 129 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
129 | 130 |
char entry_filename[2048]; |
130 | 131 |
int sha_collect; |
... | ... |
@@ -251,9 +252,7 @@ struct cl_engine { |
251 | 251 |
|
252 | 252 |
/* Callback(s) */ |
253 | 253 |
clcb_pre_scan cb_pre_scan; |
254 |
- void *cb_pre_scan_ctx; |
|
255 | 254 |
clcb_post_scan cb_post_scan; |
256 |
- void *cb_post_scan_ctx; |
|
257 | 255 |
clcb_sigload cb_sigload; |
258 | 256 |
void *cb_sigload_ctx; |
259 | 257 |
|
... | ... |
@@ -1897,7 +1897,7 @@ static void emax_reached(cli_ctx *ctx) { |
1897 | 1897 |
#define ret_from_magicscan(retcode) do { \ |
1898 | 1898 |
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \ |
1899 | 1899 |
if(ctx->engine->cb_post_scan) { \ |
1900 |
- switch(ctx->engine->cb_post_scan(desc, retcode, ctx->engine->cb_post_scan_ctx)) { \ |
|
1900 |
+ switch(ctx->engine->cb_post_scan(desc, retcode, ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \ |
|
1901 | 1901 |
case CL_BREAK: \ |
1902 | 1902 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \ |
1903 | 1903 |
return CL_CLEAN; \ |
... | ... |
@@ -1970,7 +1970,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1970 | 1970 |
} |
1971 | 1971 |
|
1972 | 1972 |
if(ctx->engine->cb_pre_scan) { |
1973 |
- switch(ctx->engine->cb_pre_scan(desc, ctx->engine->cb_pre_scan_ctx)) { |
|
1973 |
+ switch(ctx->engine->cb_pre_scan(desc, ctx->cb_ctx)) { |
|
1974 | 1974 |
case CL_BREAK: |
1975 | 1975 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); |
1976 | 1976 |
funmap(*ctx->fmap); |
... | ... |
@@ -2424,6 +2424,54 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons |
2424 | 2424 |
return cli_scandesc_stats(desc, virname, NULL, NULL, scanned, engine, scanoptions); |
2425 | 2425 |
} |
2426 | 2426 |
|
2427 |
+ |
|
2428 |
+int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context) |
|
2429 |
+{ |
|
2430 |
+ cli_ctx ctx; |
|
2431 |
+ int rc; |
|
2432 |
+ |
|
2433 |
+ memset(&ctx, '\0', sizeof(cli_ctx)); |
|
2434 |
+ ctx.engine = engine; |
|
2435 |
+ ctx.virname = virname; |
|
2436 |
+ ctx.scanned = scanned; |
|
2437 |
+ ctx.options = scanoptions; |
|
2438 |
+ ctx.found_possibly_unwanted = 0; |
|
2439 |
+ ctx.container_type = CL_TYPE_ANY; |
|
2440 |
+ ctx.container_size = 0; |
|
2441 |
+ ctx.dconf = (struct cli_dconf *) engine->dconf; |
|
2442 |
+ ctx.cb_ctx = context; |
|
2443 |
+ ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2); |
|
2444 |
+ if(!ctx.fmap) |
|
2445 |
+ return CL_EMEM; |
|
2446 |
+ if (!(ctx.hook_lsig_matches = cli_bitset_init())) { |
|
2447 |
+ free(ctx.fmap); |
|
2448 |
+ return CL_EMEM; |
|
2449 |
+ } |
|
2450 |
+ |
|
2451 |
+#ifdef HAVE__INTERNAL__SHA_COLLECT |
|
2452 |
+ if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) { |
|
2453 |
+ char link[32]; |
|
2454 |
+ ssize_t linksz; |
|
2455 |
+ |
|
2456 |
+ snprintf(link, sizeof(link), "/proc/self/fd/%u", desc); |
|
2457 |
+ link[sizeof(link)-1]='\0'; |
|
2458 |
+ if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)))==-1) { |
|
2459 |
+ cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link); |
|
2460 |
+ strcpy(ctx.entry_filename, "NO_IDEA"); |
|
2461 |
+ } else |
|
2462 |
+ ctx.entry_filename[linksz]='\0'; |
|
2463 |
+ } while(0); |
|
2464 |
+#endif |
|
2465 |
+ |
|
2466 |
+ rc = cli_magic_scandesc(desc, &ctx); |
|
2467 |
+ |
|
2468 |
+ cli_bitset_free(ctx.hook_lsig_matches); |
|
2469 |
+ free(ctx.fmap); |
|
2470 |
+ if(rc == CL_CLEAN && ctx.found_possibly_unwanted) |
|
2471 |
+ rc = CL_VIRUS; |
|
2472 |
+ return rc; |
|
2473 |
+} |
|
2474 |
+ |
|
2427 | 2475 |
int cli_found_possibly_unwanted(cli_ctx* ctx) |
2428 | 2476 |
{ |
2429 | 2477 |
if(ctx->virname) { |
... | ... |
@@ -45,7 +45,7 @@ |
45 | 45 |
Name="VCCLCompilerTool" |
46 | 46 |
Optimization="0" |
47 | 47 |
AdditionalIncludeDirectories=""$(SolutionDir)";"$(SolutionDir)..\libclamav";"$(SolutionDir)compat";"$(SolutionDir)3rdparty\zlib";"$(SolutionDir)3rdparty\pthreads";"$(SolutionDir).."" |
48 |
- PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1;CLAMAV_EXPORTS" |
|
48 |
+ PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1;CLAMAPI= __declspec(dllexport)" |
|
49 | 49 |
MinimalRebuild="true" |
50 | 50 |
BasicRuntimeChecks="3" |
51 | 51 |
RuntimeLibrary="3" |
... | ... |
@@ -123,7 +123,7 @@ |
123 | 123 |
Optimization="2" |
124 | 124 |
EnableIntrinsicFunctions="true" |
125 | 125 |
AdditionalIncludeDirectories=""$(SolutionDir)";"$(SolutionDir)..\libclamav";"$(SolutionDir)compat";"$(SolutionDir)3rdparty\zlib";"$(SolutionDir)3rdparty\pthreads";"$(SolutionDir).."" |
126 |
- PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1;CLAMAV_EXPORTS" |
|
126 |
+ PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1;CLAMAPI= __declspec(dllexport)" |
|
127 | 127 |
RuntimeLibrary="2" |
128 | 128 |
EnableFunctionLevelLinking="true" |
129 | 129 |
UsePrecompiledHeader="0" |
130 | 130 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
0 |
+#if HAVE_CONFIG_H |
|
1 |
+#include "clamav-config.h" |
|
2 |
+#endif |
|
3 |
+ |
|
4 |
+#include "clscanapi.h" |
|
5 |
+ |
|
6 |
+typedef void (CALL_CONVENTION *CLAM_PASSWORD_CALLBACK)(int objectType, const wchar_t *pObjectName, wchar_t *pPassword, int *pPasswordLen, void *context); |
|
7 |
+ |
|
8 |
+int CLAMAPI Scan_SetPasswordCallback(CClamAVScanner *pScanner, CLAM_PASSWORD_CALLBACK pfnCallback, void *pContext) { |
|
9 |
+ return CLAMAPI_SUCCESS; |
|
10 |
+} |
|
11 |
+ |
|
12 |
+int CLAMAPI Scan_ScanObjectInMemory(CClamAVScanner *pScanner, const void *pObject, unsigned int objectSize, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList) { |
|
13 |
+ return CLAMAPI_SUCCESS; |
|
14 |
+} |
|
0 | 15 |
\ No newline at end of file |
... | ... |
@@ -25,24 +25,21 @@ |
25 | 25 |
CLAMAPI interface |
26 | 26 |
***************************************************************************************/ |
27 | 27 |
|
28 |
-/* CLAMAPI declspec */ |
|
29 |
-#ifdef CLAMAV_EXPORTS |
|
30 |
-#define CLAMAPI __declspec(dllexport) |
|
31 |
-#else |
|
32 |
-#define CLAMAPI __declspec(dllimport) |
|
33 |
-#endif |
|
34 |
- |
|
35 | 28 |
/* CLAMAPI calling convention. Please do not touch */ |
36 | 29 |
#ifndef CALL_CONVENTION |
37 | 30 |
#define CALL_CONVENTION __cdecl |
38 | 31 |
#endif |
39 | 32 |
|
33 |
+#ifndef CLAMAPI |
|
34 |
+#define CLAMAPI |
|
35 |
+#endif |
|
36 |
+ |
|
40 | 37 |
|
41 | 38 |
/* CLAMAPI - return codes */ |
42 | 39 |
/* Always check for the return value of CLAMAPI's |
43 | 40 |
* Possible values are: |
44 | 41 |
* - return_value == CLAMAPI_SUCCESS: API succeded |
45 |
- * - return_value != CLAMAPI_SUCCESS: API failed (call ClamGetErrorMsg(return_value) to retrieve the error message) |
|
42 |
+ * - return_value != CLAMAPI_SUCCESS: API failed (call Scan_GetErrorMsg(return_value) to retrieve the error message) |
|
46 | 43 |
*/ |
47 | 44 |
#define CLAMAPI_SUCCESS 0 |
48 | 45 |
|
... | ... |
@@ -67,9 +64,10 @@ enum CLAM_SCAN_OPTIONS { |
67 | 67 |
/* CLAMAPI SCAN PHASES */ |
68 | 68 |
/* Define the scan phase to which the returned results refer to */ |
69 | 69 |
typedef enum _CLAM_SCAN_PHASE { |
70 |
+ SCAN_PHASE_INITIAL, /* ight before ClamAV starts scanning the entry (outer) file - in scan callback mode only */ |
|
70 | 71 |
SCAN_PHASE_PRESCAN, /* Right before ClamAV starts scanning the current file - in scan callback mode only */ |
71 | 72 |
SCAN_PHASE_POSTSCAN, /* After ClamAV has scanned the current file - in scan callback mode only */ |
72 |
- SCAN_PHASE_FINAL /* Upon returning from ScanObject */ |
|
73 |
+ SCAN_PHASE_FINAL /* After ClamAV has scanned the entry (outer) file (callback) and upon returning from ScanObject */ |
|
73 | 74 |
} CLAM_SCAN_PHASE; |
74 | 75 |
|
75 | 76 |
|
... | ... |
@@ -88,12 +86,15 @@ typedef struct _CLAM_SCAN_INFO { |
88 | 88 |
/* Presence: ALWAYS */ |
89 | 89 |
int cbSize; |
90 | 90 |
|
91 |
+ /** A single field that can store information regarding packers, installers, compound objects etc **/ |
|
92 |
+ int flags; |
|
93 |
+ |
|
91 | 94 |
/** The phase to which the results refer to **/ |
92 | 95 |
/* Presence: ALWAYS */ |
93 | 96 |
CLAM_SCAN_PHASE scanPhase; |
94 | 97 |
|
95 | 98 |
/** Error condition **/ |
96 |
- /* Possible values: CLAMAPI_SUCCESS if no error; call ClamGetErrorMsg(errorCode) |
|
99 |
+ /* Possible values: CLAMAPI_SUCCESS if no error; call Scan_GetErrorMsg(errorCode) |
|
97 | 100 |
* to retrieve the error message */ |
98 | 101 |
/* Presence: ALWAYS */ |
99 | 102 |
int errorCode; |
... | ... |
@@ -273,7 +274,7 @@ int CLAMAPI Scan_SetOption(CClamAVScanner *pScanner, int option, void *value, un |
273 | 273 |
* INPUT @param errorCode |
274 | 274 |
* NOTE: the returned string is not to be freed! |
275 | 275 |
*/ |
276 |
-const wchar_t *ClamGetErrorMsg(int errorCode); |
|
276 |
+CLAMAPI const wchar_t * Scan_GetErrorMsg(int errorCode); |
|
277 | 277 |
|
278 | 278 |
#ifdef __cplusplus |
279 | 279 |
}; /* extern "C" */ |
... | ... |
@@ -3,6 +3,9 @@ |
3 | 3 |
// check scan funcs |
4 | 4 |
// after scan returns and ret!=CL_VIRUS pInfoList NULL or unchanged? |
5 | 5 |
// changed set option value to 0 or non 0 |
6 |
+// restore file position |
|
7 |
+// cb context per instance or per scanobj ?? |
|
8 |
+// optional shit to really be OPTIONAL! |
|
6 | 9 |
|
7 | 10 |
/* |
8 | 11 |
* Copyright (C) 2010 Sourcefire, Inc. |
... | ... |
@@ -49,6 +52,9 @@ unsigned int engine_refcnt; |
49 | 49 |
#define lock_engine()(WaitForSingleObject(engine_mutex, INFINITE) == WAIT_FAILED) |
50 | 50 |
#define unlock_engine() do {ReleaseMutex(engine_mutex);} while(0) |
51 | 51 |
|
52 |
+cl_error_t prescan_cb(int fd, void *context); |
|
53 |
+cl_error_t postscan_cb(int fd, int result, const char *virname, void *context); |
|
54 |
+ |
|
52 | 55 |
BOOL interface_setup(void) { |
53 | 56 |
if(!(engine_mutex = CreateMutex(NULL, FALSE, NULL))) |
54 | 57 |
return FALSE; |
... | ... |
@@ -127,6 +133,7 @@ int CLAMAPI Scan_Initialize(const wchar_t *pEnginesFolder, const wchar_t *pTempR |
127 | 127 |
unlock_engine(); |
128 | 128 |
FAIL(CL_EMEM, "Not enough memory for a new engine"); |
129 | 129 |
} |
130 |
+ cl_engine_set_clcb_pre_scan(engine, prescan_cb); |
|
130 | 131 |
if(!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pTempRoot, -1, tmpdir, sizeof(tmpdir), NULL, &cant_convert) || cant_convert) { |
131 | 132 |
free_engine_and_unlock(); |
132 | 133 |
FAIL(CL_EARG, "Can't translate pTempRoot"); |
... | ... |
@@ -216,8 +223,11 @@ int CLAMAPI Scan_DestroyInstance(CClamAVScanner *pScanner) { |
216 | 216 |
|
217 | 217 |
int CLAMAPI Scan_SetScanCallback(CClamAVScanner *pScanner, CLAM_SCAN_CALLBACK pfnCallback, void *pContext) { |
218 | 218 |
instance *inst = (instance *)pScanner; |
219 |
+ InterlockedIncrement(&inst->refcnt); |
|
219 | 220 |
inst->scancb = pfnCallback; |
220 | 221 |
inst->scancb_ctx = pContext; |
222 |
+ InterlockedDecrement(&inst->refcnt); |
|
223 |
+ |
|
221 | 224 |
WIN(); |
222 | 225 |
} |
223 | 226 |
|
... | ... |
@@ -327,11 +337,17 @@ int CLAMAPI Scan_ScanObject(CClamAVScanner *pScanner, const wchar_t *pObjectPath |
327 | 327 |
return res; |
328 | 328 |
} |
329 | 329 |
|
330 |
+struct scan_ctx { |
|
331 |
+ int entryfd; |
|
332 |
+ instance *inst; |
|
333 |
+}; |
|
334 |
+ |
|
330 | 335 |
int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList) { |
331 | 336 |
instance *inst = (instance *)pScanner; |
332 | 337 |
HANDLE duphdl, self; |
333 | 338 |
char *virname; |
334 | 339 |
int fd, res; |
340 |
+ struct scan_ctx sctx; |
|
335 | 341 |
|
336 | 342 |
InterlockedIncrement(&inst->refcnt); |
337 | 343 |
|
... | ... |
@@ -347,7 +363,9 @@ int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int |
347 | 347 |
FAIL(CL_EOPEN, "Open handle failed"); |
348 | 348 |
} |
349 | 349 |
|
350 |
- res = cl_scandesc(fd, &virname, NULL, engine, inst->scanopts); |
|
350 |
+ sctx.entryfd = fd; |
|
351 |
+ sctx.inst = inst; |
|
352 |
+ res = cl_scandesc_callback(fd, &virname, NULL, engine, inst->scanopts, &sctx); |
|
351 | 353 |
InterlockedDecrement(&inst->refcnt); |
352 | 354 |
close(fd); |
353 | 355 |
|
... | ... |
@@ -385,3 +403,68 @@ int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST p |
385 | 385 |
WIN(); |
386 | 386 |
} |
387 | 387 |
|
388 |
+cl_error_t prescan_cb(int fd, void *context) { |
|
389 |
+ struct scan_ctx *sctx = (struct scan_ctx *)context; |
|
390 |
+ instance *inst = sctx->inst; |
|
391 |
+ CLAM_SCAN_INFO si; |
|
392 |
+ CLAM_ACTION act; |
|
393 |
+ |
|
394 |
+ logg("in prescan cb with %d %p\n", fd, context); |
|
395 |
+ si.cbSize = sizeof(si); |
|
396 |
+ si.flags = 0; |
|
397 |
+ si.scanPhase = (fd == sctx->entryfd) ? SCAN_PHASE_INITIAL : SCAN_PHASE_PRESCAN; |
|
398 |
+ si.errorCode = CLAMAPI_SUCCESS; |
|
399 |
+ si.pThreatType = NULL; |
|
400 |
+ si.pThreatName = NULL; |
|
401 |
+ si.object = (HANDLE)_get_osfhandle(fd); |
|
402 |
+ si.pInnerObjectPath = NULL; |
|
403 |
+ inst->scancb(&si, &act, inst->scancb_ctx); |
|
404 |
+ switch(act) { |
|
405 |
+ case CLAM_ACTION_SKIP: |
|
406 |
+ logg("prescan cb result: SKIP\n"); |
|
407 |
+ return CL_BREAK; |
|
408 |
+ case CLAM_ACTION_ABORT: |
|
409 |
+ logg("prescan cb result: ABORT\n"); |
|
410 |
+ return CL_VIRUS; |
|
411 |
+ default: |
|
412 |
+ logg("prescan cb returned bogus value\n"); |
|
413 |
+ case CLAM_ACTION_CONTINUE: |
|
414 |
+ logg("prescan cb result: CONTINUE\n"); |
|
415 |
+ return CL_CLEAN; |
|
416 |
+ } |
|
417 |
+} |
|
418 |
+ |
|
419 |
+cl_error_t postscan_cb(int fd, int result, const char *virname, void *context) { |
|
420 |
+ struct scan_ctx *sctx = (struct scan_ctx *)context; |
|
421 |
+ instance *inst = sctx->inst; |
|
422 |
+ CLAM_SCAN_INFO si; |
|
423 |
+ CLAM_ACTION act; |
|
424 |
+ |
|
425 |
+ logg("in prostscan cb with %d %d %s %p\n", fd, result, virname, context); |
|
426 |
+ si.cbSize = sizeof(si); |
|
427 |
+ si.flags = 0; |
|
428 |
+ si.scanPhase = (fd == sctx->entryfd) ? SCAN_PHASE_FINAL : SCAN_PHASE_POSTSCAN; |
|
429 |
+ si.errorCode = CLAMAPI_SUCCESS; |
|
430 |
+ si.pThreatType = NULL; |
|
431 |
+ si.pThreatName = (result == CL_VIRUS) ? L"Fixme" : NULL; /* FIXME */ |
|
432 |
+ si.object = (HANDLE)_get_osfhandle(fd); |
|
433 |
+ si.pInnerObjectPath = NULL; |
|
434 |
+ inst->scancb(&si, &act, inst->scancb_ctx); |
|
435 |
+ switch(act) { |
|
436 |
+ case CLAM_ACTION_SKIP: |
|
437 |
+ logg("postscan cb result: SKIP\n"); |
|
438 |
+ return CL_BREAK; |
|
439 |
+ case CLAM_ACTION_ABORT: |
|
440 |
+ logg("postscan cb result: ABORT\n"); |
|
441 |
+ return CL_VIRUS; |
|
442 |
+ default: |
|
443 |
+ logg("postscan cb returned bogus value\n"); |
|
444 |
+ case CLAM_ACTION_CONTINUE: |
|
445 |
+ logg("prescan cb result: CONTINUE\n"); |
|
446 |
+ return CL_CLEAN; |
|
447 |
+ } |
|
448 |
+} |
|
449 |
+ |
|
450 |
+CLAMAPI const wchar_t * Scan_GetErrorMsg(int errorCode) { |
|
451 |
+ return L"w00t!"; /* FIXME */ |
|
452 |
+} |
... | ... |
@@ -32,6 +32,9 @@ EXPORTS cl_statchkdir @24 |
32 | 32 |
EXPORTS cl_statfree @25 |
33 | 33 |
EXPORTS cl_statinidir @26 |
34 | 34 |
EXPORTS cl_strerror @27 |
35 |
+EXPORTS cl_engine_set_clcb_pre_scan @28 |
|
36 |
+EXPORTS cl_engine_set_clcb_post_scan @29 |
|
37 |
+EXPORTS cl_scandesc_callback @30 |
|
35 | 38 |
|
36 | 39 |
|
37 | 40 |
; path variables |