⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compat.c

📁 clamav 0.93rc1 - 最新版本的源代码
💻 C
字号:
/* *  Copyright (C) 2006 Nigel Horne <njh@bandsman.co.uk> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *  MA 02110-1301, USA. * * Unix/Linux compatibility for Windows * Inspired by glib and the cygwin source code * Tested under Microsoft Visual Studio 2005 */#include <windows.h>#if HAVE_CONFIG_H#include "clamav-config.h"#endif#include <errno.h>#include <string.h>#include "clamav.h"#include "others.h"#ifndef	CL_DEBUG#define	NDEBUG	/* map CLAMAV debug onto standard */#endif#include <stdlib.h>#include <direct.h>#include <io.h>#include <pthread.h>#ifdef	USE_SYSLOG#include <strsafe.h>#include "syslog.h"#endifstatic	const	char	*basename(const char *file_name);/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */#define _W32_FT_OFFSET (116444736000000000ULL)/* * Patches for 64 bit support in opendir by *	Mark Pizzolato clamav-win32@subscriptions.pizzolato.net */DIR *opendir(const char *dirname){	DIR *ret = cli_calloc(1, sizeof(DIR));	char mask[_MAX_PATH + 3];	size_t i, j;	if(ret == NULL)		return NULL;	/* struct _WIN32_FIND_DATAA is what a LPWIN32_FIND_DATA points to */	ret->find_file_data = cli_calloc(1, sizeof(struct _WIN32_FIND_DATAA));	if(ret->find_file_data == NULL) {		free(ret);		return NULL;	}	ret->dir_name = cli_strdup(dirname);	if(ret->dir_name == NULL) {		free(ret->find_file_data);		free(ret);		return NULL;	}	j = strlen(dirname);	for(i = 0; i < j; i++)		if(ret->dir_name[i] == '/')			ret->dir_name[i] = '\\';	if(j && dirname[j - 1] == '\\')		ret->dir_name[--j] = '\0';	sprintf(mask, "%s\\*", ret->dir_name);	ret->find_file_handle = FindFirstFile(mask,				    (LPWIN32_FIND_DATA)ret->find_file_data);	if(ret->find_file_handle == INVALID_HANDLE_VALUE) {		free(ret->find_file_data);		free(ret->dir_name);		free(ret);		cli_warnmsg("Can't opendir(%s)\n", dirname);		return NULL;	}	ret->just_opened = TRUE;	return ret;}struct dirent *readdir(DIR *dir){	/* NOTE: not thread safe */	static struct dirent result;	if(dir == NULL)		return NULL;	if(dir->just_opened)		dir->just_opened = FALSE;	else if(!FindNextFile((HANDLE)dir->find_file_handle, (LPWIN32_FIND_DATA)dir->find_file_data))		switch(GetLastError ()) {			case ERROR_NO_MORE_FILES:				return NULL;			default:				errno = EIO;				return NULL;		}	strcpy(result.d_name, basename(((LPWIN32_FIND_DATA)dir->find_file_data)->cFileName));	return &result;}intreaddir_r(DIR *dir, struct dirent *dirent, struct dirent **output){	if(dir == NULL)		return -1;	if(dirent == NULL)		return -1;	if(output == NULL)		return -1;	if(dir->just_opened)		dir->just_opened = FALSE;	else if(!FindNextFile((HANDLE)dir->find_file_handle, (LPWIN32_FIND_DATA)dir->find_file_data))		switch(GetLastError()) {			case ERROR_NO_MORE_FILES:				*output = NULL;				return -1;			default:				errno = EIO;				*output = NULL;				return -1;		}	strcpy(dirent->d_name, basename(((LPWIN32_FIND_DATA)dir->find_file_data)->cFileName));	*output = dirent;	return 0;}voidrewinddir(DIR *dir){	char mask[_MAX_PATH + 3];	if(dir == NULL)		return;	if(!FindClose((HANDLE)dir->find_file_handle))		cli_warnmsg("rewinddir(): FindClose() failed\n");	sprintf(mask, "%s\\*", dir->dir_name);	dir->find_file_handle = FindFirstFile (mask,					(LPWIN32_FIND_DATA)dir->find_file_data);	if(dir->find_file_handle == INVALID_HANDLE_VALUE) {		errno = EIO;		return;	}	dir->just_opened = TRUE;}intclosedir(DIR *dir){	if(dir == NULL)		return -1;	if(!FindClose((HANDLE)dir->find_file_handle)) {		errno = EIO;		return -1;	}	free(dir->dir_name);	free(dir->find_file_data);	free(dir);	return 0;}static const char *basename(const char *file_name){	const char *base;	if(file_name == NULL)		return NULL;	base = strrchr(file_name, '\\');	if(base)		return base + 1;	if(isalpha(file_name[0] & 0xFF) && (file_name[1] == ':'))		return (const char *)(file_name + 2);	return file_name;}/* From the cygwin source code */intgettimeofday(struct timeval *tp, void *tz){	if(tp) {		union {			unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */			FILETIME ft;		} _now;		GetSystemTimeAsFileTime(&_now.ft);		tp->tv_usec = (long)((_now.ns100 / 10ULL) % 1000000ULL );		tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);	}	/*	 * Always return 0 as per Open Group Base Specifications Issue 6.	 * Do not set errno on error.	 */	return 0;}/* TODO */intgeteuid(void){	return 0;}intgetuid(void){	return 0;}intgetgid(void){	return 0;}/* * mmap patches for more than one map area by *	Mark Pizzolato clamav-win32@subscriptions.pizzolato.net */static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;static struct mmap_context {	struct mmap_context *link;	HANDLE h;	LPVOID view;	size_t length;} *mmaps = NULL;caddr_tmmap(caddr_t address, size_t length, int protection, int flags, int fd, off_t offset){	LPVOID addr;	HANDLE h;	struct mmap_context *ctx;	if(flags != MAP_PRIVATE) {		cli_errmsg("mmap: only MAP_PRIVATE is supported\n");		return MAP_FAILED;	}	if(protection != PROT_READ) {		cli_errmsg("mmap: only PROT_READ is supported\n");		return MAP_FAILED;	}	if(address != NULL) {		cli_errmsg("mmap: only NULL map address is supported\n");		return MAP_FAILED;	}	h = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);	if(h == NULL) {		cli_errmsg("mmap: CreateFileMapping failed - error %d\n",			GetLastError());		return MAP_FAILED;	}	if(GetLastError() == ERROR_ALREADY_EXISTS) {		cli_errmsg("mmap: ERROR_ALREADY_EXISTS\n");		CloseHandle(h);		return MAP_FAILED;	}	addr = MapViewOfFile(h, FILE_MAP_READ,		(DWORD)0, ((DWORD)offset & 0xFFFFFFFF),		length);	if(addr == NULL) {		cli_errmsg("mmap failed - error %d\n", GetLastError());		CloseHandle(h);		return MAP_FAILED;	}	pthread_mutex_lock(&mmap_mutex);	ctx = cli_malloc(sizeof(*ctx));	if(NULL == ctx) {		pthread_mutex_unlock(&mmap_mutex);		cli_errmsg("mmap: can't create context block\n");		UnmapViewOfFile(addr);		CloseHandle(h);		return MAP_FAILED;	}	ctx->h = h;	ctx->view = addr;	ctx->length = length;	ctx->link = mmaps;	mmaps = ctx;	pthread_mutex_unlock(&mmap_mutex);	return (caddr_t)addr;}intmunmap(caddr_t addr, size_t length){	struct mmap_context *ctx = mmaps, *lctx = NULL;	pthread_mutex_lock(&mmap_mutex);		for(; ctx && (ctx->view != addr); ctx = ctx->link)		lctx = ctx;	if(ctx == NULL) {		pthread_mutex_unlock(&mmap_mutex);		cli_warnmsg("munmap with no corresponding mmap\n");		return -1;	}	if(ctx->length != length) {		pthread_mutex_unlock(&mmap_mutex);		cli_warnmsg("munmap with incorrect length specified (%u != %u) - partial munmap unsupported\n",			length, ctx->length);		return -1;	}	if(lctx == NULL)		mmaps = ctx->link;	else		lctx->link = ctx->link;	pthread_mutex_unlock(&mmap_mutex);	UnmapViewOfFile(ctx->view);	CloseHandle(ctx->h);	free(ctx);	return 0;}intchown(const char *filename, short uid, short gid){	return 0;}#ifdef	USE_SYSLOG/* * Put into the Windows Event Log *	Right Click My Computer->Manage->Event Viewer->Application * See http://cybertiggyr.com/gene/wel/src/insert-log.c for inspiration * http://msdn2.microsoft.com/en-gb/library/aa363634(VS.85).aspx * and http://msdn2.microsoft.com/en-us/library/aa363680(VS.85).aspx * * FIXME: Not thread safe, but see shared/output.c, which ensures this code is *	single threaded - therefore don't call this code directly */static	HANDLE	logg_handle;static	int	initlog(const char *source);voidopenlog(const char *name, int options, int facility){	if(logg_handle != NULL)		closelog();	else		(void)initlog(name);	logg_handle = RegisterEventSource(NULL, name);	if(logg_handle == NULL)		cli_warnmsg("openlog: Can't register source %s - error %d\n", name, GetLastError());}voidcloselog(void){	if(logg_handle != NULL)		DeregisterEventSource(logg_handle);}voidsyslog(int level, const char *format, ...){	if(logg_handle == NULL)		openlog("Clam AntiVirus", 0, LOG_LOCAL6);			if(logg_handle != NULL) {		va_list args;		char buff[512];		char *ptr;		va_start(args, format);		(void)vsnprintf(buff, sizeof(buff), format, args);		va_end(args);				ptr = buff;		/*		 * Category = 0, eventId = CLAMAV_EVENTMSG, SID = NULL, 1 string		 */		if(!ReportEventA(logg_handle, (WORD)level, 0, CLAMAV_EVENTMSG, NULL, 1, 0, (LPCSTR *)&ptr, NULL))			cli_warnmsg("syslog: ReportEventA(%d, %d, 0, %d, NULL, 1, 0, %s, NULL) failed: %d\n",				logg_handle, level, CLAMAV_EVENTMSG, buff, GetLastError());	}}static intinitlog(const char *source){	/*DWORD dwCategoryNum = 1;	/* The number of categories for the event source. */	HKEY hk; 	DWORD dwData, /*dwDisp,*/ len;	char path[MAX_PATH];	/* Create the event source as a subkey of the log. */	(void)snprintf(path, sizeof(path),		"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",		source); 	if(RegCreateKey(HKEY_LOCAL_MACHINE, path, &hk) != 0) {		cli_warnmsg("Could not create the registry key\n"); 		/*return 0;*/	} 	/* Set the name of the message file. */	GetModuleFileName(NULL, path, sizeof(path));	path[sizeof(path) - 1] = '\0';	len = (DWORD)(strlen(path) + 1);	if(RegSetValueEx(hk, "EventMessageFile", 0, REG_EXPAND_SZ, (LPBYTE)path, len)) {		cli_warnmsg("Could not set the event message file\n"); 		RegCloseKey(hk); 		return 0;	} 	/* Set the supported event types. */	dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;  	if(RegSetValueEx(hk, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD))) { 		cli_warnmsg("Could not set the supported types\n"); 		RegCloseKey(hk); 		return 0;	} #if	0	/* Set the category message file and number of categories. */	if(RegSetValueEx(hk, "CategoryMessageFile", 0, REG_EXPAND_SZ,	    (LPBYTE)path, len)) {		cli_warnmsg("Could not set the category message file\n"); 		RegCloseKey(hk); 		return 0;	} 	if(RegSetValueEx(hk, "CategoryCount", 0, REG_DWORD, (LPBYTE)&dwCategoryNum, sizeof(DWORD))) {		cli_warnmsg("Could not set the category count\n"); 		RegCloseKey(hk); 		return 0;	}#endif	RegCloseKey(hk); 	return 1;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -