Browse code

Added support for more than one mmap region and for 64 bit for opendir

git-svn: trunk@2288

Nigel Horne authored on 2006/09/18 22:42:43
Showing 3 changed files
... ...
@@ -1,3 +1,10 @@
1
+Mon Sep 18 14:41:10 BST 2006 (njh)
2
+----------------------------------
3
+ * contrib/Windows/Projects/clamAV/libclamav:	Fixed support for 64 bit in
4
+		the opendir code.
5
+		Added handler for more than one mmap area.
6
+		Patches from Mark Pizzolato
7
+
1 8
 Sun Sep 17 10:41:24 BST 2006 (njh)
2 9
 ----------------------------------
3 10
   * docs:	Updated to latest version of the Phish Signatures documentation
... ...
@@ -40,12 +40,17 @@
40 40
 #include <stdlib.h>
41 41
 #include <direct.h>
42 42
 #include <io.h>
43
+#include <pthread.h>
43 44
 
44 45
 static const char *basename (const char *file_name);
45 46
 
46 47
 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
47 48
 #define _W32_FT_OFFSET (116444736000000000ULL)
48 49
 
50
+/*
51
+ * Patches for 64 bit support in opendir by
52
+ *	Mark Pizzolato clamav-win32@subscriptions.pizzolato.net
53
+ */
49 54
 DIR *
50 55
 opendir(const char *dirname)
