/* $Id$ * User options handling code of libcaptive * Copyright (C) 2003 Jan Kratochvil * * 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; exactly version 2 of June 1991 is required * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "captive/options.h" /* self */ #include #include "captive/macros.h" #include #include #include "captive/rtl-file.h" #include #include #include #include #include #include #include #include gboolean captive_options_module_load(struct captive_options_module *options_module,const gchar *pathname_utf8) { g_return_val_if_fail(options_module!=NULL,FALSE); g_return_val_if_fail(pathname_utf8!=NULL,FALSE); /* Open the Module */ options_module->type=CAPTIVE_OPTIONS_MODULE_TYPE_PE32; options_module->pathname_utf8=g_strdup(pathname_utf8); options_module->u.pe32.mapped=TRUE; options_module->u.pe32.base=captive_rtl_file_mmap( &options_module->u.pe32.length, /* lenp */ pathname_utf8, /* path */ O_RDONLY, /* open_flags */ PROT_READ, /* mmap_prot */ MAP_SHARED); /* mmap_flags */ /* FIXME: convert errno instead of STATUS_INSUFFICIENT_RESOURCES */ g_return_val_if_fail(options_module->u.pe32.base!=NULL,FALSE); if (options_module->u.pe32.length>=2 && (('M'<<8U)|('Z'<<0U))==GUINT16_FROM_BE(*(const guint16 *)options_module->u.pe32.base)) { unsigned char md5_bin[1+128/8]; /* 128 bits==16 bytes; '1+' for leading stub to prevent shorter output of BN_bn2hex() */ BIGNUM *bignum; char *hex,*s; /* already done above */ /* Calculate MD5 sum and convert it to hex string: */ MD5(options_module->u.pe32.base,options_module->u.pe32.length,md5_bin+1); md5_bin[0]=0xFF; /* stub to prevent shorter output of BN_bn2hex() */ bignum=BN_bin2bn(md5_bin,1+128/8,NULL); hex=BN_bn2hex(bignum); g_assert(strlen(hex)==2*(1+128/8)); options_module->u.pe32.md5=g_strdup(hex+2); OPENSSL_free(hex); BN_free(bignum); /* BN_bn2hex() returns uppercased string: */ g_assert(strlen(options_module->u.pe32.md5)==32); for (s=options_module->u.pe32.md5;*s;s++) { g_assert(isxdigit(*s)); *s=tolower(*s); g_assert(isxdigit(*s)); } } else { captive_rtl_file_munmap(options_module->u.pe32.base); options_module->type=CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE; options_module->u.gmodule.pathname=g_strdup(pathname_utf8); } return TRUE; } void captive_options_module_copy(struct captive_options_module *dest,const struct captive_options_module *src) { g_return_if_fail(dest!=NULL); g_return_if_fail(src!=NULL); dest->pathname_utf8=g_strdup(src->pathname_utf8); dest->type=src->type; switch (src->type) { case CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY: g_assert_not_reached(); case CAPTIVE_OPTIONS_MODULE_TYPE_PE32: dest->u.pe32.base=g_memdup(src->u.pe32.base,src->u.pe32.length); dest->u.pe32.length=src->u.pe32.length; dest->u.pe32.mapped=FALSE; dest->u.pe32.md5=g_strdup(src->u.pe32.md5); break; case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE: dest->u.gmodule.pathname=g_strdup(src->u.gmodule.pathname); break; default: g_assert_not_reached(); } } void captive_options_module_free(struct captive_options_module *options_module) { g_return_if_fail(options_module!=NULL); g_free(options_module->pathname_utf8); switch (options_module->type) { case CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY: break; case CAPTIVE_OPTIONS_MODULE_TYPE_PE32: if (options_module->u.pe32.mapped) captive_rtl_file_munmap(options_module->u.pe32.base); else g_free(options_module->u.pe32.base); g_free(options_module->u.pe32.md5); break; case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE: g_free(options_module->u.gmodule.pathname); break; default: g_assert_not_reached(); } }