Browse code

c4w: iface changes for async cloud lookup

aCaB authored on 2011/02/03 00:27:42
Showing 2 changed files
... ...
@@ -119,13 +119,17 @@ typedef struct _CLAM_SCAN_INFO {
119 119
     const wchar_t *pThreatName;
120 120
 
121 121
     /** The handle of the file being processed **/
122
-    /* Note #1: the handle MUST NOT BE CLOSED by the callback
123
-     * Note #2: the handle has got GENERIC_READ	access
122
+    /* Note #1: the handle MUST BE CLOSED by the caller, at any point
123
+     * Note #2: the has FILE_ATTRIBUTE_TEMPORARY and FILE_FLAG_DELETE_ON_CLOSE attributes
124 124
      * Note #3: the file pointer is guaranteed to be set at the begin of
125
-     *          the file and its position needs not to be reset
126
-     * Note #4: the file may already be mapped into memory, entirely or just partially */
125
+     *          the file and its position needs not to be reset */
127 126
     /* Presence: SCAN_PHASE_PRESCAN, SCAN_PHASE_POSTSCAN */
128 127
     HANDLE object;
128
+
129
+    /** An unique identifier for the file being processed **/
130
+    /* Provided for mapping purposes (type HANDLE for legacy reasons) */
131
+    /* Presence: SCAN_PHASE_PRESCAN, SCAN_PHASE_POSTSCAN */
132
+    HANDLE objectId;
129 133
     
130 134
     /** The path of inner file relative to file being scanned **/
131 135
     /* This applies only to archive for which internal names can be retrieved and is NULL otherwise */
... ...
@@ -984,12 +984,14 @@ int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST p
984 984
 
985 985
 cl_error_t prescan_cb(int fd, void *context) {
986 986
     struct scan_ctx *sctx = (struct scan_ctx *)context;
987
+    char tmpf[4096];
987 988
     instance *inst;
988 989
     CLAM_SCAN_INFO si;
989 990
     CLAM_ACTION act;
990 991
     HANDLE fdhdl;
991 992
     DWORD perf;
992
-    LONG lo = 0, hi = 0, hi2 = 0;
993
+    long fpos;
994
+    int rsz;
993 995
 
994 996
     if(!context) {
995 997
 	logg("!prescan_cb called with NULL clamav context\n");
... ...
@@ -1003,18 +1005,42 @@ cl_error_t prescan_cb(int fd, void *context) {
1003 1003
     si.errorCode = CLAMAPI_SUCCESS;
1004 1004
     si.pThreatType = NULL;
1005 1005
     si.pThreatName = NULL;
1006
-    fdhdl = si.object = (HANDLE)_get_osfhandle(fd);
1007 1006
     si.pInnerObjectPath = NULL;
1008 1007
 
1009
-    lo = SetFilePointer(fdhdl, 0, &hi, FILE_CURRENT);
1010
-    SetFilePointer(fdhdl, 0, &hi2, FILE_BEGIN);
1008
+    while(1) {
1009
+	static int tmpn;
1010
+	snprintf(tmpf, sizeof(tmpf), "%s\\%08x.tmp", tmpdir, ++tmpn);
1011
+	tmpf[sizeof(tmpf)-1] = '\0';
1012
+	fdhdl = CreateFile(tmpf, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
1013
+	if(fdhdl != INVALID_HANDLE_VALUE) break;
1014
+	/* FIXME: handle non dup filename errors */
1015
+    }
1016
+
1017
+    fpos = lseek(fd, 0, SEEK_CUR);
1018
+    lseek(fd, 0, SEEK_SET);
1019
+    while((rsz = read(fd, tmpf, sizeof(tmpf))) > 0) {
1020
+	    int wsz = 0;
1021
+	    while(wsz != rsz) {
1022
+		DWORD rwsz;
1023
+		if(!WriteFile(fdhdl, &tmpf[wsz], rsz - wsz, &rwsz, NULL)) {
1024
+		    /* FIXME: handle write fail here */
1025
+		}
1026
+		wsz += rwsz;
1027
+	    }
1028
+    }
1029
+    if(rsz) {
1030
+	/* FIXME: handle read fail here */
1031
+    }
1032
+    lseek(fd, fpos, SEEK_SET);
1033
+    SetFilePointer(fdhdl, 0, NULL, FILE_BEGIN);
1034
+    si.object = fdhdl;
1035
+    si.objectId = (HANDLE)_get_osfhandle(fd);
1011 1036
     logg("*prescan_cb (clamav context %p, instance %p) invoking callback %p with context %p\n", context, inst, inst->scancb, inst->scancb_ctx);
1012 1037
     perf = GetTickCount();
1013 1038
     inst->scancb(&si, &act, inst->scancb_ctx);
1014 1039
     perf = GetTickCount() - perf;
1015 1040
     sctx->cb_times += perf;
1016 1041
     logg("*prescan_cb (clamav context %p, instance %p) callback completed with %u in %u ms\n", context, inst, act, perf);
1017
-    SetFilePointer(fdhdl, lo, &hi, FILE_BEGIN);
1018 1042
     switch(act) {
1019 1043
 	case CLAM_ACTION_SKIP:
1020 1044
 	    logg("*prescan_cb (clamav context %p, instance %p) cb result: SKIP\n", context, inst);
... ...
@@ -1036,10 +1062,8 @@ cl_error_t postscan_cb(int fd, int result, const char *virname, void *context) {
1036 1036
     instance *inst;
1037 1037
     CLAM_SCAN_INFO si;
1038 1038
     CLAM_ACTION act;
1039
-    HANDLE fdhdl;
1040 1039
     DWORD perf;
1041 1040
     wchar_t wvirname[MAX_VIRNAME_LEN] = L"Clam.";
1042
-    LONG lo = 0, hi = 0, hi2 = 0;
1043 1041
 
1044 1042
     if(!context) {
1045 1043
 	logg("!postscan_cb called with NULL clamav context\n");
... ...
@@ -1062,17 +1086,15 @@ cl_error_t postscan_cb(int fd, int result, const char *virname, void *context) {
1062 1062
 	    si.pThreatName = NULL;
1063 1063
     logg("*in postscan_cb with clamav context %p, instance %p, fd %d, result %d, virusname %S)\n", context, inst, fd, result, si.pThreatName);
1064 1064
     si.pThreatType = threat_type(virname);
1065
-    fdhdl = si.object = (HANDLE)_get_osfhandle(fd);
1065
+    si.objectId = (HANDLE)_get_osfhandle(fd);
1066
+    si.object = INVALID_HANDLE_VALUE;
1066 1067
     si.pInnerObjectPath = NULL;
1067
-    lo = SetFilePointer(fdhdl, 0, &hi, FILE_CURRENT);
1068
-    SetFilePointer(fdhdl, 0, &hi2, FILE_BEGIN);
1069 1068
     logg("*postscan_cb (clamav context %p, instance %p) invoking callback %p with context %p\n", context, inst, inst->scancb, inst->scancb_ctx);
1070 1069
     perf = GetTickCount();
1071 1070
     inst->scancb(&si, &act, inst->scancb_ctx);
1072 1071
     perf = GetTickCount() - perf;
1073 1072
     sctx->cb_times += perf;
1074 1073
     logg("*postscan_cb (clamav context %p, instance %p) callback completed with %u in %u ms\n", context, inst, act, perf);
1075
-    SetFilePointer(fdhdl, lo, &hi, FILE_BEGIN);
1076 1074
     switch(act) {
1077 1075
 	case CLAM_ACTION_SKIP:
1078 1076
 	    logg("*postscan_cb (clamav context %p, instance %p) cb result: SKIP\n", context, inst);