51 56
 {
... ...
@@ -77,10 +82,10 @@ opendir(const char *dirname)
77 77
 
78 78
 	sprintf(mask, "%s\\*", ret->dir_name);
79 79
 
80
-	ret->find_file_handle = (unsigned int)FindFirstFile(mask,
80
+	ret->find_file_handle = FindFirstFile(mask,
81 81
 				    (LPWIN32_FIND_DATA)ret->find_file_data);
82 82
 
83
-	if(ret->find_file_handle == (unsigned int)INVALID_HANDLE_VALUE) {
83
+	if(ret->find_file_handle == INVALID_HANDLE_VALUE) {
84 84
 		free(ret->find_file_data);
85 85
 		free(ret->dir_name);
86 86
 		free(ret);
... ...
@@ -131,8 +136,8 @@ readdir_r(DIR *dir, struct dirent *dirent, struct dirent **output)
131 131
 
132 132
 	if(dir->just_opened)
133 133
 		dir->just_opened = FALSE;
134
-	else if(!FindNextFile ((HANDLE)dir->find_file_handle, (LPWIN32_FIND_DATA)dir->find_file_data))
135
-		switch(GetLastError ()) {
134
+	else if(!FindNextFile((HANDLE)dir->find_file_handle, (LPWIN32_FIND_DATA)dir->find_file_data))
135
+		switch(GetLastError()) {
136 136
 			case ERROR_NO_MORE_FILES:
137 137
 				*output = NULL;
138 138
 				return -1;
... ...
@@ -161,10 +166,10 @@ rewinddir(DIR *dir)
161 161
 
162 162
 	sprintf(mask, "%s\\*", dir->dir_name);
163 163
 
164
-	dir->find_file_handle = (unsigned int)FindFirstFile (mask,
164
+	dir->find_file_handle = FindFirstFile (mask,
165 165
 					(LPWIN32_FIND_DATA)dir->find_file_data);
166 166
 
167
-	if(dir->find_file_handle == (unsigned int)INVALID_HANDLE_VALUE) {
167
+	if(dir->find_file_handle == INVALID_HANDLE_VALUE) {
168 168
 		errno = EIO;
169 169
 		return;
170 170
 	}
... ...
@@ -248,18 +253,25 @@ getgid(void)
248 248
 	return 0;
249 249
 }
250 250
 
251
-static	HANDLE	h;	/* Not thread safe and only one mmap is supported at a time */
251
+/*
252
+ * mmap patches for more than one map area by
253
+ *	Mark Pizzolato clamav-win32@subscriptions.pizzolato.net
254
+ */
255
+static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
256
+
257
+static struct mmap_context {
258
+	struct mmap_context *link;
259
+	HANDLE h;
260
+	LPVOID view;
261
+	size_t length;
262
+} *mmaps = NULL;
252 263
 
253 264
 caddr_t
254 265
 mmap(caddr_t address, size_t length, int protection, int flags, int fd, off_t offset)
255 266
 {
256 267
 	LPVOID addr;
257
-
258
-	if(h) {
259
-		/* FIXME */
260
-		cli_errmsg("mmap: only one region may be mapped at a time\n");
261
-		return MAP_FAILED;
262
-	}
268
+	HANDLE h;
269
+	struct mmap_context *ctx;
263 270
 
264 271
 	if(flags != MAP_PRIVATE) {
265 272
 		cli_errmsg("mmap: only MAP_SHARED is supported\n");
... ...
@@ -269,14 +281,12 @@ mmap(caddr_t address, size_t length, int protection, int flags, int fd, off_t of
269 269
 		cli_errmsg("mmap: only PROT_READ is supported\n");
270 270
 		return MAP_FAILED;
271 271
 	}
272
-
273
-	h = CreateFileMapping(_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
274
-
275
-	if(h && (GetLastError() == ERROR_ALREADY_EXISTS)) {
276
-		cli_errmsg("mmap: ERROR_ALREADY_EXISTS\n");
277
-		CloseHandle(h);
272
+	if(address != NULL) {
273
+		cli_errmsg("mmap: only NULL map address is supported\n");
278 274
 		return MAP_FAILED;
279 275
 	}
276
+	h = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
277
+
280 278
 	if(h == NULL) {
281 279
 		cli_errmsg("mmap: CreateFileMapping failed - error %d\n",
282 280
 			GetLastError());
... ...
@@ -287,29 +297,62 @@ mmap(caddr_t address, size_t length, int protection, int flags, int fd, off_t of
287 287
 		CloseHandle(h);
288 288
 		return MAP_FAILED;
289 289
 	}
290
-	/* FIXME hi DWORD (unsigned long) is 0, so this may not work on 64 bit machines */
291
-	addr = MapViewOfFile(h, FILE_MAP_READ, (DWORD)0,
292
-		((DWORD)address & 0xFFFFFFFF), length);
290
+	addr = MapViewOfFile(h, FILE_MAP_READ,
291
+		(DWORD)0, ((DWORD)offset & 0xFFFFFFFF),
292
+		length);
293 293
 
294 294
 	if(addr == NULL) {
295 295
 		cli_errmsg("mmap failed - error %d\n", GetLastError());
296 296
 		CloseHandle(h);
297 297
 		return MAP_FAILED;
298 298
 	}
299
+	pthread_mutex_lock(&mmap_mutex);
300
+	ctx = cli_malloc(sizeof(*ctx));
301
+	if(NULL == ctx) {
302
+		pthread_mutex_unlock(&mmap_mutex);
303
+		cli_errmsg("mmap: can't create context block\n");
304
+		UnmapViewOfFile(addr);
305
+		CloseHandle(h);
306
+		return MAP_FAILED;
307
+	}
308
+	ctx->h = h;
309
+	ctx->view = addr;
310
+	ctx->length = length;
311
+	ctx->link = mmaps;
312
+	mmaps = ctx;
313
+	pthread_mutex_unlock(&mmap_mutex);
299 314
 	return (caddr_t)addr;
300 315
 }
301 316
 
302 317
 int
303 318
 munmap(caddr_t addr, size_t length)
304 319
 {
305
-	if(h == NULL) {
320
+	struct mmap_context *ctx, *lctx = NULL;
321
+
322
+	pthread_mutex_lock(&mmap_mutex);
323
+	for(ctx = mmaps; ctx && (ctx->view != addr); ) {
324
+		lctx = ctx;
325
+		ctx = ctx->link;
326
+	}
327
+	if(ctx == NULL) {
328
+		pthread_mutex_unlock(&mmap_mutex);
306 329
 		cli_warnmsg("munmap with no corresponding mmap\n");
307 330
 		return -1;
308 331
 	}
309
-	UnmapViewOfFile((LPCVOID)addr);
310
-	CloseHandle(h);
311
-
312
-	h = NULL;
332
+	if(ctx->length != length) {
333
+		pthread_mutex_unlock(&mmap_mutex);
334
+		cli_warnmsg("munmap with incorrect length specified - partial munmap unsupported\n");
335
+		return -1;
336
+	}
337
+	if(NULL == lctx)
338
+		mmaps = ctx->link;
339
+	else
340
+		lctx->link = ctx->link;
341
+	pthread_mutex_unlock(&mmap_mutex);
342
+
343
+	UnmapViewOfFile(ctx->view);
344
+	CloseHandle(ctx->h);
345
+	free(ctx);
313 346
 
314 347
 	return 0;
315 348
 }
... ...
@@ -26,7 +26,7 @@
26 26
 
27 27
 #ifdef	C_WINDOWS
28 28
 
29
-#pragma warning(disable: 4996)      /* turn of warnings about depracated code */
29
+#pragma warning(disable: 4996)	/* turn off warnings about depracated code */
30 30
 
31 31
 /*#include	"snprintf.h"*/
32 32
 
... ...
@@ -89,7 +89,7 @@ struct timeval {
89 89
 struct DIR {
90 90
 	char    *dir_name;
91 91
 	int	just_opened;
92
-	unsigned int     find_file_handle;
92
+	void	*find_file_handle;
93 93
 	void	*find_file_data;	/* LPWIN32_FIND_DATA */
94 94
 };
95 95
 typedef struct	DIR	DIR;