diff options
142 files changed, 33915 insertions, 33915 deletions
diff --git a/utils/zenutils/CMakeLists.txt b/utils/zenutils/CMakeLists.txt index 32798747cd..0983d394a7 100755..100644 --- a/utils/zenutils/CMakeLists.txt +++ b/utils/zenutils/CMakeLists.txt @@ -1,13 +1,13 @@ -PROJECT(zenutils)
-
-SET(EXECUTABLE_OUTPUT_PATH ${zenutils_SOURCE_DIR}/bin/${CMAKE_SYSTEM_NAME})
-
-SUBDIRS(source libraries)
-
-INCLUDE_DIRECTORIES(
- ${zenutils_SOURCE_DIR}/libraries/beecrypt-4.1.2
- ${zenutils_SOURCE_DIR}/libraries/getpot-c++-1.1.17
- ${zenutils_SOURCE_DIR}/libraries/pelib-0.9
- ${zenutils_SOURCE_DIR}/libraries/zlib123
- ${zenutils_SOURCE_DIR}/source/shared
-)
+PROJECT(zenutils) + +SET(EXECUTABLE_OUTPUT_PATH ${zenutils_SOURCE_DIR}/bin/${CMAKE_SYSTEM_NAME}) + +SUBDIRS(source libraries) + +INCLUDE_DIRECTORIES( + ${zenutils_SOURCE_DIR}/libraries/beecrypt-4.1.2 + ${zenutils_SOURCE_DIR}/libraries/getpot-c++-1.1.17 + ${zenutils_SOURCE_DIR}/libraries/pelib-0.9 + ${zenutils_SOURCE_DIR}/libraries/zlib123 + ${zenutils_SOURCE_DIR}/source/shared +) diff --git a/utils/zenutils/COPYING b/utils/zenutils/COPYING index d511905c16..d511905c16 100755..100644 --- a/utils/zenutils/COPYING +++ b/utils/zenutils/COPYING diff --git a/utils/zenutils/libraries/CMakeLists.txt b/utils/zenutils/libraries/CMakeLists.txt index 19297d7a2e..82f5824c81 100755..100644 --- a/utils/zenutils/libraries/CMakeLists.txt +++ b/utils/zenutils/libraries/CMakeLists.txt @@ -1,3 +1,3 @@ -ADD_SUBDIRECTORY(beecrypt-4.1.2)
-ADD_SUBDIRECTORY(pelib-0.9)
-ADD_SUBDIRECTORY(zlib123)
+ADD_SUBDIRECTORY(beecrypt-4.1.2) +ADD_SUBDIRECTORY(pelib-0.9) +ADD_SUBDIRECTORY(zlib123) diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/CMakeLists.txt b/utils/zenutils/libraries/beecrypt-4.1.2/CMakeLists.txt index 83836af99d..7044ec090a 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/CMakeLists.txt +++ b/utils/zenutils/libraries/beecrypt-4.1.2/CMakeLists.txt @@ -1,14 +1,14 @@ -PROJECT(beecrypt)
-
-# source files for beecrypt
-SET(beecrypt_srcs
- beecrypt/blockmode.c
- beecrypt/blowfish.c
- beecrypt/endianness.c
- beecrypt/hmac.c
- beecrypt/hmacsha1.c
- beecrypt/mp.c
- beecrypt/sha1.c
-)
-
-ADD_LIBRARY(beecrypt ${beecrypt_srcs})
+PROJECT(beecrypt) + +# source files for beecrypt +SET(beecrypt_srcs + beecrypt/blockmode.c + beecrypt/blowfish.c + beecrypt/endianness.c + beecrypt/hmac.c + beecrypt/hmacsha1.c + beecrypt/mp.c + beecrypt/sha1.c +) + +ADD_LIBRARY(beecrypt ${beecrypt_srcs}) diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/AUTHORS b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/AUTHORS index 878abf5a3f..878abf5a3f 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/AUTHORS +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/AUTHORS diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BENCHMARKS b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BENCHMARKS index 7919f340db..7919f340db 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BENCHMARKS +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BENCHMARKS diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BUGS b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BUGS index 577c5adac5..577c5adac5 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BUGS +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/BUGS diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CONTRIBUTORS b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CONTRIBUTORS index 7f61011475..7f61011475 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CONTRIBUTORS +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CONTRIBUTORS diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING index a6d7d0188a..a6d7d0188a 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING.LIB b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING.LIB index 223ede7de3..223ede7de3 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING.LIB +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/COPYING.LIB diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/ChangeLog b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/ChangeLog index e69de29bb2..e69de29bb2 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/ChangeLog +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/ChangeLog diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/INSTALL b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/INSTALL index bca44d042e..bca44d042e 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/INSTALL +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/INSTALL diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/NEWS b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/NEWS index 6c6bbd0175..6c6bbd0175 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/NEWS +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/NEWS diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README index d875372c39..d875372c39 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.DLL b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.DLL index 2131f87ce2..2131f87ce2 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.DLL +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.DLL diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.WIN32 b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.WIN32 index 411116fea2..411116fea2 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.WIN32 +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/README.WIN32 diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/api.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/api.h index f5ef7ff04a..f5ef7ff04a 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/api.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/api.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/beecrypt.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/beecrypt.h index a4c8780d03..a4c8780d03 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/beecrypt.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/beecrypt.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.c index cfccd43337..cfccd43337 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.h index 4f21b81f65..4f21b81f65 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blockmode.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.c index a8b801e6ec..a8b801e6ec 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.h index 1d95ddb4f2..1d95ddb4f2 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfish.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfishopt.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfishopt.h index f38db94b52..f38db94b52 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfishopt.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/blowfishopt.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.c index 8a0999b63e..8a0999b63e 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.h index e136aa59f9..e136aa59f9 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/endianness.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/gnu.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/gnu.h index 18386ef997..18386ef997 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/gnu.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/gnu.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.c index c28770a05b..c28770a05b 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.h index 709bb079f0..709bb079f0 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmac.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.c index f201a45f0f..f201a45f0f 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.h index 207f5df37f..207f5df37f 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/hmacsha1.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/memchunk.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/memchunk.h index 4778b7ca89..4778b7ca89 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/memchunk.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/memchunk.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.c index 82d272c17a..82d272c17a 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.h index 57a3e6c502..57a3e6c502 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mp.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpnumber.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpnumber.h index f42e82a80f..f42e82a80f 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpnumber.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpnumber.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpopt.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpopt.h index 7ba66bb5f9..7ba66bb5f9 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpopt.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/mpopt.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/rsa.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/rsa.h index dbb0e45412..dbb0e45412 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/rsa.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/rsa.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.c b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.c index fe7c2cd8b4..fe7c2cd8b4 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.c +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.c diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.h index a35c917fdd..a35c917fdd 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1opt.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1opt.h index 62ea87718f..62ea87718f 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1opt.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/sha1opt.h diff --git a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/win.h b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/win.h index d578085c29..d578085c29 100755..100644 --- a/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/win.h +++ b/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/win.h diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot index 0663880990..0663880990 100755..100644 --- a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt index b1e3f5a263..b1e3f5a263 100755..100644 --- a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README index 3d55352a6b..3d55352a6b 100755..100644 --- a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp index fe820c91a2..9986d17893 100755..100644 --- a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp @@ -1,2435 +1,2435 @@ -// -*- c++ -*-
-// GetPot Version $$Version$$ $$Date$$
-//
-// WEBSITE: http://getpot.sourceforge.net
-//
-// NOTE: The LPGL License for this library is only valid in case that
-// it is not used for the production or development of applications
-// dedicated to military industry. This is what the author calls
-// the 'unofficial peace version of the LPGL'.
-//
-// This library is free software; you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation; either version 2.1 of the
-// License, or (at your option) any later version.
-//
-// This library 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
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA
-//
-// (C) 2001-2005 Frank R. Schaefer <fschaef@users.sf.net>
-//==========================================================================
-
-#ifndef __include_guard_GETPOT_H__
-#define __include_guard_GETPOT_H__
-
-#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
-#define strtok_r(a, b, c) strtok(a, b)
-#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
-
-extern "C" {
-// leave the 'extern C' to make it 100% sure to work -
-// expecially with older distributions of header files.
-#ifndef WIN32
-// this is necessary (depending on OS)
-#include <ctype.h>
-#endif
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-}
-#include <cmath>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <fstream>
-#include <iostream> // not every compiler distribution includes <iostream>
-// // with <fstream>
-
-typedef std::vector<std::string> STRING_VECTOR;
-
-#define victorate(TYPE, VARIABLE, ITERATOR) \
- std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \
- for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++)
-
-
-class GetPot {
- //--------
- inline void __basic_initialization();
-public:
- // (*) constructors, destructor, assignment operator -----------------------
- inline GetPot();
- inline GetPot(const GetPot&);
- inline GetPot(const int argc_, char** argv_,
- const char* FieldSeparator=0x0);
- inline GetPot(const char* FileName,
- const char* CommentStart=0x0, const char* CommentEnd=0x0,
- const char* FieldSeparator=0x0);
- inline ~GetPot();
- inline GetPot& operator=(const GetPot&);
-
-
- // (*) absorbing contents of another GetPot object
- inline void absorb(const GetPot& That);
- // -- for ufo detection: recording requested arguments, options etc.
- inline void clear_requests();
- inline void disable_request_recording() { __request_recording_f = false; }
- inline void enable_request_recording() { __request_recording_f = true; }
-
- // (*) direct access to command line arguments -----------------------------
- inline const std::string operator[](unsigned Idx) const;
- inline int get(unsigned Idx, int Default) const;
- inline double get(unsigned Idx, const double& Default) const;
- inline const std::string get(unsigned Idx, const char* Default) const;
- inline unsigned size() const;
-
- // (*) flags ---------------------------------------------------------------
- inline bool options_contain(const char* FlagList) const;
- inline bool argument_contains(unsigned Idx, const char* FlagList) const;
-
- // (*) variables -----------------------------------------------------------
- // -- scalar values
- inline int operator()(const char* VarName, int Default) const;
- inline double operator()(const char* VarName, const double& Default) const;
- inline const std::string operator()(const char* VarName, const char* Default) const;
- // -- vectors
- inline int operator()(const char* VarName, int Default, unsigned Idx) const;
- inline double operator()(const char* VarName, const double& Default, unsigned Idx) const;
- inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const;
-
- // -- setting variables
- // i) from outside of GetPot (considering prefix etc.)
- // ii) from inside, use '__set_variable()' below
- inline void set(const char* VarName, const char* Value, const bool Requested = true);
- inline void set(const char* VarName, const double& Value, const bool Requested = true);
- inline void set(const char* VarName, const int Value, const bool Requested = true);
-
- inline unsigned vector_variable_size(const char* VarName) const;
- inline STRING_VECTOR get_variable_names() const;
- inline STRING_VECTOR get_section_names() const;
-
-
- // (*) cursor oriented functions -------------------------------------------
- inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); }
- inline bool search_failed() const { return search_failed_f; }
-
- // -- enable/disable search for an option in loop
- inline void disable_loop() { search_loop_f = false; }
- inline void enable_loop() { search_loop_f = true; }
-
- // -- reset cursor to position '1'
- inline void reset_cursor();
- inline void init_multiple_occurrence();
-
- // -- search for a certain option and set cursor to position
- inline bool search(const char* option);
- inline bool search(unsigned No, const char* P, ...);
- // -- get argument at cursor++
- inline int next(int Default);
- inline double next(const double& Default);
- inline const std::string next(const char* Default);
- // -- search for option and get argument at cursor++
- inline int follow(int Default, const char* Option);
- inline double follow(const double& Default, const char* Option);
- inline const std::string follow(const char* Default, const char* Option);
- // -- search for one of the given options and get argument that follows it
- inline int follow(int Default, unsigned No, const char* Option, ...);
- inline double follow(const double& Default, unsigned No, const char* Option, ...);
- inline const std::string follow(const char* Default, unsigned No, const char* Option, ...);
- // -- lists of nominuses following an option
- inline std::vector<std::string> nominus_followers(const char* Option);
- inline std::vector<std::string> nominus_followers(unsigned No, ...);
-
- // -- directly followed arguments
- inline int direct_follow(int Default, const char* Option);
- inline double direct_follow(const double& Default, const char* Option);
- inline const std::string direct_follow(const char* Default, const char* Option);
-
- inline std::vector<std::string> string_tails(const char* StartString);
- inline std::vector<int> int_tails(const char* StartString, const int Default = 1);
- inline std::vector<double> double_tails(const char* StartString, const double Default = 1.0);
-
- // (*) nominus arguments ---------------------------------------------------
- inline STRING_VECTOR nominus_vector() const;
- inline unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); }
- inline std::string next_nominus();
-
- // (*) unidentified flying objects -----------------------------------------
- inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
- inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const;
- inline STRING_VECTOR unidentified_arguments() const;
-
- inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
- inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const;
- inline STRING_VECTOR unidentified_options() const;
-
- inline std::string unidentified_flags(const char* Known,
- int ArgumentNumber /* =-1 */) const;
-
- inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
- inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const;
- inline STRING_VECTOR unidentified_variables() const;
-
- inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
- inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const;
- inline STRING_VECTOR unidentified_sections() const;
-
- inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
- inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const;
- inline STRING_VECTOR unidentified_nominuses() const;
-
- // (*) output --------------------------------------------------------------
- inline int print() const;
-
-private:
- // (*) Type Declaration ----------------------------------------------------
- struct variable {
- //-----------
- // Variable to be specified on the command line or in input files.
- // (i.e. of the form var='12 312 341')
-
- // -- constructors, destructors, assignment operator
- variable();
- variable(const variable&);
- variable(const char* Name, const char* Value, const char* FieldSeparator);
- ~variable();
- variable& operator=(const variable& That);
-
- void take(const char* Value, const char* FieldSeparator);
-
- // -- get a specific element in the string vector
- // (return 0 if not present)
- const std::string* get_element(unsigned Idx) const;
-
- // -- data memebers
- std::string name; // identifier of variable
- STRING_VECTOR value; // value of variable stored in vector
- std::string original; // value of variable as given on command line
- };
-
- // (*) member variables --------------------------------------------------------------
- std::string prefix; // prefix automatically added in queries
- std::string section; // (for dollar bracket parsing)
- STRING_VECTOR section_list; // list of all parsed sections
- // -- argument vector
- STRING_VECTOR argv; // vector of command line arguments stored as strings
- unsigned cursor; // cursor for argv
- bool search_loop_f; // shall search start at beginning after
- // // reaching end of arg array ?
- bool search_failed_f; // flag indicating a failed search() operation
- // // (e.g. next() functions react with 'missed')
-
- // -- nominus vector
- int nominus_cursor; // cursor for nominus_pointers
- std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments
-
- // -- variables
- // (arguments of the form "variable=value")
- std::vector<variable> variables;
-
- // -- comment delimiters
- std::string _comment_start;
- std::string _comment_end;
-
- // -- field separator (separating elements of a vector)
- std::string _field_separator;
-
- // -- some functions return a char pointer to a temporarily existing string
- // this container makes them 'available' until the getpot object is destroyed.
- std::vector<char*> __internal_string_container;
-
- // -- keeping track about arguments that are requested, so that the UFO detection
- // can be simplified
- STRING_VECTOR _requested_arguments;
- STRING_VECTOR _requested_variables;
- STRING_VECTOR _requested_sections;
-
- bool __request_recording_f; // speed: request recording can be turned off
-
- // -- if an argument is requested record it and the 'tag' the section branch to which
- // it belongs. Caution: both functions mark the sections as 'tagged'.
- void __record_argument_request(const std::string& Arg);
- void __record_variable_request(const std::string& Arg);
-
- // (*) helper functions ----------------------------------------------------
- // set variable from inside GetPot (no prefix considered)
- inline void __set_variable(const char* VarName, const char* Value);
-
- // -- produce three basic data vectors:
- // - argument vector
- // - nominus vector
- // - variable dictionary
- inline void __parse_argument_vector(const STRING_VECTOR& ARGV);
-
- // -- helpers for argument list processing
- // * search for a variable in 'variables' array
- inline const variable* __find_variable(const char*) const;
- // * support finding directly followed arguments
- inline const char* __match_starting_string(const char* StartString);
- // * support search for flags in a specific argument
- inline bool __check_flags(const std::string& Str, const char* FlagList) const;
- // * type conversion if possible
- inline int __convert_to_type(const std::string& String, int Default) const;
- inline double __convert_to_type(const std::string& String, double Default) const;
- // * prefix extraction
- const std::string __get_remaining_string(const std::string& String,
- const std::string& Start) const;
- // * search for a specific string
- inline bool __search_string_vector(const STRING_VECTOR& Vec,
- const std::string& Str) const;
-
- // -- helpers to parse input file
- // create an argument vector based on data found in an input file, i.e.:
- // 1) delete comments (in between '_comment_start' '_comment_end')
- // 2) contract assignment expressions, such as
- // my-variable = '007 J. B.'
- // into
- // my-variable='007 J. B.'
- // 3) interprete sections like '[../my-section]' etc.
- inline void __skip_whitespace(std::istream& istr);
- inline const std::string __get_next_token(std::istream& istr);
- inline const std::string __get_string(std::istream& istr);
- inline const std::string __get_until_closing_bracket(std::istream& istr);
-
- inline STRING_VECTOR __read_in_stream(std::istream& istr);
- inline STRING_VECTOR __read_in_file(const char* FileName);
- inline std::string __process_section_label(const std::string& Section,
- STRING_VECTOR& section_stack);
-
- // -- dollar bracket expressions
- std::string __DBE_expand_string(const std::string str);
- std::string __DBE_expand(const std::string str);
- const GetPot::variable* __DBE_get_variable(const std::string str);
- STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber);
-
- std::string __double2string(const double& Value) const {
- // -- converts a double integer into a string
- char* tmp = new char[128];
-#ifndef WIN32
- snprintf(tmp, (int)sizeof(char)*128, "%e", Value);
-#else
- _snprintf(tmp, sizeof(char)*128, "%e", Value);
-#endif
- std::string result(tmp);
- delete [] tmp;
- return result;
- }
-
- std::string __int2string(const int& Value) const {
- // -- converts an integer into a string
- char* tmp = new char[128];
-#ifndef WIN32
- snprintf(tmp, (int)sizeof(char)*128, "%i", Value);
-#else
- _snprintf(tmp, sizeof(char)*128, "%i", Value);
-#endif
- std::string result(tmp);
- delete [] tmp;
- return result;
- }
-
- STRING_VECTOR __get_section_tree(const std::string& FullPath) {
- // -- cuts a variable name into a tree of sub-sections. this is requested for recording
- // requested sections when dealing with 'ufo' detection.
- STRING_VECTOR result;
- const char* Start = FullPath.c_str();
-
- for(char *p = (char*)Start; *p ; p++) {
- if( *p == '/' ) {
- *p = '\0'; // set terminating zero for convinience
- const std::string Section = Start;
- *p = '/'; // reset slash at place
- result.push_back(Section);
- }
- }
-
- return result;
- }
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) constructors, destructor, assignment operator
-//.............................................................................
-//
-inline void
-GetPot::__basic_initialization()
-{
- cursor = 0; nominus_cursor = -1;
- search_failed_f = true; search_loop_f = true;
- prefix = ""; section = "";
-
- // automatic request recording for later ufo detection
- __request_recording_f = true;
-
- // comment start and end strings
- _comment_start = std::string("#");
- _comment_end = std::string("\n");
-
- // default: separate vector elements by whitespaces
- _field_separator = " \t\n";
-}
-
-inline
-GetPot::GetPot()
-{
- __basic_initialization();
-
- STRING_VECTOR _apriori_argv;
- _apriori_argv.push_back(std::string("Empty"));
- __parse_argument_vector(_apriori_argv);
-}
-
-inline
-GetPot::GetPot(const int argc_, char ** argv_,
- const char* FieldSeparator /* =0x0 */)
- // leave 'char**' non-const to honor less capable compilers ...
-{
- // TODO: Ponder over the problem when the argument list is of size = 0.
- // This is 'sabotage', but it can still occur if the user specifies
- // it himself.
- assert(argc_ >= 1);
- __basic_initialization();
-
- // if specified -> overwrite default string
- if( FieldSeparator ) _field_separator = std::string(FieldSeparator);
-
- // -- make an internal copy of the argument list:
- STRING_VECTOR _apriori_argv;
- // -- for the sake of clarity: we do want to include the first argument in the argument vector !
- // it will not be a nominus argument, though. This gives us a minimun vector size of one
- // which facilitates error checking in many functions. Also the user will be able to
- // retrieve the name of his application by "get[0]"
- _apriori_argv.push_back(std::string(argv_[0]));
- int i=1;
- for(; i<argc_; ++i) {
- std::string tmp(argv_[i]); // recall the problem with temporaries,
- _apriori_argv.push_back(tmp); // reference counting in arguement lists ...
- }
- __parse_argument_vector(_apriori_argv);
-}
-
-
-inline
-GetPot::GetPot(const char* FileName,
- const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
- const char* FieldSeparator/* = 0x0 */)
-{
- __basic_initialization();
-
- // if specified -> overwrite default strings
- if( CommentStart ) _comment_start = std::string(CommentStart);
- if( CommentEnd ) _comment_end = std::string(CommentEnd);
- if( FieldSeparator ) _field_separator = FieldSeparator;
-
- STRING_VECTOR _apriori_argv;
- // -- file name is element of argument vector, however, it is not parsed for
- // variable assignments or nominuses.
- _apriori_argv.push_back(std::string(FileName));
-
- STRING_VECTOR args = __read_in_file(FileName);
- _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
- __parse_argument_vector(_apriori_argv);
-}
-
-inline
-GetPot::GetPot(const GetPot& That)
-{ GetPot::operator=(That); }
-
-inline
-GetPot::~GetPot()
-{
- // may be some return strings had to be created, delete now !
- victorate(char*, __internal_string_container, it)
- delete [] *it;
-}
-
-inline GetPot&
-GetPot::operator=(const GetPot& That)
-{
- if (&That == this) return *this;
-
- _comment_start = That._comment_start;
- _comment_end = That._comment_end;
- argv = That.argv;
- variables = That.variables;
- prefix = That.prefix;
-
- cursor = That.cursor;
- nominus_cursor = That.nominus_cursor;
- search_failed_f = That.search_failed_f;
-
- idx_nominus = That.idx_nominus;
- search_loop_f = That.search_loop_f;
-
- return *this;
-}
-
-
-inline void
-GetPot::absorb(const GetPot& That)
-{
- if (&That == this) return;
-
- STRING_VECTOR __tmp(That.argv);
-
- __tmp.erase(__tmp.begin());
-
- __parse_argument_vector(__tmp);
-}
-
-inline void
-GetPot::clear_requests()
-{
- _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end());
- _requested_variables.erase(_requested_variables.begin(), _requested_variables.end());
- _requested_sections.erase(_requested_sections.begin(), _requested_sections.end());
-}
-
-inline void
-GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV)
-{
- if( ARGV.size() == 0 ) return;
-
- // build internal databases:
- // 1) array with no-minus arguments (usually used as filenames)
- // 2) variable assignments:
- // 'variable name' '=' number | string
- STRING_VECTOR section_stack;
- STRING_VECTOR::const_iterator it = ARGV.begin();
-
-
- section = "";
-
- // -- do not parse the first argument, so that it is not interpreted a s a nominus or so.
- argv.push_back(*it);
- ++it;
-
- // -- loop over remaining arguments
- unsigned i=1;
- for(; it != ARGV.end(); ++it, ++i) {
- std::string arg = *it;
-
- if( arg.length() == 0 ) continue;
-
- // -- [section] labels
- if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) {
-
- // (*) sections are considered 'requested arguments'
- if( __request_recording_f ) _requested_arguments.push_back(arg);
-
- const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2));
- section = __process_section_label(Name, section_stack);
- // new section --> append to list of sections
- if( find(section_list.begin(), section_list.end(), section) == section_list.end() )
- if( section.length() != 0 ) section_list.push_back(section);
- argv.push_back(arg);
- }
- else {
- arg = section + __DBE_expand_string(arg);
- argv.push_back(arg);
- }
-
- // -- separate array for nominus arguments
- if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i));
-
- // -- variables: does arg contain a '=' operator ?
- const char* p = arg.c_str();
- for(; *p ; p++) {
- if( *p == '=' ) {
- // (*) record for later ufo detection
- // arguments carriying variables are always treated as 'requested' arguments.
- // as a whole! That is 'x=4712' is considered a requested argument.
- //
- // unrequested variables have to be detected with the ufo-variable
- // detection routine.
- if( __request_recording_f ) _requested_arguments.push_back(arg);
-
- // set terminating 'zero' to treat first part as single string
- // => arg (from start to 'p') = Name of variable
- // p+1 (until terminating zero) = value of variable
- char* o = (char*)p++;
- *o = '\0'; // set temporary terminating zero
- // __set_variable(...)
- // calls __find_variable(...) which registers the search
- // temporarily disable this
- const bool tmp = __request_recording_f;
- __request_recording_f = false;
- __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest
- __request_recording_f = tmp;
- *o = '='; // reset the original '='
- break;
- }
- }
- }
-}
-
-
-inline STRING_VECTOR
-GetPot::__read_in_file(const char* FileName)
-{
- std::ifstream i(FileName);
- if( ! i ) return STRING_VECTOR();
- // argv[0] == the filename of the file that was read in
- return __read_in_stream(i);
-}
-
-inline STRING_VECTOR
-GetPot::__read_in_stream(std::istream& istr)
-{
- STRING_VECTOR brute_tokens;
- while(istr) {
- __skip_whitespace(istr);
-
- const std::string Token = __get_next_token(istr);
- if( Token.length() == 0 || Token[0] == EOF) break;
- brute_tokens.push_back(Token);
- }
-
- // -- reduce expressions of token1'='token2 to a single
- // string 'token1=token2'
- // -- copy everything into 'argv'
- // -- arguments preceded by something like '[' name ']' (section)
- // produce a second copy of each argument with a prefix '[name]argument'
- unsigned i1 = 0;
- unsigned i2 = 1;
- unsigned i3 = 2;
-
- STRING_VECTOR arglist;
- while( i1 < brute_tokens.size() ) {
- const std::string& SRef = brute_tokens[i1];
- // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
- // note: java.lang.String: substring(a,b) = from a to b-1
- // C++ string: substr(a,b) = from a to a + b
- if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) {
- if( i3 >= brute_tokens.size() )
- arglist.push_back(brute_tokens[i1] + brute_tokens[i2]);
- else
- arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
- i1 = i3+1; i2 = i3+2; i3 = i3+3;
- continue;
- }
- else {
- arglist.push_back(SRef);
- i1=i2; i2=i3; i3++;
- }
- }
- return arglist;
-}
-
-inline void
-GetPot::__skip_whitespace(std::istream& istr)
- // find next non-whitespace while deleting comments
-{
- int tmp = istr.get();
- do {
- // -- search a non whitespace
- while( isspace(tmp) ) {
- tmp = istr.get();
- if( ! istr ) return;
- }
-
- // -- look if characters match the comment starter string
- const std::istream::pos_type Pos = istr.tellg();
- unsigned i=0;
- for(; i<_comment_start.length() ; ++i) {
- if( tmp != _comment_start[i] ) {
-// HACK: The following line throws off msvc8:
-// istr.seekg(Pos);
- // -- one step more backwards, since 'tmp' already at non-whitespace
- istr.unget();
- return;
- }
- tmp = istr.get();
- if( ! istr ) { istr.unget(); return; }
- }
- // 'tmp' contains last character of _comment_starter
-
- // -- comment starter found -> search for comment ender
- unsigned match_no=0;
- while(1+1 == 2) {
- tmp = istr.get();
- if( ! istr ) { istr.unget(); return; }
-
- if( tmp == _comment_end[match_no] ) {
- match_no++;
- if( match_no == _comment_end.length() ) {
- istr.unget();
- break; // shuffle more whitespace, end of comment found
- }
- }
- else
- match_no = 0;
- }
-
- tmp = istr.get();
-
- } while( istr );
- istr.unget();
-}
-
-inline const std::string
-GetPot::__get_next_token(std::istream& istr)
- // get next concatinates string token. consider quotes that embrace
- // whitespaces
-{
- std::string token;
- int tmp = 0;
- int last_letter = 0;
- while(1+1 == 2) {
- last_letter = tmp; tmp = istr.get();
- if( tmp == EOF
- || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) {
- return token;
- }
- else if( tmp == '\'' && last_letter != '\\' ) {
- // QUOTES: un-backslashed quotes => it's a string
- token += __get_string(istr);
- continue;
- }
- else if( tmp == '{' && last_letter == '$') {
- token += '{' + __get_until_closing_bracket(istr);
- continue;
- }
- else if( tmp == '$' && last_letter == '\\') {
- token += tmp; tmp = 0; // so that last_letter will become = 0, not '$';
- continue;
- }
- else if( tmp == '\\' && last_letter != '\\')
- continue; // don't append un-backslashed backslashes
- token += tmp;
- }
-}
-
-inline const std::string
-GetPot::__get_string(std::istream& istr)
- // parse input until next matching '
-{
- std::string str;
- int tmp = 0;
- int last_letter = 0;
- while(1 + 1 == 2) {
- last_letter = tmp; tmp = istr.get();
- if( tmp == EOF) return str;
- // un-backslashed quotes => it's the end of the string
- else if( tmp == '\'' && last_letter != '\\') return str;
- else if( tmp == '\\' && last_letter != '\\') continue; // don't append
-
- str += tmp;
- }
-}
-
-inline const std::string
-GetPot::__get_until_closing_bracket(std::istream& istr)
- // parse input until next matching }
-{
- std::string str = "";
- int tmp = 0;
- int last_letter = 0;
- int brackets = 1;
- while(1 + 1 == 2) {
- last_letter = tmp; tmp = istr.get();
- if( tmp == EOF) return str;
- else if( tmp == '{' && last_letter == '$') brackets += 1;
- else if( tmp == '}') {
- brackets -= 1;
- // un-backslashed brackets => it's the end of the string
- if( brackets == 0) return str + '}';
- else if( tmp == '\\' && last_letter != '\\')
- continue; // do not append an unbackslashed backslash
- }
- str += tmp;
- }
-}
-
-inline std::string
-GetPot::__process_section_label(const std::string& Section,
- STRING_VECTOR& section_stack)
-{
- std::string sname = Section;
- // 1) subsection of actual section ('./' prefix)
- if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) {
- sname = sname.substr(2);
- }
- // 2) subsection of parent section ('../' prefix)
- else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) {
- do {
- if( section_stack.end() != section_stack.begin() )
- section_stack.pop_back();
- sname = sname.substr(3);
- } while( sname.substr(0, 3) == "../" );
- }
- // 3) subsection of the root-section
- else {
- section_stack.erase(section_stack.begin(), section_stack.end());
- // [] => back to root section
- }
-
- if( sname != "" ) {
- // parse section name for 'slashes'
- unsigned i=0;
- while( i < sname.length() ) {
- if( sname[i] == '/' ) {
- section_stack.push_back(sname.substr(0,i));
- if( i+1 < sname.length()-1 )
- sname = sname.substr(i+1);
- i = 0;
- }
- else
- ++i;
- }
- section_stack.push_back(sname);
- }
- std::string section = "";
- if( section_stack.size() != 0 ) {
- victorate(std::string, section_stack, it)
- section += *it + "/";
- }
- return section;
-}
-
-
-// convert string to DOUBLE, if not possible return Default
-inline double
-GetPot::__convert_to_type(const std::string& String, double Default) const
-{
- double tmp;
- if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default;
- return tmp;
-}
-
-// convert string to INT, if not possible return Default
-inline int
-GetPot::__convert_to_type(const std::string& String, int Default) const
-{
- // NOTE: intermediate results may be floating points, so that the string
- // may look like 2.0e1 (i.e. float format) => use float conversion
- // in any case.
- return (int)__convert_to_type(String, (double)Default);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// (*) cursor oriented functions
-//.............................................................................
-inline const std::string
-GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const
- // Checks if 'String' begins with 'Start' and returns the remaining String.
- // Returns None if String does not begin with Start.
-{
- if( Start == "" ) return String;
- // note: java.lang.String: substring(a,b) = from a to b-1
- // C++ string: substr(a,b) = from a to a + b
- if( String.find(Start) == 0 ) return String.substr(Start.length());
- else return "";
-}
-
-// -- search for a certain argument and set cursor to position
-inline bool
-GetPot::search(const char* Option)
-{
- unsigned OldCursor = cursor;
- const std::string SearchTerm = prefix + Option;
-
- // (*) record requested arguments for later ufo detection
- __record_argument_request(SearchTerm);
-
- if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
- search_failed_f = true;
-
- // (*) first loop from cursor position until end
- unsigned c = cursor;
- for(; c < argv.size(); c++) {
- if( argv[c] == SearchTerm )
- { cursor = c; search_failed_f = false; return true; }
- }
- if( ! search_loop_f ) return false;
-
- // (*) second loop from 0 to old cursor position
- for(c = 1; c < OldCursor; c++) {
- if( argv[c] == SearchTerm )
- { cursor = c; search_failed_f = false; return true; }
- }
- // in case nothing is found the cursor stays where it was
- return false;
-}
-
-
-inline bool
-GetPot::search(unsigned No, const char* P, ...)
-{
- // (*) recording the requested arguments happens in subroutine 'search'
- if( No == 0 ) return false;
-
- // search for the first argument
- if( search(P) == true ) return true;
-
- // start interpreting variable argument list
- va_list ap;
- va_start(ap, P);
- unsigned i = 1;
- for(; i < No; ++i) {
- char* Opt = va_arg(ap, char *);
- if( search(Opt) == true ) break;
- }
-
- if( i < No ) {
- ++i;
- // loop was left before end of array --> hit but
- // make sure that the rest of the search terms is marked
- // as requested.
- for(; i < No; ++i) {
- char* Opt = va_arg(ap, char *);
- // (*) record requested arguments for later ufo detection
- __record_argument_request(Opt);
- }
- va_end(ap);
- return true;
- }
-
- va_end(ap);
- // loop was left normally --> no hit
- return false;
-}
-
-inline void
-GetPot::reset_cursor()
-{ search_failed_f = false; cursor = 0; }
-
-inline void
-GetPot::init_multiple_occurrence()
-{ disable_loop(); reset_cursor(); }
-///////////////////////////////////////////////////////////////////////////////
-// (*) direct access to command line arguments
-//.............................................................................
-//
-inline const std::string
-GetPot::operator[](unsigned idx) const
-{ return idx < argv.size() ? argv[idx] : ""; }
-
-inline int
-GetPot::get(unsigned Idx, int Default) const
-{
- if( Idx >= argv.size() ) return Default;
- return __convert_to_type(argv[Idx], Default);
-}
-
-inline double
-GetPot::get(unsigned Idx, const double& Default) const
-{
- if( Idx >= argv.size() ) return Default;
- return __convert_to_type(argv[Idx], Default);
-}
-
-inline const std::string
-GetPot::get(unsigned Idx, const char* Default) const
-{
- if( Idx >= argv.size() ) return Default;
- else return argv[Idx];
-}
-
-inline unsigned
-GetPot::size() const
-{ return static_cast<unsigned int>(argv.size()); }
-
-
-// -- next() function group
-inline int
-GetPot::next(int Default)
-{
- if( search_failed_f ) return Default;
- cursor++;
- if( cursor >= argv.size() )
- { cursor = static_cast<unsigned int>(argv.size()); return Default; }
-
- // (*) record requested argument for later ufo detection
- __record_argument_request(argv[cursor]);
-
- const std::string Remain = __get_remaining_string(argv[cursor], prefix);
-
- return Remain != "" ? __convert_to_type(Remain, Default) : Default;
-}
-
-inline double
-GetPot::next(const double& Default)
-{
- if( search_failed_f ) return Default;
- cursor++;
-
- if( cursor >= argv.size() )
- { cursor = static_cast<unsigned int>(argv.size()); return Default; }
-
- // (*) record requested argument for later ufo detection
- __record_argument_request(argv[cursor]);
-
- std::string Remain = __get_remaining_string(argv[cursor], prefix);
-
- return Remain != "" ? __convert_to_type(Remain, Default) : Default;
-}
-
-inline const std::string
-GetPot::next(const char* Default)
-{
- if( search_failed_f ) return Default;
- cursor++;
-
- if( cursor >= argv.size() )
- { cursor = static_cast<unsigned int>(argv.size()); return Default; }
-
- // (*) record requested argument for later ufo detection
- __record_argument_request(argv[cursor]);
-
- const std::string Remain = __get_remaining_string(argv[cursor], prefix);
-
- if( Remain == "" ) return Default;
-
-
- // (*) function returns a pointer to a char array (inside Remain)
- // this array will be deleted, though after this function call.
- // To ensure propper functioning, create a copy inside *this
- // object and only delete it, when *this is deleted.
- char* result = new char[Remain.length()+1];
- strncpy(result, Remain.c_str(), Remain.length()+1);
-
- // store the created string internally, delete if when object deleted
- __internal_string_container.push_back(result);
-
- return result;
-}
-
-// -- follow() function group
-// distinct option to be searched for
-inline int
-GetPot::follow(int Default, const char* Option)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( search(Option) == false ) return Default;
- return next(Default);
-}
-
-inline double
-GetPot::follow(const double& Default, const char* Option)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( search(Option) == false ) return Default;
- return next(Default);
-}
-
-inline const std::string
-GetPot::follow(const char* Default, const char* Option)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( search(Option) == false ) return Default;
- return next(Default);
-}
-
-// -- second follow() function group
-// multiple option to be searched for
-inline int
-GetPot::follow(int Default, unsigned No, const char* P, ...)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( No == 0 ) return Default;
- if( search(P) == true ) return next(Default);
-
- va_list ap;
- va_start(ap, P);
- unsigned i=1;
- for(; i<No; ++i) {
- char* Opt = va_arg(ap, char *);
- if( search(Opt) == true ) {
- va_end(ap);
- return next(Default);
- }
- }
- va_end(ap);
- return Default;
-}
-
-inline double
-GetPot::follow(const double& Default, unsigned No, const char* P, ...)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( No == 0 ) return Default;
- if( search(P) == true ) return next(Default);
-
- va_list ap;
- va_start(ap, P);
- for(unsigned i=1; i<No; ++i) {
- char* Opt = va_arg(ap, char *);
- if( search(Opt) == true ) {
- va_end(ap);
- return next(Default);
- }
- }
- va_end(ap);
- return Default;
-}
-
-inline const std::string
-GetPot::follow(const char* Default, unsigned No, const char* P, ...)
-{
- // (*) record requested of argument is entirely handled in 'search()' and 'next()'
- if( No == 0 ) return Default;
- if( search(P) == true ) return next(Default);
-
- va_list ap;
- va_start(ap, P);
- unsigned i=1;
- for(; i<No; ++i) {
- char* Opt = va_arg(ap, char *);
- if( search(Opt) == true ) {
- va_end(ap);
- return next(Default);
- }
- }
- va_end(ap);
- return Default;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) lists of nominus following an option
-//.............................................................................
-//
-inline std::vector<std::string>
-GetPot::nominus_followers(const char* Option)
-{
- std::vector<std::string> result_list;
- if( search(Option) == false ) return result_list;
- while( 1 + 1 == 2 ) {
- ++cursor;
- if( cursor >= argv.size() ) {
- cursor = argv.size() - 1;
- return result_list;
- }
- if( argv[cursor].length() >= 1 ) {
- if( argv[cursor][0] == '-' ) {
- return result_list;
- }
- // -- record for later ufo-detection
- __record_argument_request(argv[cursor]);
- // -- append to the result list
- result_list.push_back(argv[cursor]);
- }
- }
-}
-
-inline std::vector<std::string>
-GetPot::nominus_followers(unsigned No, ...)
-{
- std::vector<std::string> result_list;
- // (*) record requested of argument is entirely handled in 'search()'
- // and 'nominus_followers()'
- if( No == 0 ) return result_list;
-
- va_list ap;
- va_start(ap, No);
- for(unsigned i=0; i<No; ++i) {
- char* Option = va_arg(ap, char *);
- std::vector<std::string> tmp = nominus_followers(Option);
- result_list.insert(result_list.end(), tmp.begin(), tmp.end());
-
- // std::cerr << "option = '" << Option << "'" << std::endl;
- // std::cerr << "length = " << tmp.size() << std::endl;
- // std::cerr << "new result list = <";
- // for(std::vector<std::string>::const_iterator it = result_list.begin();
- // it != result_list.end(); ++it)
- // std::cerr << *it << ", ";
- // std::cerr << ">\n";
- }
- va_end(ap);
- return result_list;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) directly connected options
-//.............................................................................
-//
-inline int
-GetPot::direct_follow(int Default, const char* Option)
-{
- const char* FollowStr = __match_starting_string(Option);
- if( FollowStr == 0x0 ) return Default;
-
- // (*) record requested of argument for later ufo-detection
- __record_argument_request(std::string(Option) + FollowStr);
-
- if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
- return __convert_to_type(FollowStr, Default);
-}
-
-inline double
-GetPot::direct_follow(const double& Default, const char* Option)
-{
- const char* FollowStr = __match_starting_string(Option);
- if( FollowStr == 0 ) return Default;
-
- // (*) record requested of argument for later ufo-detection
- __record_argument_request(std::string(Option) + FollowStr);
-
- if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
- return __convert_to_type(FollowStr, Default);
-}
-
-inline const std::string
-GetPot::direct_follow(const char* Default, const char* Option)
-{
- if( search_failed_f ) return Default;
- const char* FollowStr = __match_starting_string(Option);
- if( FollowStr == 0 ) return Default;
-
- // (*) record requested of argument for later ufo-detection
- if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr);
-
- if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
- return std::string(FollowStr);
-}
-
-inline std::vector<std::string>
-GetPot::string_tails(const char* StartString)
-{
- std::vector<std::string> result;
- const unsigned N = static_cast<unsigned int>(strlen(StartString));
-
- std::vector<std::string>::iterator it = argv.begin();
-
- unsigned idx = 0;
- while( it != argv.end() ) {
- // (*) does start string match the given option?
- // NO -> goto next option
- if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
-
- // append the found tail to the result vector
- result.push_back((*it).substr(N));
-
- // adapt the nominus vector
- std::vector<unsigned>::iterator nit = idx_nominus.begin();
- for(; nit != idx_nominus.end(); ++nit) {
- if( *nit == idx ) {
- idx_nominus.erase(nit);
- for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
- break;
- }
- }
-
- // erase the found option
- argv.erase(it);
-
- // 100% safe solution: set iterator back to the beginning.
- // (normally, 'it--' would be enough, but who knows how the
- // iterator is implemented and .erase() definitely invalidates
- // the current iterator position.
- if( argv.empty() ) break;
- it = argv.begin();
- }
- cursor = 0;
- nominus_cursor = -1;
- return result;
-}
-
-inline std::vector<int>
-GetPot::int_tails(const char* StartString, const int Default /* = -1 */)
-{
- std::vector<int> result;
- const unsigned N = static_cast<unsigned int>(strlen(StartString));
-
- std::vector<std::string>::iterator it = argv.begin();
-
- unsigned idx = 0;
- while( it != argv.end() ) {
- // (*) does start string match the given option?
- // NO -> goto next option
- if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
-
- // append the found tail to the result vector
- result.push_back(__convert_to_type((*it).substr(N), Default));
-
- // adapt the nominus vector
- std::vector<unsigned>::iterator nit = idx_nominus.begin();
- for(; nit != idx_nominus.end(); ++nit) {
- if( *nit == idx ) {
- idx_nominus.erase(nit);
- for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
- break;
- }
- }
-
- // erase the found option
- argv.erase(it);
-
- // 100% safe solution: set iterator back to the beginning.
- // (normally, 'it--' would be enough, but who knows how the
- // iterator is implemented and .erase() definitely invalidates
- // the current iterator position.
- if( argv.empty() ) break;
- it = argv.begin();
- }
- cursor = 0;
- nominus_cursor = -1;
- return result;
-}
-
-inline std::vector<double>
-GetPot::double_tails(const char* StartString,
- const double Default /* = -1.0 */)
-{
- std::vector<double> result;
- const unsigned N = static_cast<unsigned int>(strlen(StartString));
-
- std::vector<std::string>::iterator it = argv.begin();
- unsigned idx = 0;
- while( it != argv.end() ) {
- // (*) does start string match the given option?
- // NO -> goto next option
- if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
-
- // append the found tail to the result vector
- result.push_back(__convert_to_type((*it).substr(N), Default));
-
- // adapt the nominus vector
- std::vector<unsigned>::iterator nit = idx_nominus.begin();
- for(; nit != idx_nominus.end(); ++nit) {
- if( *nit == idx ) {
- idx_nominus.erase(nit);
- for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
- break;
- }
- }
-
- // erase the found option
- argv.erase(it);
-
- // 100% safe solution: set iterator back to the beginning.
- // (normally, 'it--' would be enough, but who knows how the
- // iterator is implemented and .erase() definitely invalidates
- // the current iterator position.
- if( argv.empty() ) break;
- it = argv.begin();
- }
- cursor = 0;
- nominus_cursor = -1;
- return result;
-}
-
-
-
-
-
-inline const char*
-GetPot::__match_starting_string(const char* StartString)
- // pointer to the place where the string after
- // the match inside the found argument starts.
- // 0 no argument matches the starting string.
-{
- const unsigned N = static_cast<unsigned int>(strlen(StartString));
- unsigned OldCursor = cursor;
-
- if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
- search_failed_f = true;
-
- // (*) first loop from cursor position until end
- unsigned c = cursor;
- for(; c < argv.size(); c++) {
- if( strncmp(StartString, argv[c].c_str(), N) == 0)
- { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
- }
-
- if( ! search_loop_f ) return false;
-
- // (*) second loop from 0 to old cursor position
- for(c = 1; c < OldCursor; c++) {
- if( strncmp(StartString, argv[c].c_str(), N) == 0)
- { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
- }
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) search for flags
-//.............................................................................
-//
-inline bool
-GetPot::options_contain(const char* FlagList) const
-{
- // go through all arguments that start with a '-' (but not '--')
- std::string str;
- STRING_VECTOR::const_iterator it = argv.begin();
- for(; it != argv.end(); ++it) {
- str = __get_remaining_string(*it, prefix);
-
- if( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
- if( __check_flags(str, FlagList) ) return true;
- }
- return false;
-}
-
-inline bool
-GetPot::argument_contains(unsigned Idx, const char* FlagList) const
-{
- if( Idx >= argv.size() ) return false;
-
- // (*) record requested of argument for later ufo-detection
- // an argument that is checked for flags is considered to be 'requested'
- ((GetPot*)this)->__record_argument_request(argv[Idx]);
-
- if( prefix == "" )
- // search argument for any flag in flag list
- return __check_flags(argv[Idx], FlagList);
-
- // if a prefix is set, then the argument index is the index
- // inside the 'namespace'
- // => only check list of arguments that start with prefix
- unsigned no_matches = 0;
- unsigned i=0;
- for(; i<argv.size(); ++i) {
- const std::string Remain = __get_remaining_string(argv[i], prefix);
- if( Remain != "") {
- no_matches += 1;
- if( no_matches == Idx)
- return __check_flags(Remain, FlagList);
- }
- }
- // no argument in this namespace
- return false;
-}
-
-inline bool
-GetPot::__check_flags(const std::string& Str, const char* FlagList) const
-{
- const char* p=FlagList;
- for(; *p != '\0' ; p++)
- if( Str.find(*p) != std::string::npos ) return true; // found something
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) nominus arguments
-inline STRING_VECTOR
-GetPot::nominus_vector() const
- // return vector of nominus arguments
-{
- STRING_VECTOR nv;
- std::vector<unsigned>::const_iterator it = idx_nominus.begin();
- for(; it != idx_nominus.end(); ++it) {
- nv.push_back(argv[*it]);
-
- // (*) record for later ufo-detection
- // when a nominus vector is requested, the entire set of nominus arguments are
- // tagged as 'requested'
- ((GetPot*)this)->__record_argument_request(argv[*it]);
- }
- return nv;
-}
-
-inline std::string
-GetPot::next_nominus()
-{
- if( nominus_cursor < int(idx_nominus.size()) - 1 ) {
- const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
-
- // (*) record for later ufo-detection
- __record_argument_request(Tmp);
-
- // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer
- // to something that does no longer exist.
- return Tmp;
- }
- return std::string("");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) variables
-//.............................................................................
-//
-inline int
-GetPot::operator()(const char* VarName, int Default) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- return __convert_to_type(sv->original, Default);
-}
-
-inline double
-GetPot::operator()(const char* VarName, const double& Default) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- return __convert_to_type(sv->original, Default);
-}
-
-inline const std::string
-GetPot::operator()(const char* VarName, const char* Default) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- // -- returning a c_str() pointer is OK here, since the variable remains existant,
- // while 'sv' of course is delete at the end of the function.
- return sv->original;
-}
-
-inline int
-GetPot::operator()(const char* VarName, int Default, unsigned Idx) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- const std::string* element = sv->get_element(Idx);
- if( element == 0 ) return Default;
- return __convert_to_type(*element, Default);
-}
-
-inline double
-GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- const std::string* element = sv->get_element(Idx);
- if( element == 0 ) return Default;
- return __convert_to_type(*element, Default);
-}
-
-inline const std::string
-GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const
-{
- // (*) recording of requested variables happens in '__find_variable()'
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return Default;
- const std::string* element = sv->get_element(Idx);
- if( element == 0 ) return Default;
- return *element;
-}
-
-inline void
-GetPot::__record_argument_request(const std::string& Name)
-{
- if( ! __request_recording_f ) return;
-
- // (*) record requested variable for later ufo detection
- _requested_arguments.push_back(Name);
-
- // (*) record considered section for ufo detection
- STRING_VECTOR STree = __get_section_tree(Name);
- victorate(std::string, STree, it)
- if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
- if( section.length() != 0 ) _requested_sections.push_back(*it);
-}
-
-inline void
-GetPot::__record_variable_request(const std::string& Name)
-{
- if( ! __request_recording_f ) return;
-
- // (*) record requested variable for later ufo detection
- _requested_variables.push_back(Name);
-
- // (*) record considered section for ufo detection
- STRING_VECTOR STree = __get_section_tree(Name);
- victorate(std::string, STree, it)
- if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
- if( section.length() != 0 ) _requested_sections.push_back(*it);
-}
-
-// (*) following functions are to be used from 'outside', after getpot has parsed its
-// arguments => append an argument in the argument vector that reflects the addition
-inline void
-GetPot::__set_variable(const char* VarName, const char* Value)
-{
- const GetPot::variable* Var = __find_variable(VarName);
- if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str()));
- else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str());
-}
-
-inline void
-GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */)
-{
- const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value);
- argv.push_back(Arg);
- __set_variable(VarName, Value);
-
- // if user does not specify the variable as 'not being requested' it will be
- // considered amongst the requested variables
- if( Requested ) __record_variable_request(Arg);
-}
-
-inline void
-GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */)
-{ __set_variable(VarName, __double2string(Value).c_str()); }
-
-inline void
-GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */)
-{ __set_variable(VarName, __int2string(Value).c_str()); }
-
-
-inline unsigned
-GetPot::vector_variable_size(const char* VarName) const
-{
- const variable* sv = __find_variable(VarName);
- if( sv == 0 ) return 0;
- return static_cast<unsigned int>(sv->value.size());
-}
-
-inline STRING_VECTOR
-GetPot::get_variable_names() const
-{
- STRING_VECTOR result;
- std::vector<GetPot::variable>::const_iterator it = variables.begin();
- for(; it != variables.end(); ++it) {
- const std::string Tmp = __get_remaining_string((*it).name, prefix);
- if( Tmp != "" ) result.push_back(Tmp);
- }
- return result;
-}
-
-inline STRING_VECTOR
-GetPot::get_section_names() const
-{ return section_list; }
-
-inline const GetPot::variable*
-GetPot::__find_variable(const char* VarName) const
-{
- const std::string Name = prefix + VarName;
-
- // (*) record requested variable for later ufo detection
- ((GetPot*)this)->__record_variable_request(Name);
-
- std::vector<variable>::const_iterator it = variables.begin();
- for(; it != variables.end(); ++it) {
- if( (*it).name == Name ) return &(*it);
- }
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) ouput (basically for debugging reasons
-//.............................................................................
-//
-inline int
-GetPot::print() const
-{
- std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl;
- STRING_VECTOR::const_iterator it = argv.begin();
- for(; it != argv.end(); ++it)
- std::cout << *it << std::endl;
- std::cout << std::endl;
- return 1;
-}
-
-// (*) dollar bracket expressions (DBEs) ------------------------------------
-//
-// 1) Entry Function: __DBE_expand_string()
-// Takes a string such as
-//
-// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
-//
-// calls __DBE_expand() for each of the expressions
-//
-// ${+ ${x} ${y}}
-// ${& ${section} ${subsection}}
-// ${Title}
-//
-// and returns the string
-//
-// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
-//
-// assuming that
-// x = "4699"
-// y = "12"
-// section = "1."
-// subsection = "01"
-// title = "Mit den Clowns kamen die Schwaene"
-//
-// 2) __DBE_expand():
-//
-// checks for the command, i.e. the 'sign' that follows '${'
-// divides the argument list into sub-expressions using
-// __DBE_get_expr_list()
-//
-// ${+ ${x} ${y}} -> "${x}" "${y}"
-// ${& ${section} ${subsection}} -> "${section}" "${subsection}"
-// ${Title} -> Nothing, variable expansion
-//
-// 3) __DBE_expression_list():
-//
-// builds a vector of unbracketed whitespace separated strings, i.e.
-//
-// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
-//
-// is split into a vector
-//
-// [0] ${Number}.a
-// [1] ${: Das Marmorbild}
-// [2] AB-${& Author= ${Eichendorf}}-1870
-//
-// Each sub-expression is expanded using expand().
-//---------------------------------------------------------------------------
-inline std::string
-GetPot::__DBE_expand_string(const std::string str)
-{
- // Parses for closing operators '${ }' and expands them letting
- // white spaces and other letters as they are.
- std::string new_string = "";
- unsigned open_brackets = 0;
- unsigned first = 0;
- unsigned i = 0;
- for(; i<str.size(); ++i) {
- if( i < str.size() - 2 && str.substr(i, 2) == "${" ) {
- if( open_brackets == 0 ) first = i+2;
- open_brackets++;
- }
- else if( str[i] == '}' && open_brackets > 0) {
- open_brackets -= 1;
- if( open_brackets == 0 ) {
- const std::string Replacement = __DBE_expand(str.substr(first, i - first));
- new_string += Replacement;
- }
- }
- else if( open_brackets == 0 )
- new_string += str[i];
- }
- return new_string;
-}
-
-inline STRING_VECTOR
-GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber)
- // ensures that the resulting vector has the expected number
- // of arguments, but they may contain an error message
-{
- std::string str = str_;
- // Separates expressions by non-bracketed whitespaces, expands them
- // and puts them into a list.
-
- unsigned i=0;
- // (1) eat initial whitespaces
- for(; i < str.size(); ++i)
- if( ! isspace(str[i]) ) break;
-
- STRING_VECTOR expr_list;
- unsigned open_brackets = 0;
- std::vector<unsigned> start_idx;
- unsigned start_new_string = i;
- unsigned l = static_cast<unsigned int>(str.size());
-
- // (2) search for ${ } expressions ...
- while( i < l ) {
- const char letter = str[i];
- // whitespace -> end of expression
- if( isspace(letter) && open_brackets == 0) {
- expr_list.push_back(str.substr(start_new_string, i - start_new_string));
- bool no_breakout_f = true;
- for(++i; i < l ; ++i) {
- if( ! isspace(str[i]) )
- { no_breakout_f = false; start_new_string = i; break; }
- }
- if( no_breakout_f ) {
- // end of expression list
- if( expr_list.size() < ExpectedNumber ) {
- const std::string pre_tmp("<< ${ }: missing arguments>>");
- STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
- expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
- }
- return expr_list;
- }
- }
-
- // dollar-bracket expression
- if( str.length() >= i+2 && str.substr(i, 2) == "${" ) {
- open_brackets++;
- start_idx.push_back(i+2);
- }
- else if( letter == '}' && open_brackets > 0) {
- int start = start_idx[start_idx.size()-1];
- start_idx.pop_back();
- const std::string Replacement = __DBE_expand(str.substr(start, i-start));
- if( start - 3 < (int)0)
- str = Replacement + str.substr(i+1);
- else
- str = str.substr(0, start-2) + Replacement + str.substr(i+1);
- l = static_cast<unsigned int>(str.size());
- i = start + static_cast<unsigned int>(Replacement.size()) - 3;
- open_brackets--;
- }
- ++i;
- }
-
- // end of expression list
- expr_list.push_back(str.substr(start_new_string, i-start_new_string));
-
- if( expr_list.size() < ExpectedNumber ) {
- const std::string pre_tmp("<< ${ }: missing arguments>>");
- STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
- expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
- }
-
- return expr_list;
-}
-
-inline const GetPot::variable*
-GetPot::__DBE_get_variable(std::string VarName)
-{
- static GetPot::variable ev;
- std::string secure_Prefix = prefix;
-
- prefix = section;
- // (1) first search in currently active section
- const GetPot::variable* var = __find_variable(VarName.c_str());
- if( var != 0 ) { prefix = secure_Prefix; return var; }
-
- // (2) search in root name space
- prefix = "";
- var = __find_variable(VarName.c_str());
- if( var != 0 ) { prefix = secure_Prefix; return var; }
-
- prefix = secure_Prefix;
-
- // error occured => variable name == ""
- char* tmp = new char[VarName.length() + 25];
-#ifndef WIN32
- snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25),
-#else
- _snprintf(tmp, sizeof(char)*(VarName.length() + 25),
-#endif
- "<<${ } variable '%s' undefined>>", VarName.c_str());
- ev.name = "";
- ev.original = std::string(tmp);
- delete [] tmp;
- return &ev;
-}
-
-inline std::string
-GetPot::__DBE_expand(const std::string expr)
-{
- // ${: } pure text
- if( expr[0] == ':' )
- return expr.substr(1);
-
- // ${& expr expr ... } text concatination
- else if( expr[0] == '&' ) {
- const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1);
-
- STRING_VECTOR::const_iterator it = A.begin();
- std::string result = *it++;
- for(; it != A.end(); ++it) result += *it;
-
- return result;
- }
-
- // ${<-> expr expr expr} text replacement
- else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3);
- std::string::size_type tmp = 0;
- const std::string::size_type L = A[1].length();
- while( (tmp = A[0].find(A[1])) != std::string::npos ) {
- A[0].replace(tmp, L, A[2]);
- }
- return A[0];
- }
- // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
- else if( expr[0] == '+' ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- STRING_VECTOR::const_iterator it = A.begin();
- double result = __convert_to_type(*it++, 0.0);
- for(; it != A.end(); ++it)
- result += __convert_to_type(*it, 0.0);
-
- return __double2string(result);
- }
- else if( expr[0] == '-' ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- STRING_VECTOR::const_iterator it = A.begin();
- double result = __convert_to_type(*it++, 0.0);
- for(; it != A.end(); ++it)
- result -= __convert_to_type(*it, 0.0);
-
- return __double2string(result);
- }
- else if( expr[0] == '*' ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- STRING_VECTOR::const_iterator it = A.begin();
- double result = __convert_to_type(*it++, 0.0);
- for(; it != A.end(); ++it)
- result *= __convert_to_type(*it, 0.0);
-
- return __double2string(result);
- }
- else if( expr[0] == '/' ) {
-
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- STRING_VECTOR::const_iterator it = A.begin();
- double result = __convert_to_type(*it++, 0.0);
- if( result == 0 ) return "0.0";
- for(; it != A.end(); ++it) {
- const double Q = __convert_to_type(*it, 0.0);
- if( Q == 0.0 ) return "0.0";
- result /= Q;
- }
- return __double2string(result);
- }
-
- // ${^ ... } power expressions
- else if( expr[0] == '^' ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- STRING_VECTOR::const_iterator it = A.begin();
- double result = __convert_to_type(*it++, 0.0);
- for(; it != A.end(); ++it)
- result = pow(result, __convert_to_type(*it, 0.0));
- return __double2string(result);
- }
-
- // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
- else if( expr.length() >= 2 &&
- ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
- expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) {
- // differentiate between two and one sign operators
- unsigned op = 0;
- enum { EQ, GEQ, LEQ, GT, LT };
- if ( expr.substr(0, 2) == "==" ) op = EQ;
- else if ( expr.substr(0, 2) == ">=" ) op = GEQ;
- else if ( expr.substr(0, 2) == "<=" ) op = LEQ;
- else if ( expr[0] == '>' ) op = GT;
- else /* "<" */ op = LT;
-
- STRING_VECTOR a;
- if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2);
- else a = __DBE_get_expr_list(expr.substr(2), 2);
-
- std::string x_orig = a[0];
- double x = __convert_to_type(x_orig, 1e37);
- unsigned i = 1;
-
- STRING_VECTOR::const_iterator y_orig = a.begin();
- for(y_orig++; y_orig != a.end(); y_orig++) {
- double y = __convert_to_type(*y_orig, 1e37);
-
- // set the strings as reference if one wasn't a number
- if ( x == 1e37 || y == 1e37 ) {
- // it's a string comparison
- if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
- (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
- (op == LT && x_orig < *y_orig) )
- return __int2string(i);
- }
- else {
- // it's a number comparison
- if( (op == EQ && x == y) || (op == GEQ && x >= y) ||
- (op == LEQ && x <= y) || (op == GT && x > y) ||
- (op == LT && x < y) )
- return __int2string(i);
- }
- ++i;
- }
-
- // nothing fulfills the condition => return 0
- return "0";
- }
- // ${?? expr expr} select
- else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) {
- STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2);
- double x = __convert_to_type(a[0], 1e37);
- // last element is always the default argument
- if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1];
-
- // round x to closest integer
- return a[int(x+0.5)];
- }
- // ${? expr expr expr} if then else conditions
- else if( expr[0] == '?' ) {
- STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2);
- if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1];
- else if( a.size() > 2 ) return a[2];
- }
- // ${! expr} maxro expansion
- else if( expr[0] == '!' ) {
- const GetPot::variable* Var = __DBE_get_variable(expr.substr(1));
- // error
- if( Var->name == "" ) return std::string(Var->original);
-
- const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2);
- return A[0];
- }
- // ${@: } - string subscription
- else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) {
- const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2);
- double x = __convert_to_type(A[1], 1e37);
-
- // last element is always the default argument
- if( x == 1e37 || x < 0 || x >= A[0].size() - 1)
- return "<<1st index out of range>>";
-
- if( A.size() > 2 ) {
- double y = __convert_to_type(A[2], 1e37);
- if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
- return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
- else if( y == -1 )
- return A[0].substr(int(x+0.5));
- return "<<2nd index out of range>>";
- }
- else {
- char* tmp = new char[2];
- tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
- std::string result(tmp);
- delete [] tmp;
- return result;
- }
- }
- // ${@ } - vector subscription
- else if( expr[0] == '@' ) {
- STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
- const GetPot::variable* Var = __DBE_get_variable(A[0]);
- // error
- if( Var->name == "" ) {
- // make a copy of the string if an error occured
- // (since the error variable is a static variable inside get_variable())
- return std::string(Var->original);
- }
-
- double x = __convert_to_type(A[1], 1e37);
-
- // last element is always the default argument
- if (x == 1e37 || x < 0 || x >= Var->value.size() )
- return "<<1st index out of range>>";
-
- if ( A.size() > 2) {
- double y = __convert_to_type(A[2], 1e37);
- int begin = int(x+0.5);
- int end = 0;
- if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
- end = int(y+1.5);
- else if( y == -1 )
- end = static_cast<unsigned int>(Var->value.size());
- else
- return "<<2nd index out of range>>";
-
- std::string result = *(Var->get_element(begin));
- int i = begin+1;
- for(; i < end; ++i)
- result += std::string(" ") + *(Var->get_element(i));
- return result;
- }
- else
- return *(Var->get_element(int(x+0.5)));
- }
-
- const STRING_VECTOR A = __DBE_get_expr_list(expr, 1);
- const GetPot::variable* B = __DBE_get_variable(A[0]);
-
- // make a copy of the string if an error occured
- // (since the error variable is a static variable inside get_variable())
- if( B->name == "" ) return std::string(B->original);
- // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces
- // with: else return B->original (thanks))
- return B->original;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) unidentified flying objects
-//.............................................................................
-//
-inline bool
-GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
-{
- victorate(std::string, VecStr, itk) {
- if( *itk == Str ) return true;
- }
- return false;
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_arguments(unsigned Number,
- const char* KnownArgument1, ...) const
-{
- STRING_VECTOR known_arguments;
-
- // (1) create a vector of known arguments
- if( Number == 0 ) return STRING_VECTOR();
-
- va_list ap;
- va_start(ap, KnownArgument1);
- known_arguments.push_back(std::string(KnownArgument1));
- unsigned i=1;
- for(; i<Number; ++i)
- known_arguments.push_back(std::string(va_arg(ap, char *)));
- va_end(ap);
-
- return unidentified_arguments(known_arguments);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_arguments() const
-{ return unidentified_arguments(_requested_arguments); }
-
-inline STRING_VECTOR
-GetPot::unidentified_arguments(const STRING_VECTOR& Knowns) const
-{
- STRING_VECTOR ufos;
- STRING_VECTOR::const_iterator it = argv.begin();
- ++it; // forget about argv[0] (application or filename)
- for(; it != argv.end(); ++it) {
- // -- argument belongs to prefixed section ?
- const std::string arg = __get_remaining_string(*it, prefix);
- if( arg == "" ) continue;
-
- // -- check if in list
- if( __search_string_vector(Knowns, arg) == false)
- ufos.push_back(*it);
- }
- return ufos;
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_options(unsigned Number,
- const char* KnownOption1, ...) const
-{
- STRING_VECTOR known_options;
-
- // (1) create a vector of known arguments
- if( Number == 0 ) return STRING_VECTOR();
-
- va_list ap;
- va_start(ap, KnownOption1);
- known_options.push_back(std::string(KnownOption1));
- unsigned i=1;
- for(; i<Number; ++i)
- known_options.push_back(std::string(va_arg(ap, char *)));
- va_end(ap);
-
- return unidentified_options(known_options);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_options() const
-{
- // -- every option is an argument.
- // -- the set of requested arguments contains the set of requested options.
- // -- IF the set of requested arguments contains unrequested options,
- // THEN they were requested as 'follow' and 'next' arguments and not as real options.
- //
- // => it is not necessary to separate requested options from the list
- STRING_VECTOR option_list;
- victorate(std::string, _requested_arguments, it) {
- const std::string arg = *it;
- if( arg.length() == 0 ) continue;
- if( arg[0] == '-' ) option_list.push_back(arg);
- }
- return unidentified_options(option_list);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_options(const STRING_VECTOR& Knowns) const
-{
- STRING_VECTOR ufos;
- STRING_VECTOR::const_iterator it = argv.begin();
- ++it; // forget about argv[0] (application or filename)
- for(; it != argv.end(); ++it) {
- // -- argument belongs to prefixed section ?
- const std::string arg = __get_remaining_string(*it, prefix);
- if( arg == "" ) continue;
-
- // is argument really an option (starting with '-') ?
- if( arg.length() < 1 || arg[0] != '-' ) continue;
-
- if( __search_string_vector(Knowns, arg) == false)
- ufos.push_back(*it);
- }
-
- return ufos;
-}
-
-inline std::string
-GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
- // Two modes:
- // ArgumentNumber >= 0 check specific argument
- // ArgumentNumber == -1 check all options starting with one '-'
- // for flags
-{
- std::string ufos;
- STRING_VECTOR known_arguments;
- std::string KFL(KnownFlagList);
-
- // (2) iteration over '-' arguments (options)
- if( ArgumentNumber == -1 ) {
- STRING_VECTOR::const_iterator it = argv.begin();
- ++it; // forget about argv[0] (application or filename)
- for(; it != argv.end(); ++it) {
- // -- argument belongs to prefixed section ?
- const std::string arg = __get_remaining_string(*it, prefix);
- if( arg == "" ) continue;
-
- // -- does arguments start with '-' (but not '--')
- if ( arg.length() < 2 ) continue;
- else if( arg[0] != '-' ) continue;
- else if( arg[1] == '-' ) continue;
-
- // -- check out if flags inside option are contained in KnownFlagList
- const char* p=arg.c_str();
- p++; // skip starting minus
- for(; *p != '\0' ; p++)
- if( KFL.find(*p) == std::string::npos ) ufos += *p;
- }
- }
- // (1) check specific argument
- else {
- // -- only check arguments that start with prefix
- int no_matches = 0;
- unsigned i=1;
- for(; i<argv.size(); ++i) {
- const std::string Remain = __get_remaining_string(argv[i], prefix);
- if( Remain != "") {
- no_matches++;
- if( no_matches == ArgumentNumber) {
- // -- the right argument number inside the section is found
- // => check it for flags
- const char* p = Remain.c_str();
- p++; // skip starting minus
- for(; *p != '\0' ; p++)
- if( KFL.find(*p) == std::string::npos ) ufos += *p;
- return ufos;
- }
- }
- }
- }
- return ufos;
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_variables(unsigned Number,
- const char* KnownVariable1, ...) const
-{
- STRING_VECTOR known_variables;
-
- // create vector of known arguments
- if( Number == 0 ) return STRING_VECTOR();
-
- va_list ap;
- va_start(ap, KnownVariable1);
- known_variables.push_back(std::string(KnownVariable1));
- unsigned i=1;
- for(; i<Number; ++i)
- known_variables.push_back(std::string(va_arg(ap, char *)));
- va_end(ap);
-
- return unidentified_variables(known_variables);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_variables(const STRING_VECTOR& Knowns) const
-{
- STRING_VECTOR ufos;
-
- victorate(GetPot::variable, variables, it) {
- // -- check if variable has specific prefix
- const std::string var_name = __get_remaining_string((*it).name, prefix);
- if( var_name == "" ) continue;
-
- // -- check if variable is known
- if( __search_string_vector(Knowns, var_name) == false)
- ufos.push_back((*it).name);
- }
- return ufos;
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_variables() const
-{ return unidentified_variables(_requested_variables); }
-
-
-inline STRING_VECTOR
-GetPot::unidentified_sections(unsigned Number,
- const char* KnownSection1, ...) const
-{
- STRING_VECTOR known_sections;
-
- // (1) create a vector of known arguments
- if( Number == 0 ) return STRING_VECTOR();
-
- va_list ap;
- va_start(ap, KnownSection1);
- known_sections.push_back(std::string(KnownSection1));
- unsigned i=1;
- for(; i<Number; ++i) {
- std::string tmp = std::string(va_arg(ap, char *));
- if( tmp.length() == 0 ) continue;
- if( tmp[tmp.length()-1] != '/' ) tmp += '/';
- known_sections.push_back(tmp);
- }
- va_end(ap);
-
- return unidentified_sections(known_sections);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_sections() const
-{ return unidentified_sections(_requested_sections); }
-
-inline STRING_VECTOR
-GetPot::unidentified_sections(const STRING_VECTOR& Knowns) const
-{
- STRING_VECTOR ufos;
-
- victorate(std::string, section_list, it) {
- // -- check if section conform to prefix
- const std::string sec_name = __get_remaining_string(*it, prefix);
- if( sec_name == "" ) continue;
-
- // -- check if section is known
- if( __search_string_vector(Knowns, sec_name) == false )
- ufos.push_back(*it);
- }
-
- return ufos;
-}
-
-
-inline STRING_VECTOR
-GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
-{
- STRING_VECTOR known_nominuses;
-
- // create vector of known arguments
- if( Number == 0 ) return STRING_VECTOR();
-
- va_list ap;
- va_start(ap, Known);
- known_nominuses.push_back(std::string(Known));
- unsigned i=1;
- for(; i<Number; ++i) {
- std::string tmp = std::string(va_arg(ap, char *));
- if( tmp.length() == 0 ) continue;
- known_nominuses.push_back(tmp);
- }
- va_end(ap);
-
- return unidentified_nominuses(known_nominuses);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_nominuses() const {
- // -- every nominus is an argument.
- // -- the set of requested arguments contains the set of requested nominuss.
- // -- IF the set of requested arguments contains unrequested nominuss,
- // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
- //
- // => it is not necessary to separate requested nominus from the list
-
- return unidentified_nominuses(_requested_arguments);
-}
-
-inline STRING_VECTOR
-GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const
-{
- STRING_VECTOR ufos;
-
- // (2) iterate over all arguments
- STRING_VECTOR::const_iterator it = argv.begin();
- ++it; // forget about argv[0] (application or filename)
- for(; it != argv.end(); ++it) {
- // -- check if nominus part of prefix
- const std::string arg = __get_remaining_string(*it, prefix);
- if( arg == "" ) continue;
-
- if( arg.length() < 1 ) continue;
- // option ? --> not a nomius
- if( arg[0] == '-' ) continue;
- // section ? --> not a real nominus
- if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue;
- // variable definition ? --> not a real nominus
- bool continue_f = false;
- unsigned i=0;
- for(; i<arg.length() ; ++i)
- if( arg[i] == '=' ) { continue_f = true; break; }
- if( continue_f ) continue;
-
- // real nominuses are compared with the given list
- if( __search_string_vector(Knowns, arg) == false )
- ufos.push_back(*it);
- }
- return ufos;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// (*) variable class
-//.............................................................................
-//
-inline
-GetPot::variable::variable()
-{}
-
-inline
-GetPot::variable::variable(const variable& That)
-{
-#ifdef WIN32
- operator=(That);
-#else
- GetPot::variable::operator=(That);
-#endif
-}
-
-
-inline
-GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator)
- : name(Name)
-{
- // make a copy of the 'Value'
- take(Value, FieldSeparator);
-}
-
-inline const std::string*
-GetPot::variable::get_element(unsigned Idx) const
-{ if( Idx >= value.size() ) return 0; else return &(value[Idx]); }
-
-inline void
-GetPot::variable::take(const char* Value, const char* FieldSeparator)
-{
- original = std::string(Value);
-
- // separate string by white space delimiters using 'strtok'
- // thread safe usage of strtok (no static members)
- char* spt = 0;
- // make a copy of the 'Value'
- char* copy = new char[strlen(Value)+1];
- strcpy(copy, Value);
- char* follow_token = strtok_r(copy, FieldSeparator, &spt);
- if( value.size() != 0 ) value.erase(value.begin(), value.end());
- while(follow_token != 0) {
- value.push_back(std::string(follow_token));
- follow_token = strtok_r(NULL, FieldSeparator, &spt);
- }
-
- delete [] copy;
-}
-
-inline
-GetPot::variable::~variable()
-{}
-
-inline GetPot::variable&
-GetPot::variable::operator=(const GetPot::variable& That)
-{
- if( &That != this) {
- name = That.name;
- value = That.value;
- original = That.original;
- }
- return *this;
-}
-
-#undef victorate
-
-
-#endif // __include_guard_GETPOT_H__
-
-
-
+// -*- c++ -*- +// GetPot Version $$Version$$ $$Date$$ +// +// WEBSITE: http://getpot.sourceforge.net +// +// NOTE: The LPGL License for this library is only valid in case that +// it is not used for the production or development of applications +// dedicated to military industry. This is what the author calls +// the 'unofficial peace version of the LPGL'. +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// (C) 2001-2005 Frank R. Schaefer <fschaef@users.sf.net> +//========================================================================== + +#ifndef __include_guard_GETPOT_H__ +#define __include_guard_GETPOT_H__ + +#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC) +#define strtok_r(a, b, c) strtok(a, b) +#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC + +extern "C" { +// leave the 'extern C' to make it 100% sure to work - +// expecially with older distributions of header files. +#ifndef WIN32 +// this is necessary (depending on OS) +#include <ctype.h> +#endif +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +} +#include <cmath> +#include <string> +#include <vector> +#include <algorithm> + +#include <fstream> +#include <iostream> // not every compiler distribution includes <iostream> +// // with <fstream> + +typedef std::vector<std::string> STRING_VECTOR; + +#define victorate(TYPE, VARIABLE, ITERATOR) \ + std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \ + for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++) + + +class GetPot { + //-------- + inline void __basic_initialization(); +public: + // (*) constructors, destructor, assignment operator ----------------------- + inline GetPot(); + inline GetPot(const GetPot&); + inline GetPot(const int argc_, char** argv_, + const char* FieldSeparator=0x0); + inline GetPot(const char* FileName, + const char* CommentStart=0x0, const char* CommentEnd=0x0, + const char* FieldSeparator=0x0); + inline ~GetPot(); + inline GetPot& operator=(const GetPot&); + + + // (*) absorbing contents of another GetPot object + inline void absorb(const GetPot& That); + // -- for ufo detection: recording requested arguments, options etc. + inline void clear_requests(); + inline void disable_request_recording() { __request_recording_f = false; } + inline void enable_request_recording() { __request_recording_f = true; } + + // (*) direct access to command line arguments ----------------------------- + inline const std::string operator[](unsigned Idx) const; + inline int get(unsigned Idx, int Default) const; + inline double get(unsigned Idx, const double& Default) const; + inline const std::string get(unsigned Idx, const char* Default) const; + inline unsigned size() const; + + // (*) flags --------------------------------------------------------------- + inline bool options_contain(const char* FlagList) const; + inline bool argument_contains(unsigned Idx, const char* FlagList) const; + + // (*) variables ----------------------------------------------------------- + // -- scalar values + inline int operator()(const char* VarName, int Default) const; + inline double operator()(const char* VarName, const double& Default) const; + inline const std::string operator()(const char* VarName, const char* Default) const; + // -- vectors + inline int operator()(const char* VarName, int Default, unsigned Idx) const; + inline double operator()(const char* VarName, const double& Default, unsigned Idx) const; + inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const; + + // -- setting variables + // i) from outside of GetPot (considering prefix etc.) + // ii) from inside, use '__set_variable()' below + inline void set(const char* VarName, const char* Value, const bool Requested = true); + inline void set(const char* VarName, const double& Value, const bool Requested = true); + inline void set(const char* VarName, const int Value, const bool Requested = true); + + inline unsigned vector_variable_size(const char* VarName) const; + inline STRING_VECTOR get_variable_names() const; + inline STRING_VECTOR get_section_names() const; + + + // (*) cursor oriented functions ------------------------------------------- + inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); } + inline bool search_failed() const { return search_failed_f; } + + // -- enable/disable search for an option in loop + inline void disable_loop() { search_loop_f = false; } + inline void enable_loop() { search_loop_f = true; } + + // -- reset cursor to position '1' + inline void reset_cursor(); + inline void init_multiple_occurrence(); + + // -- search for a certain option and set cursor to position + inline bool search(const char* option); + inline bool search(unsigned No, const char* P, ...); + // -- get argument at cursor++ + inline int next(int Default); + inline double next(const double& Default); + inline const std::string next(const char* Default); + // -- search for option and get argument at cursor++ + inline int follow(int Default, const char* Option); + inline double follow(const double& Default, const char* Option); + inline const std::string follow(const char* Default, const char* Option); + // -- search for one of the given options and get argument that follows it + inline int follow(int Default, unsigned No, const char* Option, ...); + inline double follow(const double& Default, unsigned No, const char* Option, ...); + inline const std::string follow(const char* Default, unsigned No, const char* Option, ...); + // -- lists of nominuses following an option + inline std::vector<std::string> nominus_followers(const char* Option); + inline std::vector<std::string> nominus_followers(unsigned No, ...); + + // -- directly followed arguments + inline int direct_follow(int Default, const char* Option); + inline double direct_follow(const double& Default, const char* Option); + inline const std::string direct_follow(const char* Default, const char* Option); + + inline std::vector<std::string> string_tails(const char* StartString); + inline std::vector<int> int_tails(const char* StartString, const int Default = 1); + inline std::vector<double> double_tails(const char* StartString, const double Default = 1.0); + + // (*) nominus arguments --------------------------------------------------- + inline STRING_VECTOR nominus_vector() const; + inline unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); } + inline std::string next_nominus(); + + // (*) unidentified flying objects ----------------------------------------- + inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_arguments() const; + + inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_options() const; + + inline std::string unidentified_flags(const char* Known, + int ArgumentNumber /* =-1 */) const; + + inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_variables() const; + + inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_sections() const; + + inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_nominuses() const; + + // (*) output -------------------------------------------------------------- + inline int print() const; + +private: + // (*) Type Declaration ---------------------------------------------------- + struct variable { + //----------- + // Variable to be specified on the command line or in input files. + // (i.e. of the form var='12 312 341') + + // -- constructors, destructors, assignment operator + variable(); + variable(const variable&); + variable(const char* Name, const char* Value, const char* FieldSeparator); + ~variable(); + variable& operator=(const variable& That); + + void take(const char* Value, const char* FieldSeparator); + + // -- get a specific element in the string vector + // (return 0 if not present) + const std::string* get_element(unsigned Idx) const; + + // -- data memebers + std::string name; // identifier of variable + STRING_VECTOR value; // value of variable stored in vector + std::string original; // value of variable as given on command line + }; + + // (*) member variables -------------------------------------------------------------- + std::string prefix; // prefix automatically added in queries + std::string section; // (for dollar bracket parsing) + STRING_VECTOR section_list; // list of all parsed sections + // -- argument vector + STRING_VECTOR argv; // vector of command line arguments stored as strings + unsigned cursor; // cursor for argv + bool search_loop_f; // shall search start at beginning after + // // reaching end of arg array ? + bool search_failed_f; // flag indicating a failed search() operation + // // (e.g. next() functions react with 'missed') + + // -- nominus vector + int nominus_cursor; // cursor for nominus_pointers + std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments + + // -- variables + // (arguments of the form "variable=value") + std::vector<variable> variables; + + // -- comment delimiters + std::string _comment_start; + std::string _comment_end; + + // -- field separator (separating elements of a vector) + std::string _field_separator; + + // -- some functions return a char pointer to a temporarily existing string + // this container makes them 'available' until the getpot object is destroyed. + std::vector<char*> __internal_string_container; + + // -- keeping track about arguments that are requested, so that the UFO detection + // can be simplified + STRING_VECTOR _requested_arguments; + STRING_VECTOR _requested_variables; + STRING_VECTOR _requested_sections; + + bool __request_recording_f; // speed: request recording can be turned off + + // -- if an argument is requested record it and the 'tag' the section branch to which + // it belongs. Caution: both functions mark the sections as 'tagged'. + void __record_argument_request(const std::string& Arg); + void __record_variable_request(const std::string& Arg); + + // (*) helper functions ---------------------------------------------------- + // set variable from inside GetPot (no prefix considered) + inline void __set_variable(const char* VarName, const char* Value); + + // -- produce three basic data vectors: + // - argument vector + // - nominus vector + // - variable dictionary + inline void __parse_argument_vector(const STRING_VECTOR& ARGV); + + // -- helpers for argument list processing + // * search for a variable in 'variables' array + inline const variable* __find_variable(const char*) const; + // * support finding directly followed arguments + inline const char* __match_starting_string(const char* StartString); + // * support search for flags in a specific argument + inline bool __check_flags(const std::string& Str, const char* FlagList) const; + // * type conversion if possible + inline int __convert_to_type(const std::string& String, int Default) const; + inline double __convert_to_type(const std::string& String, double Default) const; + // * prefix extraction + const std::string __get_remaining_string(const std::string& String, + const std::string& Start) const; + // * search for a specific string + inline bool __search_string_vector(const STRING_VECTOR& Vec, + const std::string& Str) const; + + // -- helpers to parse input file + // create an argument vector based on data found in an input file, i.e.: + // 1) delete comments (in between '_comment_start' '_comment_end') + // 2) contract assignment expressions, such as + // my-variable = '007 J. B.' + // into + // my-variable='007 J. B.' + // 3) interprete sections like '[../my-section]' etc. + inline void __skip_whitespace(std::istream& istr); + inline const std::string __get_next_token(std::istream& istr); + inline const std::string __get_string(std::istream& istr); + inline const std::string __get_until_closing_bracket(std::istream& istr); + + inline STRING_VECTOR __read_in_stream(std::istream& istr); + inline STRING_VECTOR __read_in_file(const char* FileName); + inline std::string __process_section_label(const std::string& Section, + STRING_VECTOR& section_stack); + + // -- dollar bracket expressions + std::string __DBE_expand_string(const std::string str); + std::string __DBE_expand(const std::string str); + const GetPot::variable* __DBE_get_variable(const std::string str); + STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber); + + std::string __double2string(const double& Value) const { + // -- converts a double integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%e", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%e", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + std::string __int2string(const int& Value) const { + // -- converts an integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%i", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%i", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + STRING_VECTOR __get_section_tree(const std::string& FullPath) { + // -- cuts a variable name into a tree of sub-sections. this is requested for recording + // requested sections when dealing with 'ufo' detection. + STRING_VECTOR result; + const char* Start = FullPath.c_str(); + + for(char *p = (char*)Start; *p ; p++) { + if( *p == '/' ) { + *p = '\0'; // set terminating zero for convinience + const std::string Section = Start; + *p = '/'; // reset slash at place + result.push_back(Section); + } + } + + return result; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (*) constructors, destructor, assignment operator +//............................................................................. +// +inline void +GetPot::__basic_initialization() +{ + cursor = 0; nominus_cursor = -1; + search_failed_f = true; search_loop_f = true; + prefix = ""; section = ""; + + // automatic request recording for later ufo detection + __request_recording_f = true; + + // comment start and end strings + _comment_start = std::string("#"); + _comment_end = std::string("\n"); + + // default: separate vector elements by whitespaces + _field_separator = " \t\n"; +} + +inline +GetPot::GetPot() +{ + __basic_initialization(); + + STRING_VECTOR _apriori_argv; + _apriori_argv.push_back(std::string("Empty")); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const int argc_, char ** argv_, + const char* FieldSeparator /* =0x0 */) + // leave 'char**' non-const to honor less capable compilers ... +{ + // TODO: Ponder over the problem when the argument list is of size = 0. + // This is 'sabotage', but it can still occur if the user specifies + // it himself. + assert(argc_ >= 1); + __basic_initialization(); + + // if specified -> overwrite default string + if( FieldSeparator ) _field_separator = std::string(FieldSeparator); + + // -- make an internal copy of the argument list: + STRING_VECTOR _apriori_argv; + // -- for the sake of clarity: we do want to include the first argument in the argument vector ! + // it will not be a nominus argument, though. This gives us a minimun vector size of one + // which facilitates error checking in many functions. Also the user will be able to + // retrieve the name of his application by "get[0]" + _apriori_argv.push_back(std::string(argv_[0])); + int i=1; + for(; i<argc_; ++i) { + std::string tmp(argv_[i]); // recall the problem with temporaries, + _apriori_argv.push_back(tmp); // reference counting in arguement lists ... + } + __parse_argument_vector(_apriori_argv); +} + + +inline +GetPot::GetPot(const char* FileName, + const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */, + const char* FieldSeparator/* = 0x0 */) +{ + __basic_initialization(); + + // if specified -> overwrite default strings + if( CommentStart ) _comment_start = std::string(CommentStart); + if( CommentEnd ) _comment_end = std::string(CommentEnd); + if( FieldSeparator ) _field_separator = FieldSeparator; + + STRING_VECTOR _apriori_argv; + // -- file name is element of argument vector, however, it is not parsed for + // variable assignments or nominuses. + _apriori_argv.push_back(std::string(FileName)); + + STRING_VECTOR args = __read_in_file(FileName); + _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end()); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const GetPot& That) +{ GetPot::operator=(That); } + +inline +GetPot::~GetPot() +{ + // may be some return strings had to be created, delete now ! + victorate(char*, __internal_string_container, it) + delete [] *it; +} + +inline GetPot& +GetPot::operator=(const GetPot& That) +{ + if (&That == this) return *this; + + _comment_start = That._comment_start; + _comment_end = That._comment_end; + argv = That.argv; + variables = That.variables; + prefix = That.prefix; + + cursor = That.cursor; + nominus_cursor = That.nominus_cursor; + search_failed_f = That.search_failed_f; + + idx_nominus = That.idx_nominus; + search_loop_f = That.search_loop_f; + + return *this; +} + + +inline void +GetPot::absorb(const GetPot& That) +{ + if (&That == this) return; + + STRING_VECTOR __tmp(That.argv); + + __tmp.erase(__tmp.begin()); + + __parse_argument_vector(__tmp); +} + +inline void +GetPot::clear_requests() +{ + _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end()); + _requested_variables.erase(_requested_variables.begin(), _requested_variables.end()); + _requested_sections.erase(_requested_sections.begin(), _requested_sections.end()); +} + +inline void +GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV) +{ + if( ARGV.size() == 0 ) return; + + // build internal databases: + // 1) array with no-minus arguments (usually used as filenames) + // 2) variable assignments: + // 'variable name' '=' number | string + STRING_VECTOR section_stack; + STRING_VECTOR::const_iterator it = ARGV.begin(); + + + section = ""; + + // -- do not parse the first argument, so that it is not interpreted a s a nominus or so. + argv.push_back(*it); + ++it; + + // -- loop over remaining arguments + unsigned i=1; + for(; it != ARGV.end(); ++it, ++i) { + std::string arg = *it; + + if( arg.length() == 0 ) continue; + + // -- [section] labels + if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) { + + // (*) sections are considered 'requested arguments' + if( __request_recording_f ) _requested_arguments.push_back(arg); + + const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2)); + section = __process_section_label(Name, section_stack); + // new section --> append to list of sections + if( find(section_list.begin(), section_list.end(), section) == section_list.end() ) + if( section.length() != 0 ) section_list.push_back(section); + argv.push_back(arg); + } + else { + arg = section + __DBE_expand_string(arg); + argv.push_back(arg); + } + + // -- separate array for nominus arguments + if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i)); + + // -- variables: does arg contain a '=' operator ? + const char* p = arg.c_str(); + for(; *p ; p++) { + if( *p == '=' ) { + // (*) record for later ufo detection + // arguments carriying variables are always treated as 'requested' arguments. + // as a whole! That is 'x=4712' is considered a requested argument. + // + // unrequested variables have to be detected with the ufo-variable + // detection routine. + if( __request_recording_f ) _requested_arguments.push_back(arg); + + // set terminating 'zero' to treat first part as single string + // => arg (from start to 'p') = Name of variable + // p+1 (until terminating zero) = value of variable + char* o = (char*)p++; + *o = '\0'; // set temporary terminating zero + // __set_variable(...) + // calls __find_variable(...) which registers the search + // temporarily disable this + const bool tmp = __request_recording_f; + __request_recording_f = false; + __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest + __request_recording_f = tmp; + *o = '='; // reset the original '=' + break; + } + } + } +} + + +inline STRING_VECTOR +GetPot::__read_in_file(const char* FileName) +{ + std::ifstream i(FileName); + if( ! i ) return STRING_VECTOR(); + // argv[0] == the filename of the file that was read in + return __read_in_stream(i); +} + +inline STRING_VECTOR +GetPot::__read_in_stream(std::istream& istr) +{ + STRING_VECTOR brute_tokens; + while(istr) { + __skip_whitespace(istr); + + const std::string Token = __get_next_token(istr); + if( Token.length() == 0 || Token[0] == EOF) break; + brute_tokens.push_back(Token); + } + + // -- reduce expressions of token1'='token2 to a single + // string 'token1=token2' + // -- copy everything into 'argv' + // -- arguments preceded by something like '[' name ']' (section) + // produce a second copy of each argument with a prefix '[name]argument' + unsigned i1 = 0; + unsigned i2 = 1; + unsigned i3 = 2; + + STRING_VECTOR arglist; + while( i1 < brute_tokens.size() ) { + const std::string& SRef = brute_tokens[i1]; + // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef' + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) { + if( i3 >= brute_tokens.size() ) + arglist.push_back(brute_tokens[i1] + brute_tokens[i2]); + else + arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]); + i1 = i3+1; i2 = i3+2; i3 = i3+3; + continue; + } + else { + arglist.push_back(SRef); + i1=i2; i2=i3; i3++; + } + } + return arglist; +} + +inline void +GetPot::__skip_whitespace(std::istream& istr) + // find next non-whitespace while deleting comments +{ + int tmp = istr.get(); + do { + // -- search a non whitespace + while( isspace(tmp) ) { + tmp = istr.get(); + if( ! istr ) return; + } + + // -- look if characters match the comment starter string + const std::istream::pos_type Pos = istr.tellg(); + unsigned i=0; + for(; i<_comment_start.length() ; ++i) { + if( tmp != _comment_start[i] ) { +// HACK: The following line throws off msvc8: +// istr.seekg(Pos); + // -- one step more backwards, since 'tmp' already at non-whitespace + istr.unget(); + return; + } + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + } + // 'tmp' contains last character of _comment_starter + + // -- comment starter found -> search for comment ender + unsigned match_no=0; + while(1+1 == 2) { + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + + if( tmp == _comment_end[match_no] ) { + match_no++; + if( match_no == _comment_end.length() ) { + istr.unget(); + break; // shuffle more whitespace, end of comment found + } + } + else + match_no = 0; + } + + tmp = istr.get(); + + } while( istr ); + istr.unget(); +} + +inline const std::string +GetPot::__get_next_token(std::istream& istr) + // get next concatinates string token. consider quotes that embrace + // whitespaces +{ + std::string token; + int tmp = 0; + int last_letter = 0; + while(1+1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF + || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) { + return token; + } + else if( tmp == '\'' && last_letter != '\\' ) { + // QUOTES: un-backslashed quotes => it's a string + token += __get_string(istr); + continue; + } + else if( tmp == '{' && last_letter == '$') { + token += '{' + __get_until_closing_bracket(istr); + continue; + } + else if( tmp == '$' && last_letter == '\\') { + token += tmp; tmp = 0; // so that last_letter will become = 0, not '$'; + continue; + } + else if( tmp == '\\' && last_letter != '\\') + continue; // don't append un-backslashed backslashes + token += tmp; + } +} + +inline const std::string +GetPot::__get_string(std::istream& istr) + // parse input until next matching ' +{ + std::string str; + int tmp = 0; + int last_letter = 0; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + // un-backslashed quotes => it's the end of the string + else if( tmp == '\'' && last_letter != '\\') return str; + else if( tmp == '\\' && last_letter != '\\') continue; // don't append + + str += tmp; + } +} + +inline const std::string +GetPot::__get_until_closing_bracket(std::istream& istr) + // parse input until next matching } +{ + std::string str = ""; + int tmp = 0; + int last_letter = 0; + int brackets = 1; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + else if( tmp == '{' && last_letter == '$') brackets += 1; + else if( tmp == '}') { + brackets -= 1; + // un-backslashed brackets => it's the end of the string + if( brackets == 0) return str + '}'; + else if( tmp == '\\' && last_letter != '\\') + continue; // do not append an unbackslashed backslash + } + str += tmp; + } +} + +inline std::string +GetPot::__process_section_label(const std::string& Section, + STRING_VECTOR& section_stack) +{ + std::string sname = Section; + // 1) subsection of actual section ('./' prefix) + if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) { + sname = sname.substr(2); + } + // 2) subsection of parent section ('../' prefix) + else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) { + do { + if( section_stack.end() != section_stack.begin() ) + section_stack.pop_back(); + sname = sname.substr(3); + } while( sname.substr(0, 3) == "../" ); + } + // 3) subsection of the root-section + else { + section_stack.erase(section_stack.begin(), section_stack.end()); + // [] => back to root section + } + + if( sname != "" ) { + // parse section name for 'slashes' + unsigned i=0; + while( i < sname.length() ) { + if( sname[i] == '/' ) { + section_stack.push_back(sname.substr(0,i)); + if( i+1 < sname.length()-1 ) + sname = sname.substr(i+1); + i = 0; + } + else + ++i; + } + section_stack.push_back(sname); + } + std::string section = ""; + if( section_stack.size() != 0 ) { + victorate(std::string, section_stack, it) + section += *it + "/"; + } + return section; +} + + +// convert string to DOUBLE, if not possible return Default +inline double +GetPot::__convert_to_type(const std::string& String, double Default) const +{ + double tmp; + if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default; + return tmp; +} + +// convert string to INT, if not possible return Default +inline int +GetPot::__convert_to_type(const std::string& String, int Default) const +{ + // NOTE: intermediate results may be floating points, so that the string + // may look like 2.0e1 (i.e. float format) => use float conversion + // in any case. + return (int)__convert_to_type(String, (double)Default); +} + +////////////////////////////////////////////////////////////////////////////// +// (*) cursor oriented functions +//............................................................................. +inline const std::string +GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const + // Checks if 'String' begins with 'Start' and returns the remaining String. + // Returns None if String does not begin with Start. +{ + if( Start == "" ) return String; + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( String.find(Start) == 0 ) return String.substr(Start.length()); + else return ""; +} + +// -- search for a certain argument and set cursor to position +inline bool +GetPot::search(const char* Option) +{ + unsigned OldCursor = cursor; + const std::string SearchTerm = prefix + Option; + + // (*) record requested arguments for later ufo detection + __record_argument_request(SearchTerm); + + if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + // in case nothing is found the cursor stays where it was + return false; +} + + +inline bool +GetPot::search(unsigned No, const char* P, ...) +{ + // (*) recording the requested arguments happens in subroutine 'search' + if( No == 0 ) return false; + + // search for the first argument + if( search(P) == true ) return true; + + // start interpreting variable argument list + va_list ap; + va_start(ap, P); + unsigned i = 1; + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) break; + } + + if( i < No ) { + ++i; + // loop was left before end of array --> hit but + // make sure that the rest of the search terms is marked + // as requested. + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + // (*) record requested arguments for later ufo detection + __record_argument_request(Opt); + } + va_end(ap); + return true; + } + + va_end(ap); + // loop was left normally --> no hit + return false; +} + +inline void +GetPot::reset_cursor() +{ search_failed_f = false; cursor = 0; } + +inline void +GetPot::init_multiple_occurrence() +{ disable_loop(); reset_cursor(); } +/////////////////////////////////////////////////////////////////////////////// +// (*) direct access to command line arguments +//............................................................................. +// +inline const std::string +GetPot::operator[](unsigned idx) const +{ return idx < argv.size() ? argv[idx] : ""; } + +inline int +GetPot::get(unsigned Idx, int Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline double +GetPot::get(unsigned Idx, const double& Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline const std::string +GetPot::get(unsigned Idx, const char* Default) const +{ + if( Idx >= argv.size() ) return Default; + else return argv[Idx]; +} + +inline unsigned +GetPot::size() const +{ return static_cast<unsigned int>(argv.size()); } + + +// -- next() function group +inline int +GetPot::next(int Default) +{ + if( search_failed_f ) return Default; + cursor++; + if( cursor >= argv.size() ) + { cursor = static_cast<unsigned int>(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline double +GetPot::next(const double& Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast<unsigned int>(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline const std::string +GetPot::next(const char* Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast<unsigned int>(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + if( Remain == "" ) return Default; + + + // (*) function returns a pointer to a char array (inside Remain) + // this array will be deleted, though after this function call. + // To ensure propper functioning, create a copy inside *this + // object and only delete it, when *this is deleted. + char* result = new char[Remain.length()+1]; + strncpy(result, Remain.c_str(), Remain.length()+1); + + // store the created string internally, delete if when object deleted + __internal_string_container.push_back(result); + + return result; +} + +// -- follow() function group +// distinct option to be searched for +inline int +GetPot::follow(int Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline double +GetPot::follow(const double& Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline const std::string +GetPot::follow(const char* Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +// -- second follow() function group +// multiple option to be searched for +inline int +GetPot::follow(int Default, unsigned No, const char* P, ...) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( No == 0 ) return Default; + if( search(P) == true ) return next(Default); + + va_list ap; + va_start(ap, P); + unsigned i=1; + for(; i<No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) { + va_end(ap); + return next(Default); + } + } + va_end(ap); + return Default; +} + +inline double +GetPot::follow(const double& Default, unsigned No, const char* P, ...) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( No == 0 ) return Default; + if( search(P) == true ) return next(Default); + + va_list ap; + va_start(ap, P); + for(unsigned i=1; i<No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) { + va_end(ap); + return next(Default); + } + } + va_end(ap); + return Default; +} + +inline const std::string +GetPot::follow(const char* Default, unsigned No, const char* P, ...) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( No == 0 ) return Default; + if( search(P) == true ) return next(Default); + + va_list ap; + va_start(ap, P); + unsigned i=1; + for(; i<No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) { + va_end(ap); + return next(Default); + } + } + va_end(ap); + return Default; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) lists of nominus following an option +//............................................................................. +// +inline std::vector<std::string> +GetPot::nominus_followers(const char* Option) +{ + std::vector<std::string> result_list; + if( search(Option) == false ) return result_list; + while( 1 + 1 == 2 ) { + ++cursor; + if( cursor >= argv.size() ) { + cursor = argv.size() - 1; + return result_list; + } + if( argv[cursor].length() >= 1 ) { + if( argv[cursor][0] == '-' ) { + return result_list; + } + // -- record for later ufo-detection + __record_argument_request(argv[cursor]); + // -- append to the result list + result_list.push_back(argv[cursor]); + } + } +} + +inline std::vector<std::string> +GetPot::nominus_followers(unsigned No, ...) +{ + std::vector<std::string> result_list; + // (*) record requested of argument is entirely handled in 'search()' + // and 'nominus_followers()' + if( No == 0 ) return result_list; + + va_list ap; + va_start(ap, No); + for(unsigned i=0; i<No; ++i) { + char* Option = va_arg(ap, char *); + std::vector<std::string> tmp = nominus_followers(Option); + result_list.insert(result_list.end(), tmp.begin(), tmp.end()); + + // std::cerr << "option = '" << Option << "'" << std::endl; + // std::cerr << "length = " << tmp.size() << std::endl; + // std::cerr << "new result list = <"; + // for(std::vector<std::string>::const_iterator it = result_list.begin(); + // it != result_list.end(); ++it) + // std::cerr << *it << ", "; + // std::cerr << ">\n"; + } + va_end(ap); + return result_list; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) directly connected options +//............................................................................. +// +inline int +GetPot::direct_follow(int Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0x0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline double +GetPot::direct_follow(const double& Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline const std::string +GetPot::direct_follow(const char* Default, const char* Option) +{ + if( search_failed_f ) return Default; + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size()); + return std::string(FollowStr); +} + +inline std::vector<std::string> +GetPot::string_tails(const char* StartString) +{ + std::vector<std::string> result; + const unsigned N = static_cast<unsigned int>(strlen(StartString)); + + std::vector<std::string>::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back((*it).substr(N)); + + // adapt the nominus vector + std::vector<unsigned>::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector<int> +GetPot::int_tails(const char* StartString, const int Default /* = -1 */) +{ + std::vector<int> result; + const unsigned N = static_cast<unsigned int>(strlen(StartString)); + + std::vector<std::string>::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector<unsigned>::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector<double> +GetPot::double_tails(const char* StartString, + const double Default /* = -1.0 */) +{ + std::vector<double> result; + const unsigned N = static_cast<unsigned int>(strlen(StartString)); + + std::vector<std::string>::iterator it = argv.begin(); + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector<unsigned>::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + + + + + +inline const char* +GetPot::__match_starting_string(const char* StartString) + // pointer to the place where the string after + // the match inside the found argument starts. + // 0 no argument matches the starting string. +{ + const unsigned N = static_cast<unsigned int>(strlen(StartString)); + unsigned OldCursor = cursor; + + if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) search for flags +//............................................................................. +// +inline bool +GetPot::options_contain(const char* FlagList) const +{ + // go through all arguments that start with a '-' (but not '--') + std::string str; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) { + str = __get_remaining_string(*it, prefix); + + if( str.length() >= 2 && str[0] == '-' && str[1] != '-' ) + if( __check_flags(str, FlagList) ) return true; + } + return false; +} + +inline bool +GetPot::argument_contains(unsigned Idx, const char* FlagList) const +{ + if( Idx >= argv.size() ) return false; + + // (*) record requested of argument for later ufo-detection + // an argument that is checked for flags is considered to be 'requested' + ((GetPot*)this)->__record_argument_request(argv[Idx]); + + if( prefix == "" ) + // search argument for any flag in flag list + return __check_flags(argv[Idx], FlagList); + + // if a prefix is set, then the argument index is the index + // inside the 'namespace' + // => only check list of arguments that start with prefix + unsigned no_matches = 0; + unsigned i=0; + for(; i<argv.size(); ++i) { + const std::string Remain = __get_remaining_string(argv[i], prefix); + if( Remain != "") { + no_matches += 1; + if( no_matches == Idx) + return __check_flags(Remain, FlagList); + } + } + // no argument in this namespace + return false; +} + +inline bool +GetPot::__check_flags(const std::string& Str, const char* FlagList) const +{ + const char* p=FlagList; + for(; *p != '\0' ; p++) + if( Str.find(*p) != std::string::npos ) return true; // found something + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) nominus arguments +inline STRING_VECTOR +GetPot::nominus_vector() const + // return vector of nominus arguments +{ + STRING_VECTOR nv; + std::vector<unsigned>::const_iterator it = idx_nominus.begin(); + for(; it != idx_nominus.end(); ++it) { + nv.push_back(argv[*it]); + + // (*) record for later ufo-detection + // when a nominus vector is requested, the entire set of nominus arguments are + // tagged as 'requested' + ((GetPot*)this)->__record_argument_request(argv[*it]); + } + return nv; +} + +inline std::string +GetPot::next_nominus() +{ + if( nominus_cursor < int(idx_nominus.size()) - 1 ) { + const std::string Tmp = argv[idx_nominus[++nominus_cursor]]; + + // (*) record for later ufo-detection + __record_argument_request(Tmp); + + // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer + // to something that does no longer exist. + return Tmp; + } + return std::string(""); +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) variables +//............................................................................. +// +inline int +GetPot::operator()(const char* VarName, int Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + // -- returning a c_str() pointer is OK here, since the variable remains existant, + // while 'sv' of course is delete at the end of the function. + return sv->original; +} + +inline int +GetPot::operator()(const char* VarName, int Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return *element; +} + +inline void +GetPot::__record_argument_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_arguments.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +inline void +GetPot::__record_variable_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_variables.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +// (*) following functions are to be used from 'outside', after getpot has parsed its +// arguments => append an argument in the argument vector that reflects the addition +inline void +GetPot::__set_variable(const char* VarName, const char* Value) +{ + const GetPot::variable* Var = __find_variable(VarName); + if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str())); + else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str()); +} + +inline void +GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */) +{ + const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value); + argv.push_back(Arg); + __set_variable(VarName, Value); + + // if user does not specify the variable as 'not being requested' it will be + // considered amongst the requested variables + if( Requested ) __record_variable_request(Arg); +} + +inline void +GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __double2string(Value).c_str()); } + +inline void +GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __int2string(Value).c_str()); } + + +inline unsigned +GetPot::vector_variable_size(const char* VarName) const +{ + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return 0; + return static_cast<unsigned int>(sv->value.size()); +} + +inline STRING_VECTOR +GetPot::get_variable_names() const +{ + STRING_VECTOR result; + std::vector<GetPot::variable>::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + const std::string Tmp = __get_remaining_string((*it).name, prefix); + if( Tmp != "" ) result.push_back(Tmp); + } + return result; +} + +inline STRING_VECTOR +GetPot::get_section_names() const +{ return section_list; } + +inline const GetPot::variable* +GetPot::__find_variable(const char* VarName) const +{ + const std::string Name = prefix + VarName; + + // (*) record requested variable for later ufo detection + ((GetPot*)this)->__record_variable_request(Name); + + std::vector<variable>::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + if( (*it).name == Name ) return &(*it); + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) ouput (basically for debugging reasons +//............................................................................. +// +inline int +GetPot::print() const +{ + std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) + std::cout << *it << std::endl; + std::cout << std::endl; + return 1; +} + +// (*) dollar bracket expressions (DBEs) ------------------------------------ +// +// 1) Entry Function: __DBE_expand_string() +// Takes a string such as +// +// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}" +// +// calls __DBE_expand() for each of the expressions +// +// ${+ ${x} ${y}} +// ${& ${section} ${subsection}} +// ${Title} +// +// and returns the string +// +// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene" +// +// assuming that +// x = "4699" +// y = "12" +// section = "1." +// subsection = "01" +// title = "Mit den Clowns kamen die Schwaene" +// +// 2) __DBE_expand(): +// +// checks for the command, i.e. the 'sign' that follows '${' +// divides the argument list into sub-expressions using +// __DBE_get_expr_list() +// +// ${+ ${x} ${y}} -> "${x}" "${y}" +// ${& ${section} ${subsection}} -> "${section}" "${subsection}" +// ${Title} -> Nothing, variable expansion +// +// 3) __DBE_expression_list(): +// +// builds a vector of unbracketed whitespace separated strings, i.e. +// +// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}" +// +// is split into a vector +// +// [0] ${Number}.a +// [1] ${: Das Marmorbild} +// [2] AB-${& Author= ${Eichendorf}}-1870 +// +// Each sub-expression is expanded using expand(). +//--------------------------------------------------------------------------- +inline std::string +GetPot::__DBE_expand_string(const std::string str) +{ + // Parses for closing operators '${ }' and expands them letting + // white spaces and other letters as they are. + std::string new_string = ""; + unsigned open_brackets = 0; + unsigned first = 0; + unsigned i = 0; + for(; i<str.size(); ++i) { + if( i < str.size() - 2 && str.substr(i, 2) == "${" ) { + if( open_brackets == 0 ) first = i+2; + open_brackets++; + } + else if( str[i] == '}' && open_brackets > 0) { + open_brackets -= 1; + if( open_brackets == 0 ) { + const std::string Replacement = __DBE_expand(str.substr(first, i - first)); + new_string += Replacement; + } + } + else if( open_brackets == 0 ) + new_string += str[i]; + } + return new_string; +} + +inline STRING_VECTOR +GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber) + // ensures that the resulting vector has the expected number + // of arguments, but they may contain an error message +{ + std::string str = str_; + // Separates expressions by non-bracketed whitespaces, expands them + // and puts them into a list. + + unsigned i=0; + // (1) eat initial whitespaces + for(; i < str.size(); ++i) + if( ! isspace(str[i]) ) break; + + STRING_VECTOR expr_list; + unsigned open_brackets = 0; + std::vector<unsigned> start_idx; + unsigned start_new_string = i; + unsigned l = static_cast<unsigned int>(str.size()); + + // (2) search for ${ } expressions ... + while( i < l ) { + const char letter = str[i]; + // whitespace -> end of expression + if( isspace(letter) && open_brackets == 0) { + expr_list.push_back(str.substr(start_new_string, i - start_new_string)); + bool no_breakout_f = true; + for(++i; i < l ; ++i) { + if( ! isspace(str[i]) ) + { no_breakout_f = false; start_new_string = i; break; } + } + if( no_breakout_f ) { + // end of expression list + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + return expr_list; + } + } + + // dollar-bracket expression + if( str.length() >= i+2 && str.substr(i, 2) == "${" ) { + open_brackets++; + start_idx.push_back(i+2); + } + else if( letter == '}' && open_brackets > 0) { + int start = start_idx[start_idx.size()-1]; + start_idx.pop_back(); + const std::string Replacement = __DBE_expand(str.substr(start, i-start)); + if( start - 3 < (int)0) + str = Replacement + str.substr(i+1); + else + str = str.substr(0, start-2) + Replacement + str.substr(i+1); + l = static_cast<unsigned int>(str.size()); + i = start + static_cast<unsigned int>(Replacement.size()) - 3; + open_brackets--; + } + ++i; + } + + // end of expression list + expr_list.push_back(str.substr(start_new_string, i-start_new_string)); + + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + + return expr_list; +} + +inline const GetPot::variable* +GetPot::__DBE_get_variable(std::string VarName) +{ + static GetPot::variable ev; + std::string secure_Prefix = prefix; + + prefix = section; + // (1) first search in currently active section + const GetPot::variable* var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + // (2) search in root name space + prefix = ""; + var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + prefix = secure_Prefix; + + // error occured => variable name == "" + char* tmp = new char[VarName.length() + 25]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25), +#else + _snprintf(tmp, sizeof(char)*(VarName.length() + 25), +#endif + "<<${ } variable '%s' undefined>>", VarName.c_str()); + ev.name = ""; + ev.original = std::string(tmp); + delete [] tmp; + return &ev; +} + +inline std::string +GetPot::__DBE_expand(const std::string expr) +{ + // ${: } pure text + if( expr[0] == ':' ) + return expr.substr(1); + + // ${& expr expr ... } text concatination + else if( expr[0] == '&' ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1); + + STRING_VECTOR::const_iterator it = A.begin(); + std::string result = *it++; + for(; it != A.end(); ++it) result += *it; + + return result; + } + + // ${<-> expr expr expr} text replacement + else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3); + std::string::size_type tmp = 0; + const std::string::size_type L = A[1].length(); + while( (tmp = A[0].find(A[1])) != std::string::npos ) { + A[0].replace(tmp, L, A[2]); + } + return A[0]; + } + // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions + else if( expr[0] == '+' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result += __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '-' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result -= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '*' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result *= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '/' ) { + + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + if( result == 0 ) return "0.0"; + for(; it != A.end(); ++it) { + const double Q = __convert_to_type(*it, 0.0); + if( Q == 0.0 ) return "0.0"; + result /= Q; + } + return __double2string(result); + } + + // ${^ ... } power expressions + else if( expr[0] == '^' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result = pow(result, __convert_to_type(*it, 0.0)); + return __double2string(result); + } + + // ${== } ${<= } ${>= } comparisons (return the number of the first 'match' + else if( expr.length() >= 2 && + ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" || + expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) { + // differentiate between two and one sign operators + unsigned op = 0; + enum { EQ, GEQ, LEQ, GT, LT }; + if ( expr.substr(0, 2) == "==" ) op = EQ; + else if ( expr.substr(0, 2) == ">=" ) op = GEQ; + else if ( expr.substr(0, 2) == "<=" ) op = LEQ; + else if ( expr[0] == '>' ) op = GT; + else /* "<" */ op = LT; + + STRING_VECTOR a; + if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2); + else a = __DBE_get_expr_list(expr.substr(2), 2); + + std::string x_orig = a[0]; + double x = __convert_to_type(x_orig, 1e37); + unsigned i = 1; + + STRING_VECTOR::const_iterator y_orig = a.begin(); + for(y_orig++; y_orig != a.end(); y_orig++) { + double y = __convert_to_type(*y_orig, 1e37); + + // set the strings as reference if one wasn't a number + if ( x == 1e37 || y == 1e37 ) { + // it's a string comparison + if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) || + (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) || + (op == LT && x_orig < *y_orig) ) + return __int2string(i); + } + else { + // it's a number comparison + if( (op == EQ && x == y) || (op == GEQ && x >= y) || + (op == LEQ && x <= y) || (op == GT && x > y) || + (op == LT && x < y) ) + return __int2string(i); + } + ++i; + } + + // nothing fulfills the condition => return 0 + return "0"; + } + // ${?? expr expr} select + else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(a[0], 1e37); + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1]; + + // round x to closest integer + return a[int(x+0.5)]; + } + // ${? expr expr expr} if then else conditions + else if( expr[0] == '?' ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2); + if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1]; + else if( a.size() > 2 ) return a[2]; + } + // ${! expr} maxro expansion + else if( expr[0] == '!' ) { + const GetPot::variable* Var = __DBE_get_variable(expr.substr(1)); + // error + if( Var->name == "" ) return std::string(Var->original); + + const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2); + return A[0]; + } + // ${@: } - string subscription + else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= A[0].size() - 1) + return "<<1st index out of range>>"; + + if( A.size() > 2 ) { + double y = __convert_to_type(A[2], 1e37); + if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x ) + return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5)); + else if( y == -1 ) + return A[0].substr(int(x+0.5)); + return "<<2nd index out of range>>"; + } + else { + char* tmp = new char[2]; + tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0'; + std::string result(tmp); + delete [] tmp; + return result; + } + } + // ${@ } - vector subscription + else if( expr[0] == '@' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + const GetPot::variable* Var = __DBE_get_variable(A[0]); + // error + if( Var->name == "" ) { + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + return std::string(Var->original); + } + + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if (x == 1e37 || x < 0 || x >= Var->value.size() ) + return "<<1st index out of range>>"; + + if ( A.size() > 2) { + double y = __convert_to_type(A[2], 1e37); + int begin = int(x+0.5); + int end = 0; + if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x) + end = int(y+1.5); + else if( y == -1 ) + end = static_cast<unsigned int>(Var->value.size()); + else + return "<<2nd index out of range>>"; + + std::string result = *(Var->get_element(begin)); + int i = begin+1; + for(; i < end; ++i) + result += std::string(" ") + *(Var->get_element(i)); + return result; + } + else + return *(Var->get_element(int(x+0.5))); + } + + const STRING_VECTOR A = __DBE_get_expr_list(expr, 1); + const GetPot::variable* B = __DBE_get_variable(A[0]); + + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + if( B->name == "" ) return std::string(B->original); + // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces + // with: else return B->original (thanks)) + return B->original; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) unidentified flying objects +//............................................................................. +// +inline bool +GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const +{ + victorate(std::string, VecStr, itk) { + if( *itk == Str ) return true; + } + return false; +} + +inline STRING_VECTOR +GetPot::unidentified_arguments(unsigned Number, + const char* KnownArgument1, ...) const +{ + STRING_VECTOR known_arguments; + + // (1) create a vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownArgument1); + known_arguments.push_back(std::string(KnownArgument1)); + unsigned i=1; + for(; i<Number; ++i) + known_arguments.push_back(std::string(va_arg(ap, char *))); + va_end(ap); + + return unidentified_arguments(known_arguments); +} + +inline STRING_VECTOR +GetPot::unidentified_arguments() const +{ return unidentified_arguments(_requested_arguments); } + +inline STRING_VECTOR +GetPot::unidentified_arguments(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // -- check if in list + if( __search_string_vector(Knowns, arg) == false) + ufos.push_back(*it); + } + return ufos; +} + +inline STRING_VECTOR +GetPot::unidentified_options(unsigned Number, + const char* KnownOption1, ...) const +{ + STRING_VECTOR known_options; + + // (1) create a vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownOption1); + known_options.push_back(std::string(KnownOption1)); + unsigned i=1; + for(; i<Number; ++i) + known_options.push_back(std::string(va_arg(ap, char *))); + va_end(ap); + + return unidentified_options(known_options); +} + +inline STRING_VECTOR +GetPot::unidentified_options() const +{ + // -- every option is an argument. + // -- the set of requested arguments contains the set of requested options. + // -- IF the set of requested arguments contains unrequested options, + // THEN they were requested as 'follow' and 'next' arguments and not as real options. + // + // => it is not necessary to separate requested options from the list + STRING_VECTOR option_list; + victorate(std::string, _requested_arguments, it) { + const std::string arg = *it; + if( arg.length() == 0 ) continue; + if( arg[0] == '-' ) option_list.push_back(arg); + } + return unidentified_options(option_list); +} + +inline STRING_VECTOR +GetPot::unidentified_options(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // is argument really an option (starting with '-') ? + if( arg.length() < 1 || arg[0] != '-' ) continue; + + if( __search_string_vector(Knowns, arg) == false) + ufos.push_back(*it); + } + + return ufos; +} + +inline std::string +GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const + // Two modes: + // ArgumentNumber >= 0 check specific argument + // ArgumentNumber == -1 check all options starting with one '-' + // for flags +{ + std::string ufos; + STRING_VECTOR known_arguments; + std::string KFL(KnownFlagList); + + // (2) iteration over '-' arguments (options) + if( ArgumentNumber == -1 ) { + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // -- does arguments start with '-' (but not '--') + if ( arg.length() < 2 ) continue; + else if( arg[0] != '-' ) continue; + else if( arg[1] == '-' ) continue; + + // -- check out if flags inside option are contained in KnownFlagList + const char* p=arg.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + } + } + // (1) check specific argument + else { + // -- only check arguments that start with prefix + int no_matches = 0; + unsigned i=1; + for(; i<argv.size(); ++i) { + const std::string Remain = __get_remaining_string(argv[i], prefix); + if( Remain != "") { + no_matches++; + if( no_matches == ArgumentNumber) { + // -- the right argument number inside the section is found + // => check it for flags + const char* p = Remain.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + return ufos; + } + } + } + } + return ufos; +} + +inline STRING_VECTOR +GetPot::unidentified_variables(unsigned Number, + const char* KnownVariable1, ...) const +{ + STRING_VECTOR known_variables; + + // create vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownVariable1); + known_variables.push_back(std::string(KnownVariable1)); + unsigned i=1; + for(; i<Number; ++i) + known_variables.push_back(std::string(va_arg(ap, char *))); + va_end(ap); + + return unidentified_variables(known_variables); +} + +inline STRING_VECTOR +GetPot::unidentified_variables(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + + victorate(GetPot::variable, variables, it) { + // -- check if variable has specific prefix + const std::string var_name = __get_remaining_string((*it).name, prefix); + if( var_name == "" ) continue; + + // -- check if variable is known + if( __search_string_vector(Knowns, var_name) == false) + ufos.push_back((*it).name); + } + return ufos; +} + +inline STRING_VECTOR +GetPot::unidentified_variables() const +{ return unidentified_variables(_requested_variables); } + + +inline STRING_VECTOR +GetPot::unidentified_sections(unsigned Number, + const char* KnownSection1, ...) const +{ + STRING_VECTOR known_sections; + + // (1) create a vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownSection1); + known_sections.push_back(std::string(KnownSection1)); + unsigned i=1; + for(; i<Number; ++i) { + std::string tmp = std::string(va_arg(ap, char *)); + if( tmp.length() == 0 ) continue; + if( tmp[tmp.length()-1] != '/' ) tmp += '/'; + known_sections.push_back(tmp); + } + va_end(ap); + + return unidentified_sections(known_sections); +} + +inline STRING_VECTOR +GetPot::unidentified_sections() const +{ return unidentified_sections(_requested_sections); } + +inline STRING_VECTOR +GetPot::unidentified_sections(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + + victorate(std::string, section_list, it) { + // -- check if section conform to prefix + const std::string sec_name = __get_remaining_string(*it, prefix); + if( sec_name == "" ) continue; + + // -- check if section is known + if( __search_string_vector(Knowns, sec_name) == false ) + ufos.push_back(*it); + } + + return ufos; +} + + +inline STRING_VECTOR +GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const +{ + STRING_VECTOR known_nominuses; + + // create vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, Known); + known_nominuses.push_back(std::string(Known)); + unsigned i=1; + for(; i<Number; ++i) { + std::string tmp = std::string(va_arg(ap, char *)); + if( tmp.length() == 0 ) continue; + known_nominuses.push_back(tmp); + } + va_end(ap); + + return unidentified_nominuses(known_nominuses); +} + +inline STRING_VECTOR +GetPot::unidentified_nominuses() const { + // -- every nominus is an argument. + // -- the set of requested arguments contains the set of requested nominuss. + // -- IF the set of requested arguments contains unrequested nominuss, + // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses. + // + // => it is not necessary to separate requested nominus from the list + + return unidentified_nominuses(_requested_arguments); +} + +inline STRING_VECTOR +GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + + // (2) iterate over all arguments + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- check if nominus part of prefix + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + if( arg.length() < 1 ) continue; + // option ? --> not a nomius + if( arg[0] == '-' ) continue; + // section ? --> not a real nominus + if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue; + // variable definition ? --> not a real nominus + bool continue_f = false; + unsigned i=0; + for(; i<arg.length() ; ++i) + if( arg[i] == '=' ) { continue_f = true; break; } + if( continue_f ) continue; + + // real nominuses are compared with the given list + if( __search_string_vector(Knowns, arg) == false ) + ufos.push_back(*it); + } + return ufos; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) variable class +//............................................................................. +// +inline +GetPot::variable::variable() +{} + +inline +GetPot::variable::variable(const variable& That) +{ +#ifdef WIN32 + operator=(That); +#else + GetPot::variable::operator=(That); +#endif +} + + +inline +GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator) + : name(Name) +{ + // make a copy of the 'Value' + take(Value, FieldSeparator); +} + +inline const std::string* +GetPot::variable::get_element(unsigned Idx) const +{ if( Idx >= value.size() ) return 0; else return &(value[Idx]); } + +inline void +GetPot::variable::take(const char* Value, const char* FieldSeparator) +{ + original = std::string(Value); + + // separate string by white space delimiters using 'strtok' + // thread safe usage of strtok (no static members) + char* spt = 0; + // make a copy of the 'Value' + char* copy = new char[strlen(Value)+1]; + strcpy(copy, Value); + char* follow_token = strtok_r(copy, FieldSeparator, &spt); + if( value.size() != 0 ) value.erase(value.begin(), value.end()); + while(follow_token != 0) { + value.push_back(std::string(follow_token)); + follow_token = strtok_r(NULL, FieldSeparator, &spt); + } + + delete [] copy; +} + +inline +GetPot::variable::~variable() +{} + +inline GetPot::variable& +GetPot::variable::operator=(const GetPot::variable& That) +{ + if( &That != this) { + name = That.name; + value = That.value; + original = That.original; + } + return *this; +} + +#undef victorate + + +#endif // __include_guard_GETPOT_H__ + + + diff --git a/utils/zenutils/libraries/pelib-0.9/CMakeLists.txt b/utils/zenutils/libraries/pelib-0.9/CMakeLists.txt index 540fa99c8c..3cdb6e71ff 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/CMakeLists.txt +++ b/utils/zenutils/libraries/pelib-0.9/CMakeLists.txt @@ -1,20 +1,20 @@ -PROJECT(pelib)
-
-# source files for pelib
-SET(pelib_srcs
- pelib/BoundImportDirectory.cpp
- pelib/ComHeaderDirectory.cpp
- pelib/DebugDirectory.cpp
- pelib/ExportDirectory.cpp
- pelib/IatDirectory.cpp
- pelib/MzHeader.cpp
- pelib/PeFile.cpp
- pelib/PeHeader.cpp
- pelib/PeLibAux.cpp
- pelib/RelocationsDirectory.cpp
- pelib/ResourceDirectory.cpp
- pelib/buffer/InputBuffer.cpp
- pelib/buffer/OutputBuffer.cpp
-)
-
-ADD_LIBRARY(pelib ${pelib_srcs})
+PROJECT(pelib) + +# source files for pelib +SET(pelib_srcs + pelib/BoundImportDirectory.cpp + pelib/ComHeaderDirectory.cpp + pelib/DebugDirectory.cpp + pelib/ExportDirectory.cpp + pelib/IatDirectory.cpp + pelib/MzHeader.cpp + pelib/PeFile.cpp + pelib/PeHeader.cpp + pelib/PeLibAux.cpp + pelib/RelocationsDirectory.cpp + pelib/ResourceDirectory.cpp + pelib/buffer/InputBuffer.cpp + pelib/buffer/OutputBuffer.cpp +) + +ADD_LIBRARY(pelib ${pelib_srcs}) diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.cpp index 5b84931838..7c5ff74f0e 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.cpp @@ -1,511 +1,511 @@ -/*
-* BoundImportDirectory.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "PeLibInc.h"
-#include "BoundImportDirectory.h"
-#include <numeric>
-#include <set>
-#include <map>
-
-namespace PeLib
-{
- /**
- * Adds another bound import to the BoundImport directory.
- * @param strModuleName Name of the PE file which will be imported.
- * @param dwTds Value of the TimeDateStamp of the bound import field.
- * @param wOmn Value of the OffsetModuleName of the bound import field.
- * @param wWfr Value of the NumberOfModuleForwarderRefs of the bound import field.
- **/
- int BoundImportDirectory::addBoundImport(const std::string& strModuleName, dword dwTds, word wOmn, word wWfr)
- {
- for (unsigned int i=0;i<m_vIbd.size();i++)
- {
- if (isEqualNc(strModuleName, m_vIbd[i].strModuleName))
- {
- return ERROR_DUPLICATE_ENTRY;
- }
- }
-
- PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR ibidCurrent;
- ibidCurrent.TimeDateStamp = dwTds;
- ibidCurrent.OffsetModuleName = wOmn;
- ibidCurrent.NumberOfModuleForwarderRefs = wWfr;
- PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent;
- ibdCurrent.ibdDescriptor = ibidCurrent;
- ibdCurrent.strModuleName = strModuleName;
- m_vIbd.push_back(ibdCurrent);
-
- return NO_ERROR;
- }
-
- /**
- * Searches for the first instance of a module with the given modulename.
- * @param strModuleName The name of a module.
- * @return The id of the module.
- **/
- int BoundImportDirectory::getModuleIndex(const std::string& strModuleName) const
- {
- std::vector<PELIB_IMAGE_BOUND_DIRECTORY>::const_iterator Iter = std::find_if(m_vIbd.begin(), m_vIbd.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_BOUND_DIRECTORY::equal), strModuleName));
-
- if (Iter == m_vIbd.end())
- {
- return ERROR_ENTRY_NOT_FOUND;
- }
-
- return static_cast<int>(std::distance(m_vIbd.begin(), Iter));
- }
-
- /**
- * @return Number of files in the current BoundImport directory.
- **/
- unsigned int BoundImportDirectory::calcNumberOfModules() const
- {
- return static_cast<unsigned int>(m_vIbd.size());
- }
-
- int BoundImportDirectory::read(InputBuffer& inpBuffer, unsigned char* data, unsigned int dwSize)
- {
- std::vector<PELIB_IMAGE_BOUND_DIRECTORY> currentDirectory;
-
- do
- {
- PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent;
-
- inpBuffer >> ibdCurrent.ibdDescriptor.TimeDateStamp;
- inpBuffer >> ibdCurrent.ibdDescriptor.OffsetModuleName;
- inpBuffer >> ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs;
-
- if (ibdCurrent.ibdDescriptor.TimeDateStamp == 0 && ibdCurrent.ibdDescriptor.OffsetModuleName == 0 && ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs == 0) break;
-
- for (int i=0;i<ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs;i++)
- {
- PELIB_IMAGE_BOUND_DIRECTORY currentForwarder;
-
- inpBuffer >> currentForwarder.ibdDescriptor.TimeDateStamp;
- inpBuffer >> currentForwarder.ibdDescriptor.OffsetModuleName;
- inpBuffer >> currentForwarder.ibdDescriptor.NumberOfModuleForwarderRefs;
-
- ibdCurrent.moduleForwarders.push_back(currentForwarder);
- }
-
- currentDirectory.push_back(ibdCurrent);
- ibdCurrent.moduleForwarders.clear();
- } while (true);
-
- for (unsigned int i=0;i<currentDirectory.size();i++)
- {
- dword wOmn = currentDirectory[i].ibdDescriptor.OffsetModuleName;
- if (wOmn > dwSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- currentDirectory[i].strModuleName = "";
- for (int k=0;data[wOmn + k] != 0 && k + wOmn < dwSize;k++)
- {
- currentDirectory[i].strModuleName += data[wOmn + k];
- }
-
- for (unsigned int j=0;j<currentDirectory[i].moduleForwarders.size();j++)
- {
- dword wOmn = currentDirectory[i].moduleForwarders[j].ibdDescriptor.OffsetModuleName;
-
- if (wOmn > dwSize)
- {
- return ERROR_INVALID_FILE;
- }
-
-// m_vIbd[i].moduleForwarders[j].strModuleName.assign((char*)(&vBimpDir[wOmn]));
- currentDirectory[i].moduleForwarders[j].strModuleName = "";
- for (int k=0;data[wOmn + k] != 0 && k + wOmn < dwSize;k++)
- {
- currentDirectory[i].moduleForwarders[j].strModuleName += data[wOmn + k];
- }
- }
- }
-
- std::swap(m_vIbd, currentDirectory);
-
- return NO_ERROR;
- }
-
- /**
- * Reads the BoundImport directory from a PE file.
- * @param strModuleName The name of the PE file from which the BoundImport directory is read.
- * @param dwOffset The file offset where the BoundImport directory can be found (see #PeFile::PeHeader::getIDBoundImportRVA).
- * @param dwSize The size of the BoundImport directory (see #PeFile::PeHeader::getIDBoundImportSize).
- **/
- int BoundImportDirectory::read(const std::string& strModuleName, dword dwOffset, unsigned int uiSize)
- {
- std::ifstream ifFile(strModuleName.c_str(), std::ios::binary);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- if (fileSize(ifFile) < dwOffset + uiSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(dwOffset, std::ios::beg);
-
- std::vector<unsigned char> vBimpDir(uiSize);
- ifFile.read(reinterpret_cast<char*>(&vBimpDir[0]), uiSize);
-
- InputBuffer inpBuffer(vBimpDir);
-
- return read(inpBuffer, &vBimpDir[0], uiSize);
- }
-
- int BoundImportDirectory::read(unsigned char* pcBuffer, unsigned int uiSize)
- {
- std::vector<unsigned char> vBimpDir(pcBuffer, pcBuffer + uiSize);
- InputBuffer inpBuffer(vBimpDir);
-
- return read(inpBuffer, &vBimpDir[0], uiSize);
- }
-
- unsigned int BoundImportDirectory::totalModules() const
- {
- unsigned int modules = static_cast<unsigned int>(m_vIbd.size());
-
- for (unsigned int i=0;i<m_vIbd.size();i++)
- {
- modules += static_cast<unsigned int>(m_vIbd[i].moduleForwarders.size());
- }
-
- return modules;
- }
-
- /**
- * Rebuilds the BoundImport directory. The rebuilded BoundImport directory can then be
- * written back to a PE file.
- * @param vBuffer Buffer where the rebuilt BoundImport directory will be stored.
- * @param fMakeValid If this flag is true a valid directory will be produced.
- **/
- void BoundImportDirectory::rebuild(std::vector<byte>& vBuffer, bool fMakeValid) const
- {
- std::map<std::string, word> filename_offsets;
-
- OutputBuffer obBuffer(vBuffer);
-
- word ulNameOffset = static_cast<word>((totalModules() + 1) * PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size());
-
- for (unsigned int i=0;i<m_vIbd.size();i++)
- {
- obBuffer << m_vIbd[i].ibdDescriptor.TimeDateStamp;
-
- // Recalculate the offsets if a valid directory is wanted.
- if (fMakeValid)
- {
- if (filename_offsets.find(m_vIbd[i].strModuleName) == filename_offsets.end())
- {
- filename_offsets[m_vIbd[i].strModuleName] = ulNameOffset;
- obBuffer << ulNameOffset;
- ulNameOffset += static_cast<word>(m_vIbd[i].strModuleName.size() + 1);
- }
- else
- {
- obBuffer << filename_offsets[m_vIbd[i].strModuleName];
- }
- }
- else // Otherwise just copy the old values into the buffer.
- {
- obBuffer << m_vIbd[i].ibdDescriptor.OffsetModuleName;
- }
-
- obBuffer << m_vIbd[i].ibdDescriptor.NumberOfModuleForwarderRefs;
-
- for (int j=0;j<calcNumberOfModuleForwarderRefs(i);j++)
- {
- obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.TimeDateStamp;
-
- if (fMakeValid)
- {
- if (filename_offsets.find(m_vIbd[i].strModuleName) == filename_offsets.end())
- {
- filename_offsets[m_vIbd[i].moduleForwarders[j].strModuleName] = ulNameOffset;
- obBuffer << ulNameOffset;
- ulNameOffset += static_cast<word>(m_vIbd[i].moduleForwarders[j].strModuleName.size() + 1);
- }
- else
- {
- obBuffer << filename_offsets[m_vIbd[i].moduleForwarders[j].strModuleName];
- }
- }
- else // Otherwise just copy the old values into the buffer.
- {
- obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.OffsetModuleName;
- }
-
- obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.NumberOfModuleForwarderRefs;
- }
- }
-
- obBuffer << static_cast<dword>(0);
- obBuffer << static_cast<word>(0);
- obBuffer << static_cast<word>(0);
-
- for (unsigned int i=0;i<m_vIbd.size();i++)
- {
- if (filename_offsets.find(m_vIbd[i].strModuleName) != filename_offsets.end())
- {
- obBuffer.add(getModuleName(i).c_str(), static_cast<unsigned long>(getModuleName(i).size() + 1));
- filename_offsets.erase(m_vIbd[i].strModuleName);
- }
-
- for (int j=0;j<calcNumberOfModuleForwarderRefs(i);j++)
- {
- if (filename_offsets.find(getModuleName(i, j)) != filename_offsets.end())
- {
- obBuffer.add(getModuleName(i, j).c_str(), static_cast<unsigned long>(getModuleName(i, j).size() + 1));
- filename_offsets.erase(getModuleName(i, j));
- }
- }
- }
- }
-
- /**
- * Removes all bound import files.
- **/
- void BoundImportDirectory::clear()
- {
- m_vIbd.clear();
- }
-
- /**
- * Removes a field specified by the parameter filename from the BoundImport directory.
- * @param strModuleName Name of the file whose field will be removed from the BoundImport directory.
- **/
- void BoundImportDirectory::removeBoundImport(const std::string& strModuleName)
- {
- m_vIbd.erase(std::remove_if(m_vIbd.begin(), m_vIbd.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_BOUND_DIRECTORY::equal), strModuleName)), m_vIbd.end());
- }
-
- /**
- * Returns the size of the rebuilt BoundImportDirectory.
- * @return Size of the rebuilt BoundImportDirectory.
- **/
- unsigned int BoundImportDirectory::size() const
- {
- unsigned int size = PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size();
-
- std::set<std::string> filenames;
-
- for (unsigned int i = 0; i < m_vIbd.size(); i++)
- {
- filenames.insert(m_vIbd[i].strModuleName);
-
- size += PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size();
-
- for (unsigned int j = 0; j < m_vIbd[i].moduleForwarders.size(); j++)
- {
- filenames.insert(m_vIbd[i].moduleForwarders[j].strModuleName);
-
- size += PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size();
- }
- }
-
- for (std::set<std::string>::iterator iter = filenames.begin(); iter != filenames.end(); ++iter)
- {
- size += static_cast<unsigned int>(iter->size()) + 1;
- }
-
- return size;
- }
-
- /**
- * @param strFilename Name of the file.
- * @param dwOffset File offset the bound importdirectory will be written to.
- * @param fMakeValid If this flag is true a valid directory will be produced.
- **/
- int BoundImportDirectory::write(const std::string& strFilename, dword dwOffset, bool fMakeValid) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(dwOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
- rebuild(vBuffer, fMakeValid);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<std::streamsize>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-
- /**
- * Retrieves the value of the TimeDateStamp value of a bound import field.
- * @param dwBidnr Number of the bound import field.
- * @return Value of the TimeDateStamp of the bound import field.
- **/
- dword BoundImportDirectory::getTimeDateStamp(dword dwBidnr) const
- {
- return m_vIbd[dwBidnr].ibdDescriptor.TimeDateStamp;
- }
-
- /**
- * Retrieves the value of the OffsetModuleName value of a bound import field.
- * @param dwBidnr Number of the bound import field.
- * @return Value of the OffsetModuleName of the bound import field.
- **/
- word BoundImportDirectory::getOffsetModuleName(dword dwBidnr) const
- {
- return m_vIbd[dwBidnr].ibdDescriptor.OffsetModuleName;
- }
-
- /**
- * Retrieves the value of the NumberOfModuleForwarderRefs value of a bound import field.
- * @param dwBidnr Number of the bound import field.
- * @return Value of the NumberOfModuleForwarderRefs of the bound import field.
- **/
- word BoundImportDirectory::getNumberOfModuleForwarderRefs(dword dwBidnr) const
- {
- return m_vIbd[dwBidnr].ibdDescriptor.NumberOfModuleForwarderRefs;
- }
-
- /**
- * Retrieves the value of the ModuleName value of a bound import field.
- * @param dwBidnr Number of the bound import field.
- * @return Value of the ModuleName of the bound import field.
- **/
- std::string BoundImportDirectory::getModuleName(dword dwBidnr) const
- {
- return m_vIbd[dwBidnr].strModuleName;
- }
-
- /**
- * Changes the TimeDateStamp value of an existing bound import field.
- * @param dwBidnr Number of the bound import field which will be changed.
- * @param dwTds New value of the TimeDateStamp of the bound import field.
- **/
- void BoundImportDirectory::setTimeDateStamp(dword dwBidnr, dword dwTds)
- {
- m_vIbd[dwBidnr].ibdDescriptor.TimeDateStamp = dwTds;
- }
-
- /**
- * Changes the OffsetModuleName value of an existing bound import field.
- * @param dwBidnr Number of the bound import field which will be changed.
- * @param wOmn New value of the OffsetModuleName of the bound import field.
- **/
- void BoundImportDirectory::setOffsetModuleName(dword dwBidnr, word wOmn)
- {
- m_vIbd[dwBidnr].ibdDescriptor.OffsetModuleName = wOmn;
- }
-
- /**
- * Changes the NumberOfModuleForwarderRefs value of an existing bound import field.
- * @param dwBidnr Number of the bound import field which will be changed.
- * @param wMfr New value of the NumberOfModuleForwarderRefs of the bound import field.
- **/
- void BoundImportDirectory::setNumberOfModuleForwarderRefs(dword dwBidnr, word wMfr)
- {
- m_vIbd[dwBidnr].ibdDescriptor.NumberOfModuleForwarderRefs = wMfr;
- }
-
- /**
- * Changes the ModuleName value of an existing bound import field.
- * @param dwBidnr Number of the bound import field which will be changed.
- * @param strModuleName New value of the ModuleName of the bound import field.
- **/
- void BoundImportDirectory::setModuleName(dword dwBidnr, const std::string& strModuleName)
- {
- m_vIbd[dwBidnr].strModuleName = strModuleName;
- }
-
- dword BoundImportDirectory::getTimeDateStamp(dword dwBidnr, dword forwardedModule) const
- {
- return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.TimeDateStamp;
- }
-
- word BoundImportDirectory::getOffsetModuleName(dword dwBidnr, dword forwardedModule) const
- {
- return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.OffsetModuleName;
- }
-
- word BoundImportDirectory::getNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule) const
- {
- return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.NumberOfModuleForwarderRefs;
- }
-
- std::string BoundImportDirectory::getModuleName(dword dwBidnr, dword forwardedModule) const
- {
- return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].strModuleName;
- }
-
- void BoundImportDirectory::setTimeDateStamp(dword dwBidnr, dword forwardedModule, dword dwTds)
- {
- m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.TimeDateStamp = dwTds;
- }
-
- void BoundImportDirectory::setOffsetModuleName(dword dwBidnr, dword forwardedModule, word wOmn)
- {
- m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.OffsetModuleName = wOmn;
- }
-
- void BoundImportDirectory::setNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule, word wMfr)
- {
- m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.NumberOfModuleForwarderRefs = wMfr;
- }
-
- void BoundImportDirectory::setModuleName(dword dwBidnr, dword forwardedModule, const std::string& strModuleName)
- {
- m_vIbd[dwBidnr].moduleForwarders[forwardedModule].strModuleName = strModuleName;
- }
-
- word BoundImportDirectory::calcNumberOfModuleForwarderRefs(dword dwBidnr) const
- {
- return static_cast<word>(m_vIbd[dwBidnr].moduleForwarders.size());
- }
-
- void BoundImportDirectory::addForwardedModule(dword dwBidnr, const std::string& name, dword timeStamp, word offsetModuleName, word forwardedModules)
- {
- // XXX: Maybe test if there are already 0xFFFF forwarded modules.
- // XXX: Check for duplicate entries. Is it also necessary to check
- // non-forwarded entries and forwarded entries in other non-forwarded
- // entries?
- // XXX: Can forwarders forward recursively?
-
- PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent;
- ibdCurrent.strModuleName = name;
- ibdCurrent.ibdDescriptor.TimeDateStamp = timeStamp;
- ibdCurrent.ibdDescriptor.OffsetModuleName = offsetModuleName;
- ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs = forwardedModules;
-
- m_vIbd[dwBidnr].moduleForwarders.push_back(ibdCurrent);
- }
-
- void BoundImportDirectory::removeForwardedModule(dword dwBidnr, word forwardedModule)
- {
- m_vIbd[dwBidnr].moduleForwarders.erase(m_vIbd[dwBidnr].moduleForwarders.begin() + forwardedModule);
- }
-}
+/* +* BoundImportDirectory.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "PeLibInc.h" +#include "BoundImportDirectory.h" +#include <numeric> +#include <set> +#include <map> + +namespace PeLib +{ + /** + * Adds another bound import to the BoundImport directory. + * @param strModuleName Name of the PE file which will be imported. + * @param dwTds Value of the TimeDateStamp of the bound import field. + * @param wOmn Value of the OffsetModuleName of the bound import field. + * @param wWfr Value of the NumberOfModuleForwarderRefs of the bound import field. + **/ + int BoundImportDirectory::addBoundImport(const std::string& strModuleName, dword dwTds, word wOmn, word wWfr) + { + for (unsigned int i=0;i<m_vIbd.size();i++) + { + if (isEqualNc(strModuleName, m_vIbd[i].strModuleName)) + { + return ERROR_DUPLICATE_ENTRY; + } + } + + PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR ibidCurrent; + ibidCurrent.TimeDateStamp = dwTds; + ibidCurrent.OffsetModuleName = wOmn; + ibidCurrent.NumberOfModuleForwarderRefs = wWfr; + PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent; + ibdCurrent.ibdDescriptor = ibidCurrent; + ibdCurrent.strModuleName = strModuleName; + m_vIbd.push_back(ibdCurrent); + + return NO_ERROR; + } + + /** + * Searches for the first instance of a module with the given modulename. + * @param strModuleName The name of a module. + * @return The id of the module. + **/ + int BoundImportDirectory::getModuleIndex(const std::string& strModuleName) const + { + std::vector<PELIB_IMAGE_BOUND_DIRECTORY>::const_iterator Iter = std::find_if(m_vIbd.begin(), m_vIbd.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_BOUND_DIRECTORY::equal), strModuleName)); + + if (Iter == m_vIbd.end()) + { + return ERROR_ENTRY_NOT_FOUND; + } + + return static_cast<int>(std::distance(m_vIbd.begin(), Iter)); + } + + /** + * @return Number of files in the current BoundImport directory. + **/ + unsigned int BoundImportDirectory::calcNumberOfModules() const + { + return static_cast<unsigned int>(m_vIbd.size()); + } + + int BoundImportDirectory::read(InputBuffer& inpBuffer, unsigned char* data, unsigned int dwSize) + { + std::vector<PELIB_IMAGE_BOUND_DIRECTORY> currentDirectory; + + do + { + PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent; + + inpBuffer >> ibdCurrent.ibdDescriptor.TimeDateStamp; + inpBuffer >> ibdCurrent.ibdDescriptor.OffsetModuleName; + inpBuffer >> ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs; + + if (ibdCurrent.ibdDescriptor.TimeDateStamp == 0 && ibdCurrent.ibdDescriptor.OffsetModuleName == 0 && ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs == 0) break; + + for (int i=0;i<ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs;i++) + { + PELIB_IMAGE_BOUND_DIRECTORY currentForwarder; + + inpBuffer >> currentForwarder.ibdDescriptor.TimeDateStamp; + inpBuffer >> currentForwarder.ibdDescriptor.OffsetModuleName; + inpBuffer >> currentForwarder.ibdDescriptor.NumberOfModuleForwarderRefs; + + ibdCurrent.moduleForwarders.push_back(currentForwarder); + } + + currentDirectory.push_back(ibdCurrent); + ibdCurrent.moduleForwarders.clear(); + } while (true); + + for (unsigned int i=0;i<currentDirectory.size();i++) + { + dword wOmn = currentDirectory[i].ibdDescriptor.OffsetModuleName; + if (wOmn > dwSize) + { + return ERROR_INVALID_FILE; + } + + currentDirectory[i].strModuleName = ""; + for (int k=0;data[wOmn + k] != 0 && k + wOmn < dwSize;k++) + { + currentDirectory[i].strModuleName += data[wOmn + k]; + } + + for (unsigned int j=0;j<currentDirectory[i].moduleForwarders.size();j++) + { + dword wOmn = currentDirectory[i].moduleForwarders[j].ibdDescriptor.OffsetModuleName; + + if (wOmn > dwSize) + { + return ERROR_INVALID_FILE; + } + +// m_vIbd[i].moduleForwarders[j].strModuleName.assign((char*)(&vBimpDir[wOmn])); + currentDirectory[i].moduleForwarders[j].strModuleName = ""; + for (int k=0;data[wOmn + k] != 0 && k + wOmn < dwSize;k++) + { + currentDirectory[i].moduleForwarders[j].strModuleName += data[wOmn + k]; + } + } + } + + std::swap(m_vIbd, currentDirectory); + + return NO_ERROR; + } + + /** + * Reads the BoundImport directory from a PE file. + * @param strModuleName The name of the PE file from which the BoundImport directory is read. + * @param dwOffset The file offset where the BoundImport directory can be found (see #PeFile::PeHeader::getIDBoundImportRVA). + * @param dwSize The size of the BoundImport directory (see #PeFile::PeHeader::getIDBoundImportSize). + **/ + int BoundImportDirectory::read(const std::string& strModuleName, dword dwOffset, unsigned int uiSize) + { + std::ifstream ifFile(strModuleName.c_str(), std::ios::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + if (fileSize(ifFile) < dwOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(dwOffset, std::ios::beg); + + std::vector<unsigned char> vBimpDir(uiSize); + ifFile.read(reinterpret_cast<char*>(&vBimpDir[0]), uiSize); + + InputBuffer inpBuffer(vBimpDir); + + return read(inpBuffer, &vBimpDir[0], uiSize); + } + + int BoundImportDirectory::read(unsigned char* pcBuffer, unsigned int uiSize) + { + std::vector<unsigned char> vBimpDir(pcBuffer, pcBuffer + uiSize); + InputBuffer inpBuffer(vBimpDir); + + return read(inpBuffer, &vBimpDir[0], uiSize); + } + + unsigned int BoundImportDirectory::totalModules() const + { + unsigned int modules = static_cast<unsigned int>(m_vIbd.size()); + + for (unsigned int i=0;i<m_vIbd.size();i++) + { + modules += static_cast<unsigned int>(m_vIbd[i].moduleForwarders.size()); + } + + return modules; + } + + /** + * Rebuilds the BoundImport directory. The rebuilded BoundImport directory can then be + * written back to a PE file. + * @param vBuffer Buffer where the rebuilt BoundImport directory will be stored. + * @param fMakeValid If this flag is true a valid directory will be produced. + **/ + void BoundImportDirectory::rebuild(std::vector<byte>& vBuffer, bool fMakeValid) const + { + std::map<std::string, word> filename_offsets; + + OutputBuffer obBuffer(vBuffer); + + word ulNameOffset = static_cast<word>((totalModules() + 1) * PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size()); + + for (unsigned int i=0;i<m_vIbd.size();i++) + { + obBuffer << m_vIbd[i].ibdDescriptor.TimeDateStamp; + + // Recalculate the offsets if a valid directory is wanted. + if (fMakeValid) + { + if (filename_offsets.find(m_vIbd[i].strModuleName) == filename_offsets.end()) + { + filename_offsets[m_vIbd[i].strModuleName] = ulNameOffset; + obBuffer << ulNameOffset; + ulNameOffset += static_cast<word>(m_vIbd[i].strModuleName.size() + 1); + } + else + { + obBuffer << filename_offsets[m_vIbd[i].strModuleName]; + } + } + else // Otherwise just copy the old values into the buffer. + { + obBuffer << m_vIbd[i].ibdDescriptor.OffsetModuleName; + } + + obBuffer << m_vIbd[i].ibdDescriptor.NumberOfModuleForwarderRefs; + + for (int j=0;j<calcNumberOfModuleForwarderRefs(i);j++) + { + obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.TimeDateStamp; + + if (fMakeValid) + { + if (filename_offsets.find(m_vIbd[i].strModuleName) == filename_offsets.end()) + { + filename_offsets[m_vIbd[i].moduleForwarders[j].strModuleName] = ulNameOffset; + obBuffer << ulNameOffset; + ulNameOffset += static_cast<word>(m_vIbd[i].moduleForwarders[j].strModuleName.size() + 1); + } + else + { + obBuffer << filename_offsets[m_vIbd[i].moduleForwarders[j].strModuleName]; + } + } + else // Otherwise just copy the old values into the buffer. + { + obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.OffsetModuleName; + } + + obBuffer << m_vIbd[i].moduleForwarders[j].ibdDescriptor.NumberOfModuleForwarderRefs; + } + } + + obBuffer << static_cast<dword>(0); + obBuffer << static_cast<word>(0); + obBuffer << static_cast<word>(0); + + for (unsigned int i=0;i<m_vIbd.size();i++) + { + if (filename_offsets.find(m_vIbd[i].strModuleName) != filename_offsets.end()) + { + obBuffer.add(getModuleName(i).c_str(), static_cast<unsigned long>(getModuleName(i).size() + 1)); + filename_offsets.erase(m_vIbd[i].strModuleName); + } + + for (int j=0;j<calcNumberOfModuleForwarderRefs(i);j++) + { + if (filename_offsets.find(getModuleName(i, j)) != filename_offsets.end()) + { + obBuffer.add(getModuleName(i, j).c_str(), static_cast<unsigned long>(getModuleName(i, j).size() + 1)); + filename_offsets.erase(getModuleName(i, j)); + } + } + } + } + + /** + * Removes all bound import files. + **/ + void BoundImportDirectory::clear() + { + m_vIbd.clear(); + } + + /** + * Removes a field specified by the parameter filename from the BoundImport directory. + * @param strModuleName Name of the file whose field will be removed from the BoundImport directory. + **/ + void BoundImportDirectory::removeBoundImport(const std::string& strModuleName) + { + m_vIbd.erase(std::remove_if(m_vIbd.begin(), m_vIbd.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_BOUND_DIRECTORY::equal), strModuleName)), m_vIbd.end()); + } + + /** + * Returns the size of the rebuilt BoundImportDirectory. + * @return Size of the rebuilt BoundImportDirectory. + **/ + unsigned int BoundImportDirectory::size() const + { + unsigned int size = PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size(); + + std::set<std::string> filenames; + + for (unsigned int i = 0; i < m_vIbd.size(); i++) + { + filenames.insert(m_vIbd[i].strModuleName); + + size += PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size(); + + for (unsigned int j = 0; j < m_vIbd[i].moduleForwarders.size(); j++) + { + filenames.insert(m_vIbd[i].moduleForwarders[j].strModuleName); + + size += PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR::size(); + } + } + + for (std::set<std::string>::iterator iter = filenames.begin(); iter != filenames.end(); ++iter) + { + size += static_cast<unsigned int>(iter->size()) + 1; + } + + return size; + } + + /** + * @param strFilename Name of the file. + * @param dwOffset File offset the bound importdirectory will be written to. + * @param fMakeValid If this flag is true a valid directory will be produced. + **/ + int BoundImportDirectory::write(const std::string& strFilename, dword dwOffset, bool fMakeValid) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(dwOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + rebuild(vBuffer, fMakeValid); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<std::streamsize>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } + + /** + * Retrieves the value of the TimeDateStamp value of a bound import field. + * @param dwBidnr Number of the bound import field. + * @return Value of the TimeDateStamp of the bound import field. + **/ + dword BoundImportDirectory::getTimeDateStamp(dword dwBidnr) const + { + return m_vIbd[dwBidnr].ibdDescriptor.TimeDateStamp; + } + + /** + * Retrieves the value of the OffsetModuleName value of a bound import field. + * @param dwBidnr Number of the bound import field. + * @return Value of the OffsetModuleName of the bound import field. + **/ + word BoundImportDirectory::getOffsetModuleName(dword dwBidnr) const + { + return m_vIbd[dwBidnr].ibdDescriptor.OffsetModuleName; + } + + /** + * Retrieves the value of the NumberOfModuleForwarderRefs value of a bound import field. + * @param dwBidnr Number of the bound import field. + * @return Value of the NumberOfModuleForwarderRefs of the bound import field. + **/ + word BoundImportDirectory::getNumberOfModuleForwarderRefs(dword dwBidnr) const + { + return m_vIbd[dwBidnr].ibdDescriptor.NumberOfModuleForwarderRefs; + } + + /** + * Retrieves the value of the ModuleName value of a bound import field. + * @param dwBidnr Number of the bound import field. + * @return Value of the ModuleName of the bound import field. + **/ + std::string BoundImportDirectory::getModuleName(dword dwBidnr) const + { + return m_vIbd[dwBidnr].strModuleName; + } + + /** + * Changes the TimeDateStamp value of an existing bound import field. + * @param dwBidnr Number of the bound import field which will be changed. + * @param dwTds New value of the TimeDateStamp of the bound import field. + **/ + void BoundImportDirectory::setTimeDateStamp(dword dwBidnr, dword dwTds) + { + m_vIbd[dwBidnr].ibdDescriptor.TimeDateStamp = dwTds; + } + + /** + * Changes the OffsetModuleName value of an existing bound import field. + * @param dwBidnr Number of the bound import field which will be changed. + * @param wOmn New value of the OffsetModuleName of the bound import field. + **/ + void BoundImportDirectory::setOffsetModuleName(dword dwBidnr, word wOmn) + { + m_vIbd[dwBidnr].ibdDescriptor.OffsetModuleName = wOmn; + } + + /** + * Changes the NumberOfModuleForwarderRefs value of an existing bound import field. + * @param dwBidnr Number of the bound import field which will be changed. + * @param wMfr New value of the NumberOfModuleForwarderRefs of the bound import field. + **/ + void BoundImportDirectory::setNumberOfModuleForwarderRefs(dword dwBidnr, word wMfr) + { + m_vIbd[dwBidnr].ibdDescriptor.NumberOfModuleForwarderRefs = wMfr; + } + + /** + * Changes the ModuleName value of an existing bound import field. + * @param dwBidnr Number of the bound import field which will be changed. + * @param strModuleName New value of the ModuleName of the bound import field. + **/ + void BoundImportDirectory::setModuleName(dword dwBidnr, const std::string& strModuleName) + { + m_vIbd[dwBidnr].strModuleName = strModuleName; + } + + dword BoundImportDirectory::getTimeDateStamp(dword dwBidnr, dword forwardedModule) const + { + return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.TimeDateStamp; + } + + word BoundImportDirectory::getOffsetModuleName(dword dwBidnr, dword forwardedModule) const + { + return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.OffsetModuleName; + } + + word BoundImportDirectory::getNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule) const + { + return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.NumberOfModuleForwarderRefs; + } + + std::string BoundImportDirectory::getModuleName(dword dwBidnr, dword forwardedModule) const + { + return m_vIbd[dwBidnr].moduleForwarders[forwardedModule].strModuleName; + } + + void BoundImportDirectory::setTimeDateStamp(dword dwBidnr, dword forwardedModule, dword dwTds) + { + m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.TimeDateStamp = dwTds; + } + + void BoundImportDirectory::setOffsetModuleName(dword dwBidnr, dword forwardedModule, word wOmn) + { + m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.OffsetModuleName = wOmn; + } + + void BoundImportDirectory::setNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule, word wMfr) + { + m_vIbd[dwBidnr].moduleForwarders[forwardedModule].ibdDescriptor.NumberOfModuleForwarderRefs = wMfr; + } + + void BoundImportDirectory::setModuleName(dword dwBidnr, dword forwardedModule, const std::string& strModuleName) + { + m_vIbd[dwBidnr].moduleForwarders[forwardedModule].strModuleName = strModuleName; + } + + word BoundImportDirectory::calcNumberOfModuleForwarderRefs(dword dwBidnr) const + { + return static_cast<word>(m_vIbd[dwBidnr].moduleForwarders.size()); + } + + void BoundImportDirectory::addForwardedModule(dword dwBidnr, const std::string& name, dword timeStamp, word offsetModuleName, word forwardedModules) + { + // XXX: Maybe test if there are already 0xFFFF forwarded modules. + // XXX: Check for duplicate entries. Is it also necessary to check + // non-forwarded entries and forwarded entries in other non-forwarded + // entries? + // XXX: Can forwarders forward recursively? + + PELIB_IMAGE_BOUND_DIRECTORY ibdCurrent; + ibdCurrent.strModuleName = name; + ibdCurrent.ibdDescriptor.TimeDateStamp = timeStamp; + ibdCurrent.ibdDescriptor.OffsetModuleName = offsetModuleName; + ibdCurrent.ibdDescriptor.NumberOfModuleForwarderRefs = forwardedModules; + + m_vIbd[dwBidnr].moduleForwarders.push_back(ibdCurrent); + } + + void BoundImportDirectory::removeForwardedModule(dword dwBidnr, word forwardedModule) + { + m_vIbd[dwBidnr].moduleForwarders.erase(m_vIbd[dwBidnr].moduleForwarders.begin() + forwardedModule); + } +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.h index fd2bab56fd..142d78f710 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/BoundImportDirectory.h @@ -1,87 +1,87 @@ -/*
-* BoundImportDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef BOUNDIMPORTDIRECTORY_H
-#define BOUNDIMPORTDIRECTORY_H
-
-#include "PeLibAux.h"
-
-namespace PeLib
-{
- /// Class that handles the BoundImport directory.
- /**
- * This class can read and modify the BoundImport directory table of a PE file.
- **/
- class BoundImportDirectory
- {
- private:
- std::vector<PELIB_IMAGE_BOUND_DIRECTORY> m_vIbd; ///< Stores the individual BoundImport fields.
-
- int read(InputBuffer& inpBuffer, unsigned char* data, unsigned int dwSize);
- unsigned int totalModules() const;
- public:
- /// Adds another bound import.
- int addBoundImport(const std::string& strModuleName, dword dwTds, word dwOmn, word wWfr); // EXPORT
- /// Identifies a module through it's name.
- int getModuleIndex(const std::string& strModuleName) const; // EXPORT
- /// Returns the number of files in the BoundImport directory.
- unsigned int calcNumberOfModules() const; // EXPORT
- /// Reads the BoundImport directory table from a PE file.
- int read(const std::string& strFileName, dword dwOffset, unsigned int uiSize); // EXPORT
- int read(unsigned char* pcBuffer, unsigned int uiSize); // EXPORT
- /// Rebuilds the BoundImport directory.
- void rebuild(std::vector<byte>& vBuffer, bool fMakeValid = true) const; // EXPORT
- /// Empties the BoundImport directory.
- void clear(); // EXPORT
- /// Removes a bound import.
- void removeBoundImport(const std::string& strModuleName); // EXPORT
- /// Returns the size of the BoundImport directory.
- unsigned int size() const; // EXPORT
- /// Writes the current bound import directory to a file.
- int write(const std::string& strFilename, dword dwOffset, bool fMakeValid = true) const; // EXPORT
-
- /// Retrieves the TimeDateStamp value of a bound import.
- dword getTimeDateStamp(dword dwBidnr) const; // EXPORT
- /// Retrieves the OffsetModuleName value of a bound import.
- word getOffsetModuleName(dword dwBidnr) const; // EXPORT
- /// Retrieves the NumberOfModuleForwarderRefs value of a bound import.
- word getNumberOfModuleForwarderRefs(dword dwBidnr) const; // EXPORT
- /// Retrieves the ModuleName value of a bound import.
- std::string getModuleName(dword dwBidnr) const; // EXPORT
-
- /// Updates the TimeDateStamp value of a bound import.
- void setTimeDateStamp(dword dwBidnr, dword dwTds); // EXPORT
- /// Updates the OffsetModuleName value of a bound import.
- void setOffsetModuleName(dword dwBidnr, word wOmn); // EXPORT
- /// Updates the NumberOfModuleForwarderRefs value of a bound import.
- void setNumberOfModuleForwarderRefs(dword dwBidnr, word wMfr); // EXPORT
- /// Updates the ModuleName value of a bound import.
- void setModuleName(dword dwBidnr, const std::string& strModuleName); // EXPORT
-
- dword getTimeDateStamp(dword dwBidnr, dword forwardedModule) const; // EXPORT _module
- word getOffsetModuleName(dword dwBidnr, dword forwardedModule) const; // EXPORT _module
- word getNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule) const; // EXPORT _module
- std::string getModuleName(dword dwBidnr, dword forwardedModule) const; // EXPORT _module
-
- void setTimeDateStamp(dword dwBidnr, dword forwardedModule, dword dwTds); // EXPORT _module
- void setOffsetModuleName(dword dwBidnr, dword forwardedModule, word wOmn); // EXPORT _module
- void setNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule, word wMfr); // EXPORT _module
- void setModuleName(dword dwBidnr, dword forwardedModule, const std::string& strModuleName); // EXPORT _module
-
- word calcNumberOfModuleForwarderRefs(dword dwBidnr) const; // EXPORT
- void addForwardedModule(dword dwBidnr, const std::string& name, dword timeStamp = 0, word offsetModuleName = 0, word forwardedModules = 0); // EXPORT
- void removeForwardedModule(dword dwBidnr, word forwardedModule); // EXPORT
- };
-}
-
-
-#endif
+/* +* BoundImportDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef BOUNDIMPORTDIRECTORY_H +#define BOUNDIMPORTDIRECTORY_H + +#include "PeLibAux.h" + +namespace PeLib +{ + /// Class that handles the BoundImport directory. + /** + * This class can read and modify the BoundImport directory table of a PE file. + **/ + class BoundImportDirectory + { + private: + std::vector<PELIB_IMAGE_BOUND_DIRECTORY> m_vIbd; ///< Stores the individual BoundImport fields. + + int read(InputBuffer& inpBuffer, unsigned char* data, unsigned int dwSize); + unsigned int totalModules() const; + public: + /// Adds another bound import. + int addBoundImport(const std::string& strModuleName, dword dwTds, word dwOmn, word wWfr); // EXPORT + /// Identifies a module through it's name. + int getModuleIndex(const std::string& strModuleName) const; // EXPORT + /// Returns the number of files in the BoundImport directory. + unsigned int calcNumberOfModules() const; // EXPORT + /// Reads the BoundImport directory table from a PE file. + int read(const std::string& strFileName, dword dwOffset, unsigned int uiSize); // EXPORT + int read(unsigned char* pcBuffer, unsigned int uiSize); // EXPORT + /// Rebuilds the BoundImport directory. + void rebuild(std::vector<byte>& vBuffer, bool fMakeValid = true) const; // EXPORT + /// Empties the BoundImport directory. + void clear(); // EXPORT + /// Removes a bound import. + void removeBoundImport(const std::string& strModuleName); // EXPORT + /// Returns the size of the BoundImport directory. + unsigned int size() const; // EXPORT + /// Writes the current bound import directory to a file. + int write(const std::string& strFilename, dword dwOffset, bool fMakeValid = true) const; // EXPORT + + /// Retrieves the TimeDateStamp value of a bound import. + dword getTimeDateStamp(dword dwBidnr) const; // EXPORT + /// Retrieves the OffsetModuleName value of a bound import. + word getOffsetModuleName(dword dwBidnr) const; // EXPORT + /// Retrieves the NumberOfModuleForwarderRefs value of a bound import. + word getNumberOfModuleForwarderRefs(dword dwBidnr) const; // EXPORT + /// Retrieves the ModuleName value of a bound import. + std::string getModuleName(dword dwBidnr) const; // EXPORT + + /// Updates the TimeDateStamp value of a bound import. + void setTimeDateStamp(dword dwBidnr, dword dwTds); // EXPORT + /// Updates the OffsetModuleName value of a bound import. + void setOffsetModuleName(dword dwBidnr, word wOmn); // EXPORT + /// Updates the NumberOfModuleForwarderRefs value of a bound import. + void setNumberOfModuleForwarderRefs(dword dwBidnr, word wMfr); // EXPORT + /// Updates the ModuleName value of a bound import. + void setModuleName(dword dwBidnr, const std::string& strModuleName); // EXPORT + + dword getTimeDateStamp(dword dwBidnr, dword forwardedModule) const; // EXPORT _module + word getOffsetModuleName(dword dwBidnr, dword forwardedModule) const; // EXPORT _module + word getNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule) const; // EXPORT _module + std::string getModuleName(dword dwBidnr, dword forwardedModule) const; // EXPORT _module + + void setTimeDateStamp(dword dwBidnr, dword forwardedModule, dword dwTds); // EXPORT _module + void setOffsetModuleName(dword dwBidnr, dword forwardedModule, word wOmn); // EXPORT _module + void setNumberOfModuleForwarderRefs(dword dwBidnr, dword forwardedModule, word wMfr); // EXPORT _module + void setModuleName(dword dwBidnr, dword forwardedModule, const std::string& strModuleName); // EXPORT _module + + word calcNumberOfModuleForwarderRefs(dword dwBidnr) const; // EXPORT + void addForwardedModule(dword dwBidnr, const std::string& name, dword timeStamp = 0, word offsetModuleName = 0, word forwardedModules = 0); // EXPORT + void removeForwardedModule(dword dwBidnr, word forwardedModule); // EXPORT + }; +} + + +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.cpp index 886348994e..fef12f4d8b 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.cpp @@ -1,467 +1,467 @@ -/*
-* ComHeaderDirectory.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "PeLibInc.h"
-#include "ComHeaderDirectory.h"
-
-namespace PeLib
-{
- void ComHeaderDirectory::read(InputBuffer& inputbuffer)
- {
- PELIB_IMAGE_COR20_HEADER ichCurr;
-
- inputbuffer >> ichCurr.cb;
- inputbuffer >> ichCurr.MajorRuntimeVersion;
- inputbuffer >> ichCurr.MinorRuntimeVersion;
- inputbuffer >> ichCurr.MetaData.VirtualAddress;
- inputbuffer >> ichCurr.MetaData.Size;
- inputbuffer >> ichCurr.Flags;
- inputbuffer >> ichCurr.EntryPointToken;
- inputbuffer >> ichCurr.Resources.VirtualAddress;
- inputbuffer >> ichCurr.Resources.Size;
- inputbuffer >> ichCurr.StrongNameSignature.VirtualAddress;
- inputbuffer >> ichCurr.StrongNameSignature.Size;
- inputbuffer >> ichCurr.CodeManagerTable.VirtualAddress;
- inputbuffer >> ichCurr.CodeManagerTable.Size;
- inputbuffer >> ichCurr.VTableFixups.VirtualAddress;
- inputbuffer >> ichCurr.VTableFixups.Size;
- inputbuffer >> ichCurr.ExportAddressTableJumps.VirtualAddress;
- inputbuffer >> ichCurr.ExportAddressTableJumps.Size;
- inputbuffer >> ichCurr.ManagedNativeHeader.VirtualAddress;
- inputbuffer >> ichCurr.ManagedNativeHeader.Size;
-
- std::swap(ichCurr, m_ichComHeader);
- }
-
- int ComHeaderDirectory::read(unsigned char* buffer, unsigned int buffersize)
- {
- if (buffersize < PELIB_IMAGE_COR20_HEADER::size())
- {
- return ERROR_INVALID_FILE;
- }
-
- std::vector<byte> vComDescDirectory(buffer, buffer + buffersize);
-
- InputBuffer ibBuffer(vComDescDirectory);
- read(ibBuffer);
- return NO_ERROR;
- }
-
- /**
- * Reads a file's COM+ descriptor.
- * @param strFilename Name of the file.
- * @param uiOffset File offset of the COM+ descriptor.
- * @param uiSize Size of the COM+ descriptor.
- **/
- int ComHeaderDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios::binary);
- unsigned int ulFileSize = fileSize(ifFile);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- if (ulFileSize < uiOffset + uiSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(uiOffset, std::ios::beg);
-
- std::vector<byte> vComDescDirectory(uiSize);
- ifFile.read(reinterpret_cast<char*>(&vComDescDirectory[0]), uiSize);
-
- InputBuffer ibBuffer(vComDescDirectory);
- read(ibBuffer);
- return NO_ERROR;
- }
-
- /**
- * Rebuilds the current COM+ descriptor.
- * @param vBuffer Buffer where the COM+ descriptor will be written to.
- **/
- void ComHeaderDirectory::rebuild(std::vector<byte>& vBuffer) const
- {
- OutputBuffer obBuffer(vBuffer);
-
- obBuffer << m_ichComHeader.cb;
- obBuffer << m_ichComHeader.MajorRuntimeVersion;
- obBuffer << m_ichComHeader.MinorRuntimeVersion;
- obBuffer << m_ichComHeader.MetaData.VirtualAddress;
- obBuffer << m_ichComHeader.MetaData.Size;
- obBuffer << m_ichComHeader.Flags;
- obBuffer << m_ichComHeader.EntryPointToken;
- obBuffer << m_ichComHeader.Resources.VirtualAddress;
- obBuffer << m_ichComHeader.Resources.Size;
- obBuffer << m_ichComHeader.StrongNameSignature.VirtualAddress;
- obBuffer << m_ichComHeader.StrongNameSignature.Size;
- obBuffer << m_ichComHeader.CodeManagerTable.VirtualAddress;
- obBuffer << m_ichComHeader.CodeManagerTable.Size;
- obBuffer << m_ichComHeader.VTableFixups.VirtualAddress;
- obBuffer << m_ichComHeader.VTableFixups.Size;
- obBuffer << m_ichComHeader.ExportAddressTableJumps.VirtualAddress;
- obBuffer << m_ichComHeader.ExportAddressTableJumps.Size;
- obBuffer << m_ichComHeader.ManagedNativeHeader.VirtualAddress;
- obBuffer << m_ichComHeader.ManagedNativeHeader.Size;
- }
-
- /**
- * @return Size in bytes.
- **/
- unsigned int ComHeaderDirectory::size() const
- {
- return PELIB_IMAGE_COR20_HEADER::size();
- }
-
- /**
- * @param strFilename Name of the file.
- * @param dwOffset File offset the COM+ descriptor will be written to.
- **/
- int ComHeaderDirectory::write(const std::string& strFilename, unsigned int dwOffset) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(dwOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
- rebuild(vBuffer);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-
- /**
- * @return SizeOfHeader value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getSizeOfHeader() const
- {
- return m_ichComHeader.cb;
- }
-
- /**
- * @return MajorRuntimeVersion value of the current COM+ descriptor.
- **/
- word ComHeaderDirectory::getMajorRuntimeVersion() const
- {
- return m_ichComHeader.MajorRuntimeVersion;
- }
-
- /**
- * @return MinorRuntimeVersion value of the current COM+ descriptor.
- **/
- word ComHeaderDirectory::getMinorRuntimeVersion() const
- {
- return m_ichComHeader.MinorRuntimeVersion;
- }
-
- /**
- * @return MetaData (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getMetaDataVa() const
- {
- return m_ichComHeader.MetaData.VirtualAddress;
- }
-
- /**
- * @return MetaData (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getMetaDataSize() const
- {
- return m_ichComHeader.MetaData.Size;
- }
-
- /**
- * @return Flags value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getFlags() const
- {
- return m_ichComHeader.Flags;
- }
-
- /**
- * @return EntryPointToken value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getEntryPointToken() const
- {
- return m_ichComHeader.EntryPointToken;
- }
-
- /**
- * @return Resources (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getResourcesVa() const
- {
- return m_ichComHeader.Resources.VirtualAddress;
- }
-
- /**
- * @return Resources (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getResourcesSize()
- {
- return m_ichComHeader.Resources.Size;
- }
-
- /**
- * @return StrongNameSignature (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getStrongNameSignatureVa() const
- {
- return m_ichComHeader.StrongNameSignature.VirtualAddress;
- }
-
- /**
- * @return StrongNameSignature (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getStrongNameSignagureSize() const
- {
- return m_ichComHeader.StrongNameSignature.Size;
- }
-
- /**
- * @return CodeManagerTable (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getCodeManagerTableVa() const
- {
- return m_ichComHeader.CodeManagerTable.VirtualAddress;
- }
-
- /**
- * @return CodeManagerTable (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getCodeManagerTableSize() const
- {
- return m_ichComHeader.CodeManagerTable.Size;
- }
-
- /**
- * @return VTableFixups (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getVTableFixupsVa() const
- {
- return m_ichComHeader.VTableFixups.VirtualAddress;
- }
-
- /**
- * @return VTableFixups (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getVTableFixupsSize() const
- {
- return m_ichComHeader.VTableFixups.Size;
- }
-
- /**
- * @return ExportAddressTableJumps (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getExportAddressTableJumpsVa() const
- {
- return m_ichComHeader.ExportAddressTableJumps.VirtualAddress;
- }
-
- /**
- * @return ExportAddressTableJumps (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getExportAddressTableJumpsSize() const
- {
- return m_ichComHeader.ExportAddressTableJumps.Size;
- }
-
- /**
- * @return ManagedNativeHeader (Virtual Address) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getManagedNativeHeaderVa() const
- {
- return m_ichComHeader.ManagedNativeHeader.VirtualAddress;
- }
-
- /**
- * @return ManagedNativeHeader (Size) value of the current COM+ descriptor.
- **/
- dword ComHeaderDirectory::getManagedNativeHeaderSize() const
- {
- return m_ichComHeader.ManagedNativeHeader.Size;
- }
-
- /**
- * @param dwValue New value for the current SizeOfHeader (cb) value.
- **/
- void ComHeaderDirectory::setSizeOfHeader(dword dwValue)
- {
- m_ichComHeader.cb = dwValue;
- }
-
- /**
- * @param wValue New value for the current MajorRuntimeVersion value.
- **/
- void ComHeaderDirectory::setMajorRuntimeVersion(word wValue)
- {
- m_ichComHeader.MajorRuntimeVersion = wValue;
- }
-
- /**
- * @param wValue New value for the current MinorRuntimeVersion value.
- **/
- void ComHeaderDirectory::setMinorRuntimeVersion(word wValue)
- {
- m_ichComHeader.MinorRuntimeVersion = wValue;
- }
-
- /**
- * @param dwValue New value for the current MetaData (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setMetaDataVa(dword dwValue)
- {
- m_ichComHeader.MetaData.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current MetaData (Size) value.
- **/
- void ComHeaderDirectory::setMetaDataSize(dword dwValue)
- {
- m_ichComHeader.MetaData.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current Flags value.
- **/
- void ComHeaderDirectory::setFlags(dword dwValue)
- {
- m_ichComHeader.Flags = dwValue;
- }
-
- /**
- * @param dwValue New value for the current EntryPointToken value.
- **/
- void ComHeaderDirectory::setEntryPointToken(dword dwValue)
- {
- m_ichComHeader.EntryPointToken = dwValue;
- }
-
- /**
- * @param dwValue New value for the current Resources (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setResourcesVa(dword dwValue)
- {
- m_ichComHeader.Resources.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current Resources (Size) value.
- **/
- void ComHeaderDirectory::setResourcesSize(dword dwValue)
- {
- m_ichComHeader.Resources.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current StrongNameSignature (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setStrongNameSignatureVa(dword dwValue)
- {
- m_ichComHeader.StrongNameSignature.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current StrongNameSignature (Size) value.
- **/
- void ComHeaderDirectory::setStrongNameSignagureSize(dword dwValue)
- {
- m_ichComHeader.StrongNameSignature.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current CodeManagerTable (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setCodeManagerTableVa(dword dwValue)
- {
- m_ichComHeader.CodeManagerTable.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current CodeManagerTable (Size) value.
- **/
- void ComHeaderDirectory::setCodeManagerTableSize(dword dwValue)
- {
- m_ichComHeader.CodeManagerTable.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current VTableFixups (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setVTableFixupsVa(dword dwValue)
- {
- m_ichComHeader.VTableFixups.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current VTableFixups (Size) value.
- **/
- void ComHeaderDirectory::setVTableFixupsSize(dword dwValue)
- {
- m_ichComHeader.VTableFixups.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current ExportAddressTableJumps (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setExportAddressTableJumpsVa(dword dwValue)
- {
- m_ichComHeader.ExportAddressTableJumps.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current ExportAddressTableJumps (Size) value.
- **/
- void ComHeaderDirectory::setExportAddressTableJumpsSize(dword dwValue)
- {
- m_ichComHeader.ExportAddressTableJumps.Size = dwValue;
- }
-
- /**
- * @param dwValue New value for the current ManagedNativeHeader (VirtualAddress) value.
- **/
- void ComHeaderDirectory::setManagedNativeHeaderVa(dword dwValue)
- {
- m_ichComHeader.ManagedNativeHeader.VirtualAddress = dwValue;
- }
-
- /**
- * @param dwValue New value for the current ManagedNativeHeader (Size) value.
- **/
- void ComHeaderDirectory::setManagedNativeHeaderSize(dword dwValue)
- {
- m_ichComHeader.ManagedNativeHeader.Size = dwValue;
- }
-
-}
+/* +* ComHeaderDirectory.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "PeLibInc.h" +#include "ComHeaderDirectory.h" + +namespace PeLib +{ + void ComHeaderDirectory::read(InputBuffer& inputbuffer) + { + PELIB_IMAGE_COR20_HEADER ichCurr; + + inputbuffer >> ichCurr.cb; + inputbuffer >> ichCurr.MajorRuntimeVersion; + inputbuffer >> ichCurr.MinorRuntimeVersion; + inputbuffer >> ichCurr.MetaData.VirtualAddress; + inputbuffer >> ichCurr.MetaData.Size; + inputbuffer >> ichCurr.Flags; + inputbuffer >> ichCurr.EntryPointToken; + inputbuffer >> ichCurr.Resources.VirtualAddress; + inputbuffer >> ichCurr.Resources.Size; + inputbuffer >> ichCurr.StrongNameSignature.VirtualAddress; + inputbuffer >> ichCurr.StrongNameSignature.Size; + inputbuffer >> ichCurr.CodeManagerTable.VirtualAddress; + inputbuffer >> ichCurr.CodeManagerTable.Size; + inputbuffer >> ichCurr.VTableFixups.VirtualAddress; + inputbuffer >> ichCurr.VTableFixups.Size; + inputbuffer >> ichCurr.ExportAddressTableJumps.VirtualAddress; + inputbuffer >> ichCurr.ExportAddressTableJumps.Size; + inputbuffer >> ichCurr.ManagedNativeHeader.VirtualAddress; + inputbuffer >> ichCurr.ManagedNativeHeader.Size; + + std::swap(ichCurr, m_ichComHeader); + } + + int ComHeaderDirectory::read(unsigned char* buffer, unsigned int buffersize) + { + if (buffersize < PELIB_IMAGE_COR20_HEADER::size()) + { + return ERROR_INVALID_FILE; + } + + std::vector<byte> vComDescDirectory(buffer, buffer + buffersize); + + InputBuffer ibBuffer(vComDescDirectory); + read(ibBuffer); + return NO_ERROR; + } + + /** + * Reads a file's COM+ descriptor. + * @param strFilename Name of the file. + * @param uiOffset File offset of the COM+ descriptor. + * @param uiSize Size of the COM+ descriptor. + **/ + int ComHeaderDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize) + { + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + unsigned int ulFileSize = fileSize(ifFile); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + if (ulFileSize < uiOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(uiOffset, std::ios::beg); + + std::vector<byte> vComDescDirectory(uiSize); + ifFile.read(reinterpret_cast<char*>(&vComDescDirectory[0]), uiSize); + + InputBuffer ibBuffer(vComDescDirectory); + read(ibBuffer); + return NO_ERROR; + } + + /** + * Rebuilds the current COM+ descriptor. + * @param vBuffer Buffer where the COM+ descriptor will be written to. + **/ + void ComHeaderDirectory::rebuild(std::vector<byte>& vBuffer) const + { + OutputBuffer obBuffer(vBuffer); + + obBuffer << m_ichComHeader.cb; + obBuffer << m_ichComHeader.MajorRuntimeVersion; + obBuffer << m_ichComHeader.MinorRuntimeVersion; + obBuffer << m_ichComHeader.MetaData.VirtualAddress; + obBuffer << m_ichComHeader.MetaData.Size; + obBuffer << m_ichComHeader.Flags; + obBuffer << m_ichComHeader.EntryPointToken; + obBuffer << m_ichComHeader.Resources.VirtualAddress; + obBuffer << m_ichComHeader.Resources.Size; + obBuffer << m_ichComHeader.StrongNameSignature.VirtualAddress; + obBuffer << m_ichComHeader.StrongNameSignature.Size; + obBuffer << m_ichComHeader.CodeManagerTable.VirtualAddress; + obBuffer << m_ichComHeader.CodeManagerTable.Size; + obBuffer << m_ichComHeader.VTableFixups.VirtualAddress; + obBuffer << m_ichComHeader.VTableFixups.Size; + obBuffer << m_ichComHeader.ExportAddressTableJumps.VirtualAddress; + obBuffer << m_ichComHeader.ExportAddressTableJumps.Size; + obBuffer << m_ichComHeader.ManagedNativeHeader.VirtualAddress; + obBuffer << m_ichComHeader.ManagedNativeHeader.Size; + } + + /** + * @return Size in bytes. + **/ + unsigned int ComHeaderDirectory::size() const + { + return PELIB_IMAGE_COR20_HEADER::size(); + } + + /** + * @param strFilename Name of the file. + * @param dwOffset File offset the COM+ descriptor will be written to. + **/ + int ComHeaderDirectory::write(const std::string& strFilename, unsigned int dwOffset) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(dwOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + rebuild(vBuffer); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } + + /** + * @return SizeOfHeader value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getSizeOfHeader() const + { + return m_ichComHeader.cb; + } + + /** + * @return MajorRuntimeVersion value of the current COM+ descriptor. + **/ + word ComHeaderDirectory::getMajorRuntimeVersion() const + { + return m_ichComHeader.MajorRuntimeVersion; + } + + /** + * @return MinorRuntimeVersion value of the current COM+ descriptor. + **/ + word ComHeaderDirectory::getMinorRuntimeVersion() const + { + return m_ichComHeader.MinorRuntimeVersion; + } + + /** + * @return MetaData (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getMetaDataVa() const + { + return m_ichComHeader.MetaData.VirtualAddress; + } + + /** + * @return MetaData (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getMetaDataSize() const + { + return m_ichComHeader.MetaData.Size; + } + + /** + * @return Flags value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getFlags() const + { + return m_ichComHeader.Flags; + } + + /** + * @return EntryPointToken value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getEntryPointToken() const + { + return m_ichComHeader.EntryPointToken; + } + + /** + * @return Resources (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getResourcesVa() const + { + return m_ichComHeader.Resources.VirtualAddress; + } + + /** + * @return Resources (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getResourcesSize() + { + return m_ichComHeader.Resources.Size; + } + + /** + * @return StrongNameSignature (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getStrongNameSignatureVa() const + { + return m_ichComHeader.StrongNameSignature.VirtualAddress; + } + + /** + * @return StrongNameSignature (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getStrongNameSignagureSize() const + { + return m_ichComHeader.StrongNameSignature.Size; + } + + /** + * @return CodeManagerTable (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getCodeManagerTableVa() const + { + return m_ichComHeader.CodeManagerTable.VirtualAddress; + } + + /** + * @return CodeManagerTable (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getCodeManagerTableSize() const + { + return m_ichComHeader.CodeManagerTable.Size; + } + + /** + * @return VTableFixups (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getVTableFixupsVa() const + { + return m_ichComHeader.VTableFixups.VirtualAddress; + } + + /** + * @return VTableFixups (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getVTableFixupsSize() const + { + return m_ichComHeader.VTableFixups.Size; + } + + /** + * @return ExportAddressTableJumps (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getExportAddressTableJumpsVa() const + { + return m_ichComHeader.ExportAddressTableJumps.VirtualAddress; + } + + /** + * @return ExportAddressTableJumps (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getExportAddressTableJumpsSize() const + { + return m_ichComHeader.ExportAddressTableJumps.Size; + } + + /** + * @return ManagedNativeHeader (Virtual Address) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getManagedNativeHeaderVa() const + { + return m_ichComHeader.ManagedNativeHeader.VirtualAddress; + } + + /** + * @return ManagedNativeHeader (Size) value of the current COM+ descriptor. + **/ + dword ComHeaderDirectory::getManagedNativeHeaderSize() const + { + return m_ichComHeader.ManagedNativeHeader.Size; + } + + /** + * @param dwValue New value for the current SizeOfHeader (cb) value. + **/ + void ComHeaderDirectory::setSizeOfHeader(dword dwValue) + { + m_ichComHeader.cb = dwValue; + } + + /** + * @param wValue New value for the current MajorRuntimeVersion value. + **/ + void ComHeaderDirectory::setMajorRuntimeVersion(word wValue) + { + m_ichComHeader.MajorRuntimeVersion = wValue; + } + + /** + * @param wValue New value for the current MinorRuntimeVersion value. + **/ + void ComHeaderDirectory::setMinorRuntimeVersion(word wValue) + { + m_ichComHeader.MinorRuntimeVersion = wValue; + } + + /** + * @param dwValue New value for the current MetaData (VirtualAddress) value. + **/ + void ComHeaderDirectory::setMetaDataVa(dword dwValue) + { + m_ichComHeader.MetaData.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current MetaData (Size) value. + **/ + void ComHeaderDirectory::setMetaDataSize(dword dwValue) + { + m_ichComHeader.MetaData.Size = dwValue; + } + + /** + * @param dwValue New value for the current Flags value. + **/ + void ComHeaderDirectory::setFlags(dword dwValue) + { + m_ichComHeader.Flags = dwValue; + } + + /** + * @param dwValue New value for the current EntryPointToken value. + **/ + void ComHeaderDirectory::setEntryPointToken(dword dwValue) + { + m_ichComHeader.EntryPointToken = dwValue; + } + + /** + * @param dwValue New value for the current Resources (VirtualAddress) value. + **/ + void ComHeaderDirectory::setResourcesVa(dword dwValue) + { + m_ichComHeader.Resources.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current Resources (Size) value. + **/ + void ComHeaderDirectory::setResourcesSize(dword dwValue) + { + m_ichComHeader.Resources.Size = dwValue; + } + + /** + * @param dwValue New value for the current StrongNameSignature (VirtualAddress) value. + **/ + void ComHeaderDirectory::setStrongNameSignatureVa(dword dwValue) + { + m_ichComHeader.StrongNameSignature.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current StrongNameSignature (Size) value. + **/ + void ComHeaderDirectory::setStrongNameSignagureSize(dword dwValue) + { + m_ichComHeader.StrongNameSignature.Size = dwValue; + } + + /** + * @param dwValue New value for the current CodeManagerTable (VirtualAddress) value. + **/ + void ComHeaderDirectory::setCodeManagerTableVa(dword dwValue) + { + m_ichComHeader.CodeManagerTable.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current CodeManagerTable (Size) value. + **/ + void ComHeaderDirectory::setCodeManagerTableSize(dword dwValue) + { + m_ichComHeader.CodeManagerTable.Size = dwValue; + } + + /** + * @param dwValue New value for the current VTableFixups (VirtualAddress) value. + **/ + void ComHeaderDirectory::setVTableFixupsVa(dword dwValue) + { + m_ichComHeader.VTableFixups.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current VTableFixups (Size) value. + **/ + void ComHeaderDirectory::setVTableFixupsSize(dword dwValue) + { + m_ichComHeader.VTableFixups.Size = dwValue; + } + + /** + * @param dwValue New value for the current ExportAddressTableJumps (VirtualAddress) value. + **/ + void ComHeaderDirectory::setExportAddressTableJumpsVa(dword dwValue) + { + m_ichComHeader.ExportAddressTableJumps.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current ExportAddressTableJumps (Size) value. + **/ + void ComHeaderDirectory::setExportAddressTableJumpsSize(dword dwValue) + { + m_ichComHeader.ExportAddressTableJumps.Size = dwValue; + } + + /** + * @param dwValue New value for the current ManagedNativeHeader (VirtualAddress) value. + **/ + void ComHeaderDirectory::setManagedNativeHeaderVa(dword dwValue) + { + m_ichComHeader.ManagedNativeHeader.VirtualAddress = dwValue; + } + + /** + * @param dwValue New value for the current ManagedNativeHeader (Size) value. + **/ + void ComHeaderDirectory::setManagedNativeHeaderSize(dword dwValue) + { + m_ichComHeader.ManagedNativeHeader.Size = dwValue; + } + +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.h index 915813c1cc..cdc993df1f 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ComHeaderDirectory.h @@ -1,120 +1,120 @@ -/*
-* ComHeaderDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef COMHEADERDIRECTORY_H
-#define COMHEADERDIRECTORY_H
-
-namespace PeLib
-{
- /// Class that handles the COM+ descriptor directory.
- /**
- * This class handles the COM+ Descriptor directory which was added to PE files
- * which work with the .NET runtime modules.
- **/
- class ComHeaderDirectory
- {
- private:
- PELIB_IMAGE_COR20_HEADER m_ichComHeader; ///< The COM+ descriptor.
-
- void read(InputBuffer& inputbuffer);
-
- public:
- /// Read a file's COM+ runtime descriptor directory.
- int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize); // EXPORT
- int read(unsigned char* buffer, unsigned int buffersize); // EXPORT
- /// Rebuild the COM+ descriptor.
- void rebuild(std::vector<byte>& vBuffer) const; // EXPORT
- /// Returns the size of the current COM+ descriptor.
- unsigned int size() const; // EXPORT
- /// Writes the current COM+ descriptor directory to a file.
- int write(const std::string& strFilename, unsigned int dwOffset) const; // EXPORT
-
- /// Get the COM+ descriptor's SizeOfHeader (cb) value.
- dword getSizeOfHeader() const; // EXPORT
- /// Get the COM+ descriptor's MajorRuntimeVersion value.
- word getMajorRuntimeVersion() const; // EXPORT
- /// Get the COM+ descriptor's MinorRuntimeVersion value.
- word getMinorRuntimeVersion() const; // EXPORT
- /// Get the COM+ descriptor's MetaData (Virtual Address) value.
- dword getMetaDataVa() const; // EXPORT
- /// Get the COM+ descriptor's MetaData (Size) value.
- dword getMetaDataSize() const; // EXPORT
- /// Get the COM+ descriptor's Flags value.
- dword getFlags() const; // EXPORT
- /// Get the COM+ descriptor's EntryPointToken value.
- dword getEntryPointToken() const; // EXPORT
- /// Get the COM+ descriptor's Resources (Virtual Address) value.
- dword getResourcesVa() const; // EXPORT
- /// Get the COM+ descriptor's Resources (Size) value.
- dword getResourcesSize(); // EXPORT
- /// Get the COM+ descriptor's StrongNameSignature (Virtual Address) value.
- dword getStrongNameSignatureVa() const; // EXPORT
- /// Get the COM+ descriptor's StrongNameSignature (Size) value.
- dword getStrongNameSignagureSize() const; // EXPORT
- /// Get the COM+ descriptor's CodeManagerTable (Virtual Address) value.
- dword getCodeManagerTableVa() const; // EXPORT
- /// Get the COM+ descriptor's CodeManagerTable (Size) value.
- dword getCodeManagerTableSize() const; // EXPORT
- /// Get the COM+ descriptor's VTableFixup (Virtual Address) value.
- dword getVTableFixupsVa() const; // EXPORT
- /// Get the COM+ descriptor's VTableFixup (Size) value.
- dword getVTableFixupsSize() const; // EXPORT
- /// Get the COM+ descriptor's ExportAddressTable (Virtual Address) value.
- dword getExportAddressTableJumpsVa() const; // EXPORT
- /// Get the COM+ descriptor's ExportAddressTable (Size) value.
- dword getExportAddressTableJumpsSize() const; // EXPORT
- /// Get the COM+ descriptor's ManagedNativeHeader (Virtual Address) value.
- dword getManagedNativeHeaderVa() const; // EXPORT
- /// Get the COM+ descriptor's ManagedNativeHeader (Size) value.
- dword getManagedNativeHeaderSize() const; // EXPORT
-
- /// Change the COM+ descriptor's SizeOfHeader (cb) value.
- void setSizeOfHeader(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's MajorRuntimeVersion value.
- void setMajorRuntimeVersion(word wValue); // EXPORT
- /// Change the COM+ descriptor's MinorRuntimeVersion value.
- void setMinorRuntimeVersion(word wValue); // EXPORT
- /// Change the COM+ descriptor's MetaData (VirtualAddress) value.
- void setMetaDataVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's MetaData (Size) value.
- void setMetaDataSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's Flags value.
- void setFlags(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's EntryPointToken value.
- void setEntryPointToken(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's Resources (VirtualAddress) value.
- void setResourcesVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's Resources (Size) value.
- void setResourcesSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's StrongNameSignatureVa (VirtualAddress) value.
- void setStrongNameSignatureVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's StrongNameSignatureVa (Size) value.
- void setStrongNameSignagureSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's CodeManagerTable (VirtualAddress) value.
- void setCodeManagerTableVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's CodeManagerTable (Size) value.
- void setCodeManagerTableSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's VTableFixups (VirtualAddress) value.
- void setVTableFixupsVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's VTableFixups (Size) value.
- void setVTableFixupsSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's ExportAddressTableJumps (VirtualAddress) value.
- void setExportAddressTableJumpsVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's ExportAddressTableJumps (Size) value.
- void setExportAddressTableJumpsSize(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's ManagedNativeHeader (VirtualAddress) value.
- void setManagedNativeHeaderVa(dword dwValue); // EXPORT
- /// Change the COM+ descriptor's ManagedNativeHeader (Size) value.
- void setManagedNativeHeaderSize(dword dwValue); // EXPORT
- };
-}
-#endif
+/* +* ComHeaderDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef COMHEADERDIRECTORY_H +#define COMHEADERDIRECTORY_H + +namespace PeLib +{ + /// Class that handles the COM+ descriptor directory. + /** + * This class handles the COM+ Descriptor directory which was added to PE files + * which work with the .NET runtime modules. + **/ + class ComHeaderDirectory + { + private: + PELIB_IMAGE_COR20_HEADER m_ichComHeader; ///< The COM+ descriptor. + + void read(InputBuffer& inputbuffer); + + public: + /// Read a file's COM+ runtime descriptor directory. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize); // EXPORT + int read(unsigned char* buffer, unsigned int buffersize); // EXPORT + /// Rebuild the COM+ descriptor. + void rebuild(std::vector<byte>& vBuffer) const; // EXPORT + /// Returns the size of the current COM+ descriptor. + unsigned int size() const; // EXPORT + /// Writes the current COM+ descriptor directory to a file. + int write(const std::string& strFilename, unsigned int dwOffset) const; // EXPORT + + /// Get the COM+ descriptor's SizeOfHeader (cb) value. + dword getSizeOfHeader() const; // EXPORT + /// Get the COM+ descriptor's MajorRuntimeVersion value. + word getMajorRuntimeVersion() const; // EXPORT + /// Get the COM+ descriptor's MinorRuntimeVersion value. + word getMinorRuntimeVersion() const; // EXPORT + /// Get the COM+ descriptor's MetaData (Virtual Address) value. + dword getMetaDataVa() const; // EXPORT + /// Get the COM+ descriptor's MetaData (Size) value. + dword getMetaDataSize() const; // EXPORT + /// Get the COM+ descriptor's Flags value. + dword getFlags() const; // EXPORT + /// Get the COM+ descriptor's EntryPointToken value. + dword getEntryPointToken() const; // EXPORT + /// Get the COM+ descriptor's Resources (Virtual Address) value. + dword getResourcesVa() const; // EXPORT + /// Get the COM+ descriptor's Resources (Size) value. + dword getResourcesSize(); // EXPORT + /// Get the COM+ descriptor's StrongNameSignature (Virtual Address) value. + dword getStrongNameSignatureVa() const; // EXPORT + /// Get the COM+ descriptor's StrongNameSignature (Size) value. + dword getStrongNameSignagureSize() const; // EXPORT + /// Get the COM+ descriptor's CodeManagerTable (Virtual Address) value. + dword getCodeManagerTableVa() const; // EXPORT + /// Get the COM+ descriptor's CodeManagerTable (Size) value. + dword getCodeManagerTableSize() const; // EXPORT + /// Get the COM+ descriptor's VTableFixup (Virtual Address) value. + dword getVTableFixupsVa() const; // EXPORT + /// Get the COM+ descriptor's VTableFixup (Size) value. + dword getVTableFixupsSize() const; // EXPORT + /// Get the COM+ descriptor's ExportAddressTable (Virtual Address) value. + dword getExportAddressTableJumpsVa() const; // EXPORT + /// Get the COM+ descriptor's ExportAddressTable (Size) value. + dword getExportAddressTableJumpsSize() const; // EXPORT + /// Get the COM+ descriptor's ManagedNativeHeader (Virtual Address) value. + dword getManagedNativeHeaderVa() const; // EXPORT + /// Get the COM+ descriptor's ManagedNativeHeader (Size) value. + dword getManagedNativeHeaderSize() const; // EXPORT + + /// Change the COM+ descriptor's SizeOfHeader (cb) value. + void setSizeOfHeader(dword dwValue); // EXPORT + /// Change the COM+ descriptor's MajorRuntimeVersion value. + void setMajorRuntimeVersion(word wValue); // EXPORT + /// Change the COM+ descriptor's MinorRuntimeVersion value. + void setMinorRuntimeVersion(word wValue); // EXPORT + /// Change the COM+ descriptor's MetaData (VirtualAddress) value. + void setMetaDataVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's MetaData (Size) value. + void setMetaDataSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's Flags value. + void setFlags(dword dwValue); // EXPORT + /// Change the COM+ descriptor's EntryPointToken value. + void setEntryPointToken(dword dwValue); // EXPORT + /// Change the COM+ descriptor's Resources (VirtualAddress) value. + void setResourcesVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's Resources (Size) value. + void setResourcesSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's StrongNameSignatureVa (VirtualAddress) value. + void setStrongNameSignatureVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's StrongNameSignatureVa (Size) value. + void setStrongNameSignagureSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's CodeManagerTable (VirtualAddress) value. + void setCodeManagerTableVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's CodeManagerTable (Size) value. + void setCodeManagerTableSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's VTableFixups (VirtualAddress) value. + void setVTableFixupsVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's VTableFixups (Size) value. + void setVTableFixupsSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's ExportAddressTableJumps (VirtualAddress) value. + void setExportAddressTableJumpsVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's ExportAddressTableJumps (Size) value. + void setExportAddressTableJumpsSize(dword dwValue); // EXPORT + /// Change the COM+ descriptor's ManagedNativeHeader (VirtualAddress) value. + void setManagedNativeHeaderVa(dword dwValue); // EXPORT + /// Change the COM+ descriptor's ManagedNativeHeader (Size) value. + void setManagedNativeHeaderSize(dword dwValue); // EXPORT + }; +} +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.cpp index eb3d5c5600..9a91c7b18c 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.cpp @@ -1,383 +1,383 @@ -/*
-* DebugDirectory.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "PeLibInc.h"
-#include "DebugDirectory.h"
-
-namespace PeLib
-{
- void DebugDirectory::clear()
- {
- m_vDebugInfo.clear();
- }
-
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> DebugDirectory::read(InputBuffer& ibBuffer, unsigned int uiSize)
- {
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo;
-
- PELIB_IMG_DEBUG_DIRECTORY iddCurr;
-
- for (unsigned int i=0;i<uiSize/PELIB_IMAGE_DEBUG_DIRECTORY::size();i++)
- {
-
- ibBuffer >> iddCurr.idd.Characteristics;
- ibBuffer >> iddCurr.idd.TimeDateStamp;
- ibBuffer >> iddCurr.idd.MajorVersion;
- ibBuffer >> iddCurr.idd.MinorVersion;
- ibBuffer >> iddCurr.idd.Type;
- ibBuffer >> iddCurr.idd.SizeOfData;
- ibBuffer >> iddCurr.idd.AddressOfRawData;
- ibBuffer >> iddCurr.idd.PointerToRawData;
-
- currDebugInfo.push_back(iddCurr);
- }
-
- return currDebugInfo;
- }
-
- int DebugDirectory::read(unsigned char* buffer, unsigned int buffersize)
- {
- // XXX: Note, debug data is not read at all. This might or might not change
- // in the future.
-
- std::vector<byte> vDebugDirectory(buffer, buffer + buffersize);
-
- InputBuffer ibBuffer(vDebugDirectory);
-
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo = read(ibBuffer, buffersize);
-
- std::swap(currDebugInfo, m_vDebugInfo);
-
- return NO_ERROR;
- }
-
- /**
- * @param strFilename Name of the file which will be read.
- * @param uiOffset File offset of the Debug directory.
- * @param uiSize Size of the Debug directory.
- **/
- int DebugDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios::binary);
- unsigned int ulFileSize = fileSize(ifFile);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- if (ulFileSize < uiOffset + uiSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(uiOffset, std::ios::beg);
-
- std::vector<byte> vDebugDirectory(uiSize);
- ifFile.read(reinterpret_cast<char*>(&vDebugDirectory[0]), uiSize);
-
- InputBuffer ibBuffer(vDebugDirectory);
-
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo = read(ibBuffer, uiSize);
-
- for (unsigned int i=0;i<currDebugInfo.size();i++)
- {
- ifFile.seekg(currDebugInfo[i].idd.PointerToRawData, std::ios::beg);
- currDebugInfo[i].data.resize(currDebugInfo[i].idd.SizeOfData);
- ifFile.read(reinterpret_cast<char*>(&currDebugInfo[i].data[0]), currDebugInfo[i].idd.SizeOfData);
- if (!ifFile) return ERROR_INVALID_FILE;
- }
-
- std::swap(currDebugInfo, m_vDebugInfo);
-
- return NO_ERROR;
- }
-
- /**
- * Rebuilds the current debug directory.
- * @param vBuffer Buffer where the rebuilt directory is stored.
- **/
- void DebugDirectory::rebuild(std::vector<byte>& vBuffer) const
- {
- OutputBuffer obBuffer(vBuffer);
-
- for (unsigned int i=0;i<m_vDebugInfo.size();i++)
- {
- obBuffer << m_vDebugInfo[i].idd.Characteristics;
- obBuffer << m_vDebugInfo[i].idd.TimeDateStamp;
- obBuffer << m_vDebugInfo[i].idd.MajorVersion;
- obBuffer << m_vDebugInfo[i].idd.MinorVersion;
- obBuffer << m_vDebugInfo[i].idd.Type;
- obBuffer << m_vDebugInfo[i].idd.SizeOfData;
- obBuffer << m_vDebugInfo[i].idd.AddressOfRawData;
- obBuffer << m_vDebugInfo[i].idd.PointerToRawData;
- }
- }
-
- /**
- * @return Size of the debug directory.
- **/
- unsigned int DebugDirectory::size() const
- {
- return static_cast<unsigned int>(m_vDebugInfo.size()) * PELIB_IMAGE_DEBUG_DIRECTORY::size();
- }
-
- /**
- * @param strFilename Name of the file which will be written.
- * @param uiOffset File offset where the debug directory will be stored.
- **/
- int DebugDirectory::write(const std::string& strFilename, unsigned int uiOffset) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(uiOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
- rebuild(vBuffer);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-
- /**
- * @return Number of debug structures in the current Debug directory.
- **/
- unsigned int DebugDirectory::calcNumberOfEntries() const
- {
- return static_cast<unsigned int>(m_vDebugInfo.size());
- }
-
- /**
- * Adds a new debug structure to the debug directory. The initial values of all members of the structure
- * are undefined.
- **/
- void DebugDirectory::addEntry()
- {
- PELIB_IMG_DEBUG_DIRECTORY p;
- m_vDebugInfo.push_back(p);
- }
-
- /**
- * Removes a debug structure from the current debug directory. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- **/
- void DebugDirectory::removeEntry(unsigned int uiIndex)
- {
- m_vDebugInfo.erase(m_vDebugInfo.begin() + uiIndex);
- }
-
- /**
- * Returns the Characteristics value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return Characteristics value of the debug structure.
- **/
- dword DebugDirectory::getCharacteristics(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.Characteristics;
- }
-
- /**
- * Returns the TimeDateStamp value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return TimeDateStamp value of the debug structure.
- **/
- dword DebugDirectory::getTimeDateStamp(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.TimeDateStamp;
- }
-
- /**
- * Returns the MajorVersion value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return MajorVersion value of the debug structure.
- **/
- word DebugDirectory::getMajorVersion(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.MajorVersion;
- }
-
- /**
- * Returns the MinorVersion value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return MinorVersion value of the debug structure.
- **/
- word DebugDirectory::getMinorVersion(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.MinorVersion;
- }
-
- /**
- * Returns the Type value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return Type value of the debug structure.
- **/
- dword DebugDirectory::getType(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.Type;
- }
-
- /**
- * Returns the SizeOfData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return SizeOfData value of the debug structure.
- **/
- dword DebugDirectory::getSizeOfData(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.SizeOfData;
- }
-
- /**
- * Returns the AddressOfRawData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return AddressOfRawData value of the debug structure.
- **/
- dword DebugDirectory::getAddressOfRawData(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.AddressOfRawData;
- }
-
- /**
- * Returns the PointerToRawData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @return PointerToRawData value of the debug structure.
- **/
- dword DebugDirectory::getPointerToRawData(unsigned int uiIndex) const
- {
- return m_vDebugInfo[uiIndex].idd.PointerToRawData;
- }
-
- std::vector<byte> DebugDirectory::getData(unsigned int index) const
- {
- return m_vDebugInfo[index].data;
- }
-
- /**
- * Changes the Characteristics value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the Characteristics value of the debug structure.
- **/
- void DebugDirectory::setCharacteristics(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.Characteristics = dwValue;
- }
-
- /**
- * Changes the TimeDateStamp value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the TimeDateStamp value of the debug structure.
- **/
- void DebugDirectory::setTimeDateStamp(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.TimeDateStamp = dwValue;
- }
-
- /**
- * Changes the MajorVersion value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param wValue New value of the MajorVersion value of the debug structure.
- **/
- void DebugDirectory::setMajorVersion(unsigned int uiIndex, word wValue)
- {
- m_vDebugInfo[uiIndex].idd.MajorVersion = wValue;
- }
-
- /**
- * Changes the MinorVersion value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param wValue New value of the MinorVersion value of the debug structure.
- **/
- void DebugDirectory::setMinorVersion(unsigned int uiIndex, word wValue)
- {
- m_vDebugInfo[uiIndex].idd.MinorVersion = wValue;
- }
-
- /**
- * Changes the Type value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the Type value of the debug structure.
- **/
- void DebugDirectory::setType(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.Type = dwValue;
- }
-
- /**
- * Changes the SizeOfData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the SizeOfData value of the debug structure.
- **/
- void DebugDirectory::setSizeOfData(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.SizeOfData = dwValue;
- }
-
- /**
- * Changes the AddressOfRawData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the AddressOfRawData value of the debug structure.
- **/
- void DebugDirectory::setAddressOfRawData(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.AddressOfRawData = dwValue;
- }
-
- /**
- * Changes the PointerToRawData value of a debug structure. If an invalid structure is specified
- * by the parameter uiIndex the result will be undefined behaviour.
- * @param uiIndex Identifies the debug structure.
- * @param dwValue New value of the PointerToRawData value of the debug structure.
- **/
- void DebugDirectory::setPointerToRawData(unsigned int uiIndex, dword dwValue)
- {
- m_vDebugInfo[uiIndex].idd.PointerToRawData = dwValue;
- }
-
- void DebugDirectory::setData(unsigned int index, const std::vector<byte>& data)
- {
- m_vDebugInfo[index].data = data;
- }
-}
+/* +* DebugDirectory.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "PeLibInc.h" +#include "DebugDirectory.h" + +namespace PeLib +{ + void DebugDirectory::clear() + { + m_vDebugInfo.clear(); + } + + std::vector<PELIB_IMG_DEBUG_DIRECTORY> DebugDirectory::read(InputBuffer& ibBuffer, unsigned int uiSize) + { + std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo; + + PELIB_IMG_DEBUG_DIRECTORY iddCurr; + + for (unsigned int i=0;i<uiSize/PELIB_IMAGE_DEBUG_DIRECTORY::size();i++) + { + + ibBuffer >> iddCurr.idd.Characteristics; + ibBuffer >> iddCurr.idd.TimeDateStamp; + ibBuffer >> iddCurr.idd.MajorVersion; + ibBuffer >> iddCurr.idd.MinorVersion; + ibBuffer >> iddCurr.idd.Type; + ibBuffer >> iddCurr.idd.SizeOfData; + ibBuffer >> iddCurr.idd.AddressOfRawData; + ibBuffer >> iddCurr.idd.PointerToRawData; + + currDebugInfo.push_back(iddCurr); + } + + return currDebugInfo; + } + + int DebugDirectory::read(unsigned char* buffer, unsigned int buffersize) + { + // XXX: Note, debug data is not read at all. This might or might not change + // in the future. + + std::vector<byte> vDebugDirectory(buffer, buffer + buffersize); + + InputBuffer ibBuffer(vDebugDirectory); + + std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo = read(ibBuffer, buffersize); + + std::swap(currDebugInfo, m_vDebugInfo); + + return NO_ERROR; + } + + /** + * @param strFilename Name of the file which will be read. + * @param uiOffset File offset of the Debug directory. + * @param uiSize Size of the Debug directory. + **/ + int DebugDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize) + { + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + unsigned int ulFileSize = fileSize(ifFile); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + if (ulFileSize < uiOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(uiOffset, std::ios::beg); + + std::vector<byte> vDebugDirectory(uiSize); + ifFile.read(reinterpret_cast<char*>(&vDebugDirectory[0]), uiSize); + + InputBuffer ibBuffer(vDebugDirectory); + + std::vector<PELIB_IMG_DEBUG_DIRECTORY> currDebugInfo = read(ibBuffer, uiSize); + + for (unsigned int i=0;i<currDebugInfo.size();i++) + { + ifFile.seekg(currDebugInfo[i].idd.PointerToRawData, std::ios::beg); + currDebugInfo[i].data.resize(currDebugInfo[i].idd.SizeOfData); + ifFile.read(reinterpret_cast<char*>(&currDebugInfo[i].data[0]), currDebugInfo[i].idd.SizeOfData); + if (!ifFile) return ERROR_INVALID_FILE; + } + + std::swap(currDebugInfo, m_vDebugInfo); + + return NO_ERROR; + } + + /** + * Rebuilds the current debug directory. + * @param vBuffer Buffer where the rebuilt directory is stored. + **/ + void DebugDirectory::rebuild(std::vector<byte>& vBuffer) const + { + OutputBuffer obBuffer(vBuffer); + + for (unsigned int i=0;i<m_vDebugInfo.size();i++) + { + obBuffer << m_vDebugInfo[i].idd.Characteristics; + obBuffer << m_vDebugInfo[i].idd.TimeDateStamp; + obBuffer << m_vDebugInfo[i].idd.MajorVersion; + obBuffer << m_vDebugInfo[i].idd.MinorVersion; + obBuffer << m_vDebugInfo[i].idd.Type; + obBuffer << m_vDebugInfo[i].idd.SizeOfData; + obBuffer << m_vDebugInfo[i].idd.AddressOfRawData; + obBuffer << m_vDebugInfo[i].idd.PointerToRawData; + } + } + + /** + * @return Size of the debug directory. + **/ + unsigned int DebugDirectory::size() const + { + return static_cast<unsigned int>(m_vDebugInfo.size()) * PELIB_IMAGE_DEBUG_DIRECTORY::size(); + } + + /** + * @param strFilename Name of the file which will be written. + * @param uiOffset File offset where the debug directory will be stored. + **/ + int DebugDirectory::write(const std::string& strFilename, unsigned int uiOffset) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + rebuild(vBuffer); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } + + /** + * @return Number of debug structures in the current Debug directory. + **/ + unsigned int DebugDirectory::calcNumberOfEntries() const + { + return static_cast<unsigned int>(m_vDebugInfo.size()); + } + + /** + * Adds a new debug structure to the debug directory. The initial values of all members of the structure + * are undefined. + **/ + void DebugDirectory::addEntry() + { + PELIB_IMG_DEBUG_DIRECTORY p; + m_vDebugInfo.push_back(p); + } + + /** + * Removes a debug structure from the current debug directory. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + **/ + void DebugDirectory::removeEntry(unsigned int uiIndex) + { + m_vDebugInfo.erase(m_vDebugInfo.begin() + uiIndex); + } + + /** + * Returns the Characteristics value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return Characteristics value of the debug structure. + **/ + dword DebugDirectory::getCharacteristics(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.Characteristics; + } + + /** + * Returns the TimeDateStamp value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return TimeDateStamp value of the debug structure. + **/ + dword DebugDirectory::getTimeDateStamp(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.TimeDateStamp; + } + + /** + * Returns the MajorVersion value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return MajorVersion value of the debug structure. + **/ + word DebugDirectory::getMajorVersion(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.MajorVersion; + } + + /** + * Returns the MinorVersion value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return MinorVersion value of the debug structure. + **/ + word DebugDirectory::getMinorVersion(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.MinorVersion; + } + + /** + * Returns the Type value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return Type value of the debug structure. + **/ + dword DebugDirectory::getType(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.Type; + } + + /** + * Returns the SizeOfData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return SizeOfData value of the debug structure. + **/ + dword DebugDirectory::getSizeOfData(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.SizeOfData; + } + + /** + * Returns the AddressOfRawData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return AddressOfRawData value of the debug structure. + **/ + dword DebugDirectory::getAddressOfRawData(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.AddressOfRawData; + } + + /** + * Returns the PointerToRawData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @return PointerToRawData value of the debug structure. + **/ + dword DebugDirectory::getPointerToRawData(unsigned int uiIndex) const + { + return m_vDebugInfo[uiIndex].idd.PointerToRawData; + } + + std::vector<byte> DebugDirectory::getData(unsigned int index) const + { + return m_vDebugInfo[index].data; + } + + /** + * Changes the Characteristics value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the Characteristics value of the debug structure. + **/ + void DebugDirectory::setCharacteristics(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.Characteristics = dwValue; + } + + /** + * Changes the TimeDateStamp value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the TimeDateStamp value of the debug structure. + **/ + void DebugDirectory::setTimeDateStamp(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.TimeDateStamp = dwValue; + } + + /** + * Changes the MajorVersion value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param wValue New value of the MajorVersion value of the debug structure. + **/ + void DebugDirectory::setMajorVersion(unsigned int uiIndex, word wValue) + { + m_vDebugInfo[uiIndex].idd.MajorVersion = wValue; + } + + /** + * Changes the MinorVersion value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param wValue New value of the MinorVersion value of the debug structure. + **/ + void DebugDirectory::setMinorVersion(unsigned int uiIndex, word wValue) + { + m_vDebugInfo[uiIndex].idd.MinorVersion = wValue; + } + + /** + * Changes the Type value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the Type value of the debug structure. + **/ + void DebugDirectory::setType(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.Type = dwValue; + } + + /** + * Changes the SizeOfData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the SizeOfData value of the debug structure. + **/ + void DebugDirectory::setSizeOfData(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.SizeOfData = dwValue; + } + + /** + * Changes the AddressOfRawData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the AddressOfRawData value of the debug structure. + **/ + void DebugDirectory::setAddressOfRawData(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.AddressOfRawData = dwValue; + } + + /** + * Changes the PointerToRawData value of a debug structure. If an invalid structure is specified + * by the parameter uiIndex the result will be undefined behaviour. + * @param uiIndex Identifies the debug structure. + * @param dwValue New value of the PointerToRawData value of the debug structure. + **/ + void DebugDirectory::setPointerToRawData(unsigned int uiIndex, dword dwValue) + { + m_vDebugInfo[uiIndex].idd.PointerToRawData = dwValue; + } + + void DebugDirectory::setData(unsigned int index, const std::vector<byte>& data) + { + m_vDebugInfo[index].data = data; + } +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.h index 0ffda38815..adfef6b52e 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/DebugDirectory.h @@ -1,84 +1,84 @@ -/*
-* DebugDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef DEBUGDIRECTORY_H
-#define DEBUGDIRECTORY_H
-
-namespace PeLib
-{
- /// Class that handles the Debug directory.
- class DebugDirectory
- {
- private:
- /// Stores the various DebugDirectory structures.
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> m_vDebugInfo;
-
- std::vector<PELIB_IMG_DEBUG_DIRECTORY> read(InputBuffer& ibBuffer, unsigned int uiSize);
-
- public:
- void clear(); // EXPORT
- /// Reads the Debug directory from a file.
- int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize); // EXPORT
- int read(unsigned char* buffer, unsigned int buffersize);
- /// Rebuilds the current Debug directory.
- void rebuild(std::vector<byte>& obBuffer) const; // EXPORT
- /// Returns the size the current Debug directory needs after rebuilding.
- unsigned int size() const;
- /// Writes the current Debug directory back to a file.
- int write(const std::string& strFilename, unsigned int uiOffset) const; // EXPORT
-
- /// Returns the number of DebugDirectory image structures in the current DebugDirectory.
- unsigned int calcNumberOfEntries() const; // EXPORT
-
- /// Adds a new debug structure.
- void addEntry(); // EXPORT
- /// Removes a debug structure.
- void removeEntry(unsigned int uiIndex); // EXPORT
-
- /// Returns the Characteristics value of a debug structure.
- dword getCharacteristics(unsigned int uiIndex) const; // EXPORT
- /// Returns the TimeDateStamp value of a debug structure.
- dword getTimeDateStamp(unsigned int uiIndex) const; // EXPORT
- /// Returns the MajorVersion value of a debug structure.
- word getMajorVersion(unsigned int uiIndex) const; // EXPORT
- /// Returns the MinorVersion value of a debug structure.
- word getMinorVersion(unsigned int uiIndex) const; // EXPORT
- /// Returns the Type value of a debug structure.
- dword getType(unsigned int uiIndex) const; // EXPORT
- /// Returns the SizeOfData value of a debug structure.
- dword getSizeOfData(unsigned int uiIndex) const; // EXPORT
- /// Returns the AddressOfRawData value of a debug structure.
- dword getAddressOfRawData(unsigned int uiIndex) const; // EXPORT
- /// Returns the PointerToRawData value of a debug structure.
- dword getPointerToRawData(unsigned int uiIndex) const; // EXPORT
- std::vector<byte> getData(unsigned int index) const; // EXPORT
-
- /// Sets the Characteristics value of a debug structure.
- void setCharacteristics(unsigned int uiIndex, dword dwValue); // EXPORT
- /// Sets the TimeDateStamp value of a debug structure.
- void setTimeDateStamp(unsigned int uiIndex, dword dwValue); // EXPORT
- /// Sets the MajorVersion value of a debug structure.
- void setMajorVersion(unsigned int uiIndex, word wValue); // EXPORT
- /// Sets the MinorVersion value of a debug structure.
- void setMinorVersion(unsigned int uiIndex, word wValue); // EXPORT
- /// Sets the Type value of a debug structure.
- void setType(unsigned int uiIndex, dword dwValue); // EXPORT
- /// Sets the SizeOfData value of a debug structure.
- void setSizeOfData(unsigned int uiIndex, dword dwValue); // EXPORT
- /// Sets the AddressOfRawData value of a debug structure.
- void setAddressOfRawData(unsigned int uiIndex, dword dwValue); // EXPORT
- /// Sets the PointerToRawData value of a debug structure.
- void setPointerToRawData(unsigned int uiIndex, dword dwValue); // EXPORT
- void setData(unsigned int index, const std::vector<byte>& data); // EXPORT
- };
-}
-#endif
+/* +* DebugDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef DEBUGDIRECTORY_H +#define DEBUGDIRECTORY_H + +namespace PeLib +{ + /// Class that handles the Debug directory. + class DebugDirectory + { + private: + /// Stores the various DebugDirectory structures. + std::vector<PELIB_IMG_DEBUG_DIRECTORY> m_vDebugInfo; + + std::vector<PELIB_IMG_DEBUG_DIRECTORY> read(InputBuffer& ibBuffer, unsigned int uiSize); + + public: + void clear(); // EXPORT + /// Reads the Debug directory from a file. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize); // EXPORT + int read(unsigned char* buffer, unsigned int buffersize); + /// Rebuilds the current Debug directory. + void rebuild(std::vector<byte>& obBuffer) const; // EXPORT + /// Returns the size the current Debug directory needs after rebuilding. + unsigned int size() const; + /// Writes the current Debug directory back to a file. + int write(const std::string& strFilename, unsigned int uiOffset) const; // EXPORT + + /// Returns the number of DebugDirectory image structures in the current DebugDirectory. + unsigned int calcNumberOfEntries() const; // EXPORT + + /// Adds a new debug structure. + void addEntry(); // EXPORT + /// Removes a debug structure. + void removeEntry(unsigned int uiIndex); // EXPORT + + /// Returns the Characteristics value of a debug structure. + dword getCharacteristics(unsigned int uiIndex) const; // EXPORT + /// Returns the TimeDateStamp value of a debug structure. + dword getTimeDateStamp(unsigned int uiIndex) const; // EXPORT + /// Returns the MajorVersion value of a debug structure. + word getMajorVersion(unsigned int uiIndex) const; // EXPORT + /// Returns the MinorVersion value of a debug structure. + word getMinorVersion(unsigned int uiIndex) const; // EXPORT + /// Returns the Type value of a debug structure. + dword getType(unsigned int uiIndex) const; // EXPORT + /// Returns the SizeOfData value of a debug structure. + dword getSizeOfData(unsigned int uiIndex) const; // EXPORT + /// Returns the AddressOfRawData value of a debug structure. + dword getAddressOfRawData(unsigned int uiIndex) const; // EXPORT + /// Returns the PointerToRawData value of a debug structure. + dword getPointerToRawData(unsigned int uiIndex) const; // EXPORT + std::vector<byte> getData(unsigned int index) const; // EXPORT + + /// Sets the Characteristics value of a debug structure. + void setCharacteristics(unsigned int uiIndex, dword dwValue); // EXPORT + /// Sets the TimeDateStamp value of a debug structure. + void setTimeDateStamp(unsigned int uiIndex, dword dwValue); // EXPORT + /// Sets the MajorVersion value of a debug structure. + void setMajorVersion(unsigned int uiIndex, word wValue); // EXPORT + /// Sets the MinorVersion value of a debug structure. + void setMinorVersion(unsigned int uiIndex, word wValue); // EXPORT + /// Sets the Type value of a debug structure. + void setType(unsigned int uiIndex, dword dwValue); // EXPORT + /// Sets the SizeOfData value of a debug structure. + void setSizeOfData(unsigned int uiIndex, dword dwValue); // EXPORT + /// Sets the AddressOfRawData value of a debug structure. + void setAddressOfRawData(unsigned int uiIndex, dword dwValue); // EXPORT + /// Sets the PointerToRawData value of a debug structure. + void setPointerToRawData(unsigned int uiIndex, dword dwValue); // EXPORT + void setData(unsigned int index, const std::vector<byte>& data); // EXPORT + }; +} +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.cpp index aa9c28a50f..83c4b4e69d 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.cpp @@ -1,692 +1,692 @@ -/*
-* ExportDirectory.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-//#ifdef false
-
-#include "PeLibInc.h"
-#include "ExportDirectory.h"
-
-namespace PeLib
-{
- /**
- * @param strFuncname Name of the function.
- * @param dwFuncAddr RVA of the function.
- **/
- void ExportDirectory::addFunction(const std::string& strFuncname, dword dwFuncAddr)
- {
- PELIB_EXP_FUNC_INFORMATION efiCurr;
- efiCurr.funcname = strFuncname;
- efiCurr.addroffunc = dwFuncAddr;
- m_ied.functions.push_back(efiCurr);
- }
-
- void ExportDirectory::removeFunction(unsigned int index)
- {
- m_ied.functions.erase(m_ied.functions.begin() + index);
- }
-
- void ExportDirectory::clear()
- {
- m_ied.functions.clear();
- }
-
- unsigned int ExportDirectory::calcNumberOfFunctions() const
- {
- return static_cast<unsigned int>(m_ied.functions.size());
- }
-
- /**
- * Identifies an exported function through it's name.
- * @param strFunctionName Name of the function
- * @return Number which identifies the functions.
- **/
- int ExportDirectory::getFunctionIndex(const std::string& strFunctionName) const
- {
- std::vector<PELIB_EXP_FUNC_INFORMATION>::const_iterator Iter = std::find_if(m_ied.functions.begin(), m_ied.functions.end(), std::bind2nd(std::mem_fun_ref(&PELIB_EXP_FUNC_INFORMATION::equal), strFunctionName));
-
- if (Iter == m_ied.functions.end())
- {
-// throw Exceptions::InvalidName(ExportDirectoryId, __LINE__);
- return -1;
- }
-
- return static_cast<int>(std::distance(m_ied.functions.begin(), Iter));
- }
-
- /**
- * @param strFilename Name of the file.
- * @param uiOffset File offset of the export directory.
- * @param uiSize Size of the export directory.
- * @param pehHeader A valid PE header which is necessary because some RVA calculations need to be done.
- * \todo: Proper use of InputBuffer
- **/
- int ExportDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeader& pehHeader)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios::binary);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- unsigned int filesize = fileSize(ifFile);
-
- if (filesize < uiOffset + uiSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(uiOffset, std::ios::beg);
-
- PELIB_IMAGE_EXP_DIRECTORY iedCurr;
-
- std::vector<unsigned char> vExportdirectory(uiSize);
- ifFile.read(reinterpret_cast<char*>(&vExportdirectory[0]), uiSize);
-
- InputBuffer inpBuffer(vExportdirectory);
-
- inpBuffer >> iedCurr.ied.Characteristics;
- inpBuffer >> iedCurr.ied.TimeDateStamp;
- inpBuffer >> iedCurr.ied.MajorVersion;
- inpBuffer >> iedCurr.ied.MinorVersion;
- inpBuffer >> iedCurr.ied.Name;
- inpBuffer >> iedCurr.ied.Base;
- inpBuffer >> iedCurr.ied.NumberOfFunctions;
- inpBuffer >> iedCurr.ied.NumberOfNames;
- inpBuffer >> iedCurr.ied.AddressOfFunctions;
- inpBuffer >> iedCurr.ied.AddressOfNames;
- inpBuffer >> iedCurr.ied.AddressOfNameOrdinals;
-
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.ied.Name);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: Files might be > 4 GB
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.Name));
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
-
- char c = 0;
- std::string strFname = "";
- do
- {
- ifFile.read(reinterpret_cast<char*>(&c), sizeof(c));
- if (!ifFile) return ERROR_INVALID_FILE;
- if (c) strFname += c;
- }
- while (c != 0);
- iedCurr.name = strFname;
-
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfFunctions);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: File might be > 4 GB
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfFunctions));
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
-
- PELIB_EXP_FUNC_INFORMATION efiCurr;
- efiCurr.ordinal = 0; efiCurr.addroffunc = 0; efiCurr.addrofname = 0;
-
- for (unsigned int i=0;i<iedCurr.ied.NumberOfFunctions;i++)
- {
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfFunctions) + i*sizeof(efiCurr.addroffunc);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: File might be > 4GB
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfFunctions)) + i*sizeof(efiCurr.addroffunc);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
-
- ifFile.read(reinterpret_cast<char*>(&efiCurr.addroffunc), sizeof(efiCurr.addroffunc));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- efiCurr.ordinal = i;
- iedCurr.functions.push_back(efiCurr);
- }
-
- for (unsigned int i=0;i<iedCurr.ied.NumberOfNames;i++)
- {
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfNameOrdinals) + i*sizeof(efiCurr.ordinal);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: File might be > 4 GB
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfNameOrdinals)) + i*sizeof(efiCurr.ordinal);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
-
- word ordinal;
- ifFile.read(reinterpret_cast<char*>(&ordinal), sizeof(ordinal));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- iedCurr.functions[ordinal].ordinal = ordinal;
-
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfNames) + i*sizeof(efiCurr.addrofname);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: File might be > 4 GB.
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfNames)) + i*sizeof(efiCurr.addrofname);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
-
- ifFile.read(reinterpret_cast<char*>(&iedCurr.functions[ordinal].addrofname), sizeof(iedCurr.functions[ordinal].addrofname));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader))
- {
- unsigned int offset = p32->rvaToOffset(iedCurr.functions[ordinal].addrofname);
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(offset, std::ios::beg);
- }
- else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader))
- {
- // XXX: File might be > 4 GB.
- unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.functions[ordinal].addrofname));
-
- if (offset >= filesize)
- return ERROR_INVALID_FILE;
-
- ifFile.seekg(static_cast<unsigned int>(p64->rvaToOffset(iedCurr.functions[ordinal].addrofname)), std::ios::beg);
- }
-
- char c = 0;
- std::string strFname = "";
- do
- {
- ifFile.read(reinterpret_cast<char*>(&c), sizeof(c));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- if (c) strFname += c;
- }
- while (c != 0);
-
- iedCurr.functions[ordinal].funcname = strFname;
- }
-
- std::swap(m_ied, iedCurr);
-
- return NO_ERROR;
- }
-
- /**
- * @param vBuffer Buffer where the rebuilt export directory is written to.
- * @param dwRva RVA of the export directory.
- * \todo fValid flag
- **/
- void ExportDirectory::rebuild(std::vector<byte>& vBuffer, dword dwRva) const
- {
- unsigned int uiSizeDirectory = sizeof(PELIB_IMAGE_EXPORT_DIRECTORY);
-
- unsigned int uiSizeNames = 0;
- unsigned int uiSizeAddrFuncs = 0;
- unsigned int uiSizeAddrNames = 0;
- unsigned int uiSizeOrdinals = 0;
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- uiSizeNames += (m_ied.functions[i].funcname.empty()) ? 0 : static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1;
- uiSizeAddrFuncs += sizeof(m_ied.functions[i].addroffunc);
- uiSizeAddrNames += (m_ied.functions[i].funcname.empty()) ? 0 : sizeof(m_ied.functions[i].addrofname);
- uiSizeOrdinals += (m_ied.functions[i].funcname.empty()) ? 0 : sizeof(m_ied.functions[i].ordinal);
- }
-
- unsigned int uiFilenameSize = static_cast<unsigned int>(m_ied.name.size()) + 1;
-
- OutputBuffer obBuffer(vBuffer);
-
- obBuffer << m_ied.ied.Characteristics;
- obBuffer << m_ied.ied.TimeDateStamp;
- obBuffer << m_ied.ied.MajorVersion;
- obBuffer << m_ied.ied.MinorVersion;
- obBuffer << dwRva + uiSizeDirectory;
- obBuffer << m_ied.ied.Base;
- obBuffer << static_cast<unsigned int>(m_ied.functions.size());
-
- // TODO: Not correct but sufficient for now. (Update: I forgot what this comment refers to, but I'll leave it in)
- obBuffer << static_cast<unsigned int>(m_ied.functions.size());
- obBuffer << dwRva + uiSizeDirectory + uiFilenameSize;
- obBuffer << dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs;
- obBuffer << dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs + uiSizeAddrNames;
-
- obBuffer.add(m_ied.name.c_str(), static_cast<unsigned int>(m_ied.name.size())+1);
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- obBuffer << m_ied.functions[i].addroffunc;
- }
-
- unsigned int ulFuncCounter = dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs + uiSizeAddrNames + uiSizeOrdinals;
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- if (!m_ied.functions[i].funcname.empty())
- {
- obBuffer << ulFuncCounter;
- ulFuncCounter += static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1;
- }
- }
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- if (!m_ied.functions[i].funcname.empty())
- {
- obBuffer << m_ied.functions[i].ordinal;
- }
- }
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- if (m_ied.functions[i].funcname.empty() && m_ied.functions[i].addroffunc)
- {
- obBuffer << m_ied.functions[i].ordinal;
- }
- }
-
- for (unsigned int i=0;i<m_ied.functions.size();i++)
- {
- if (!m_ied.functions[i].funcname.empty())
- {
- obBuffer.add(m_ied.functions[i].funcname.c_str(), static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1);
- }
- }
- }
-
- /**
- * @return Size of the current export directory.
- **/
- unsigned int ExportDirectory::size() const
- {
- return m_ied.size();
- }
-
- /**
- * @param strFilename Name of the file.
- * @param uiOffset File offset the export directory will be written to.
- * @param uiRva RVA of the export directory.
- * \todo Check if ofFile.write succeeded.
- **/
- int ExportDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(uiOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
- rebuild(vBuffer, uiRva);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-
- /**
- * Changes the filename according to the export directory.
- * @param strFilename New filename.
- **/
- void ExportDirectory::setNameString(const std::string& strFilename)
- {
- m_ied.name = strFilename;
- }
-
- std::string ExportDirectory::getNameString() const
- {
- return m_ied.name;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @return The name of that function.
- **/
- std::string ExportDirectory::getFunctionName(dword dwIndex) const
- {
- return m_ied.functions[dwIndex].funcname;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @return The ordinal of that function.
- **/
- word ExportDirectory::getFunctionOrdinal(dword dwIndex) const
- {
- return m_ied.functions[dwIndex].ordinal;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @return The RVA of the name string of that function.
- **/
- dword ExportDirectory::getAddressOfName(dword dwIndex) const
- {
- return m_ied.functions[dwIndex].addrofname;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @return The RVA of that function.
- **/
- dword ExportDirectory::getAddressOfFunction(dword dwIndex) const
- {
- return m_ied.functions[dwIndex].addroffunc;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @param strName The name of that function.
- **/
- void ExportDirectory::setFunctionName(dword dwIndex, const std::string& strName)
- {
- m_ied.functions[dwIndex].funcname = strName;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @param wValue The ordinal of that function.
- **/
- void ExportDirectory::setFunctionOrdinal(dword dwIndex, word wValue)
- {
- m_ied.functions[dwIndex].ordinal = wValue;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @param dwValue The RVA of the name string of that function.
- **/
- void ExportDirectory::setAddressOfName(dword dwIndex, dword dwValue)
- {
- m_ied.functions[dwIndex].addrofname = dwValue;
- }
-
- /**
- * @param dwIndex Number which identifies an exported function.
- * @param dwValue The RVA of that function.
- **/
- void ExportDirectory::setAddressOfFunction(dword dwIndex, dword dwValue)
- {
- m_ied.functions[dwIndex].addroffunc = dwValue;
- }
-
- /**
- * @return The ordinal base of the export directory.
- **/
- dword ExportDirectory::getBase() const
- {
- return m_ied.ied.Base;
- }
-
- /**
- * @return The characteristics of the export directory.
- **/
- dword ExportDirectory::getCharacteristics() const
- {
- return m_ied.ied.Characteristics;
- }
-
- /**
- * @return The time/date stamp of the export directory.
- **/
- dword ExportDirectory::getTimeDateStamp() const
- {
- return m_ied.ied.TimeDateStamp;
- }
-
- /**
- * @return The MajorVersion of the export directory.
- **/
- word ExportDirectory::getMajorVersion() const
- {
- return m_ied.ied.MajorVersion;
- }
-
- /**
- * @return The MinorVersion of the export directory.
- **/
- word ExportDirectory::getMinorVersion() const
- {
- return m_ied.ied.MinorVersion;
- }
-
- /**
- * @return The RVA of the name of the file.
- **/
- dword ExportDirectory::getName() const
- {
- return m_ied.ied.Name;
- }
-
- /**
- * @return The NumberOfFunctions of the export directory.
- **/
- dword ExportDirectory::getNumberOfFunctions() const
- {
- return m_ied.ied.NumberOfFunctions;
- }
-
- /**
- * @return The NumberOfNames of the export directory.
- **/
- dword ExportDirectory::getNumberOfNames() const
- {
- return m_ied.ied.NumberOfNames;
- }
-
- /**
- * @return The AddressOfFunctions of the export directory.
- **/
- dword ExportDirectory::getAddressOfFunctions() const
- {
- return m_ied.ied.AddressOfFunctions;
- }
-
- /**
- * @return The AddressOfNames of the export directory.
- **/
- dword ExportDirectory::getAddressOfNames() const
- {
- return m_ied.ied.AddressOfNames;
- }
-
-/* dword ExportDirectory::getNumberOfNameOrdinals() const
- {
- return static_cast<dword>(m_ied.functions.size());
- }
-
- dword ExportDirectory::getNumberOfAddressOfFunctionNames() const
- {
- return static_cast<dword>(m_ied.functions.size());
- }
-
- dword ExportDirectory::getNumberOfAddressOfFunctions() const
- {
- return static_cast<dword>(m_ied.functions.size());
- }
-*/
- /**
- * @return The AddressOfNameOrdinals of the export directory.
- **/
- dword ExportDirectory::getAddressOfNameOrdinals() const
- {
- return m_ied.ied.AddressOfNameOrdinals;
- }
-
- /**
- * @param dwValue The ordinal base of the export directory.
- **/
- void ExportDirectory::setBase(dword dwValue)
- {
- m_ied.ied.Base = dwValue;
- }
-
- /**
- * @param dwValue The Characteristics of the export directory.
- **/
- void ExportDirectory::setCharacteristics(dword dwValue)
- {
- m_ied.ied.Characteristics = dwValue;
- }
-
- /**
- * @param dwValue The TimeDateStamp of the export directory.
- **/
- void ExportDirectory::setTimeDateStamp(dword dwValue)
- {
- m_ied.ied.TimeDateStamp = dwValue;
- }
-
- /**
- * @param wValue The MajorVersion of the export directory.
- **/
- void ExportDirectory::setMajorVersion(word wValue)
- {
- m_ied.ied.MajorVersion = wValue;
- }
-
- /**
- * @param wValue The MinorVersion of the export directory.
- **/
- void ExportDirectory::setMinorVersion(word wValue)
- {
- m_ied.ied.MinorVersion = wValue;
- }
-
- /**
- * @param dwValue The Name of the export directory.
- **/
- void ExportDirectory::setName(dword dwValue)
- {
- m_ied.ied.Name = dwValue;
- }
-
- /**
- * @param dwValue The NumberOfFunctions of the export directory.
- **/
- void ExportDirectory::setNumberOfFunctions(dword dwValue)
- {
- m_ied.ied.NumberOfFunctions = dwValue;
- }
-
- /**
- * @param dwValue The NumberOfNames of the export directory.
- **/
- void ExportDirectory::setNumberOfNames(dword dwValue)
- {
- m_ied.ied.NumberOfNames = dwValue;
- }
-
- /**
- * @param dwValue The AddressOfFunctions of the export directory.
- **/
- void ExportDirectory::setAddressOfFunctions(dword dwValue)
- {
- m_ied.ied.AddressOfFunctions = dwValue;
- }
-
- /**
- * @param dwValue The AddressOfNames of the export directory.
- **/
- void ExportDirectory::setAddressOfNames(dword dwValue)
- {
- m_ied.ied.AddressOfNames = dwValue;
- }
-
- void ExportDirectory::setAddressOfNameOrdinals(dword value)
- {
- m_ied.ied.AddressOfNameOrdinals = value;
- }
-}
+/* +* ExportDirectory.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +//#ifdef false + +#include "PeLibInc.h" +#include "ExportDirectory.h" + +namespace PeLib +{ + /** + * @param strFuncname Name of the function. + * @param dwFuncAddr RVA of the function. + **/ + void ExportDirectory::addFunction(const std::string& strFuncname, dword dwFuncAddr) + { + PELIB_EXP_FUNC_INFORMATION efiCurr; + efiCurr.funcname = strFuncname; + efiCurr.addroffunc = dwFuncAddr; + m_ied.functions.push_back(efiCurr); + } + + void ExportDirectory::removeFunction(unsigned int index) + { + m_ied.functions.erase(m_ied.functions.begin() + index); + } + + void ExportDirectory::clear() + { + m_ied.functions.clear(); + } + + unsigned int ExportDirectory::calcNumberOfFunctions() const + { + return static_cast<unsigned int>(m_ied.functions.size()); + } + + /** + * Identifies an exported function through it's name. + * @param strFunctionName Name of the function + * @return Number which identifies the functions. + **/ + int ExportDirectory::getFunctionIndex(const std::string& strFunctionName) const + { + std::vector<PELIB_EXP_FUNC_INFORMATION>::const_iterator Iter = std::find_if(m_ied.functions.begin(), m_ied.functions.end(), std::bind2nd(std::mem_fun_ref(&PELIB_EXP_FUNC_INFORMATION::equal), strFunctionName)); + + if (Iter == m_ied.functions.end()) + { +// throw Exceptions::InvalidName(ExportDirectoryId, __LINE__); + return -1; + } + + return static_cast<int>(std::distance(m_ied.functions.begin(), Iter)); + } + + /** + * @param strFilename Name of the file. + * @param uiOffset File offset of the export directory. + * @param uiSize Size of the export directory. + * @param pehHeader A valid PE header which is necessary because some RVA calculations need to be done. + * \todo: Proper use of InputBuffer + **/ + int ExportDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeader& pehHeader) + { + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + unsigned int filesize = fileSize(ifFile); + + if (filesize < uiOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(uiOffset, std::ios::beg); + + PELIB_IMAGE_EXP_DIRECTORY iedCurr; + + std::vector<unsigned char> vExportdirectory(uiSize); + ifFile.read(reinterpret_cast<char*>(&vExportdirectory[0]), uiSize); + + InputBuffer inpBuffer(vExportdirectory); + + inpBuffer >> iedCurr.ied.Characteristics; + inpBuffer >> iedCurr.ied.TimeDateStamp; + inpBuffer >> iedCurr.ied.MajorVersion; + inpBuffer >> iedCurr.ied.MinorVersion; + inpBuffer >> iedCurr.ied.Name; + inpBuffer >> iedCurr.ied.Base; + inpBuffer >> iedCurr.ied.NumberOfFunctions; + inpBuffer >> iedCurr.ied.NumberOfNames; + inpBuffer >> iedCurr.ied.AddressOfFunctions; + inpBuffer >> iedCurr.ied.AddressOfNames; + inpBuffer >> iedCurr.ied.AddressOfNameOrdinals; + + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.ied.Name); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: Files might be > 4 GB + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.Name)); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + + char c = 0; + std::string strFname = ""; + do + { + ifFile.read(reinterpret_cast<char*>(&c), sizeof(c)); + if (!ifFile) return ERROR_INVALID_FILE; + if (c) strFname += c; + } + while (c != 0); + iedCurr.name = strFname; + + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfFunctions); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: File might be > 4 GB + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfFunctions)); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + + PELIB_EXP_FUNC_INFORMATION efiCurr; + efiCurr.ordinal = 0; efiCurr.addroffunc = 0; efiCurr.addrofname = 0; + + for (unsigned int i=0;i<iedCurr.ied.NumberOfFunctions;i++) + { + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfFunctions) + i*sizeof(efiCurr.addroffunc); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: File might be > 4GB + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfFunctions)) + i*sizeof(efiCurr.addroffunc); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + + ifFile.read(reinterpret_cast<char*>(&efiCurr.addroffunc), sizeof(efiCurr.addroffunc)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + efiCurr.ordinal = i; + iedCurr.functions.push_back(efiCurr); + } + + for (unsigned int i=0;i<iedCurr.ied.NumberOfNames;i++) + { + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfNameOrdinals) + i*sizeof(efiCurr.ordinal); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: File might be > 4 GB + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfNameOrdinals)) + i*sizeof(efiCurr.ordinal); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + + word ordinal; + ifFile.read(reinterpret_cast<char*>(&ordinal), sizeof(ordinal)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + iedCurr.functions[ordinal].ordinal = ordinal; + + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.ied.AddressOfNames) + i*sizeof(efiCurr.addrofname); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: File might be > 4 GB. + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.ied.AddressOfNames)) + i*sizeof(efiCurr.addrofname); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + + ifFile.read(reinterpret_cast<char*>(&iedCurr.functions[ordinal].addrofname), sizeof(iedCurr.functions[ordinal].addrofname)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + if (const PeHeader32* p32 = dynamic_cast<const PeHeader32*>(&pehHeader)) + { + unsigned int offset = p32->rvaToOffset(iedCurr.functions[ordinal].addrofname); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(offset, std::ios::beg); + } + else if (const PeHeader64* p64 = dynamic_cast<const PeHeader64*>(&pehHeader)) + { + // XXX: File might be > 4 GB. + unsigned int offset = static_cast<unsigned int>(p64->rvaToOffset(iedCurr.functions[ordinal].addrofname)); + + if (offset >= filesize) + return ERROR_INVALID_FILE; + + ifFile.seekg(static_cast<unsigned int>(p64->rvaToOffset(iedCurr.functions[ordinal].addrofname)), std::ios::beg); + } + + char c = 0; + std::string strFname = ""; + do + { + ifFile.read(reinterpret_cast<char*>(&c), sizeof(c)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + if (c) strFname += c; + } + while (c != 0); + + iedCurr.functions[ordinal].funcname = strFname; + } + + std::swap(m_ied, iedCurr); + + return NO_ERROR; + } + + /** + * @param vBuffer Buffer where the rebuilt export directory is written to. + * @param dwRva RVA of the export directory. + * \todo fValid flag + **/ + void ExportDirectory::rebuild(std::vector<byte>& vBuffer, dword dwRva) const + { + unsigned int uiSizeDirectory = sizeof(PELIB_IMAGE_EXPORT_DIRECTORY); + + unsigned int uiSizeNames = 0; + unsigned int uiSizeAddrFuncs = 0; + unsigned int uiSizeAddrNames = 0; + unsigned int uiSizeOrdinals = 0; + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + uiSizeNames += (m_ied.functions[i].funcname.empty()) ? 0 : static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1; + uiSizeAddrFuncs += sizeof(m_ied.functions[i].addroffunc); + uiSizeAddrNames += (m_ied.functions[i].funcname.empty()) ? 0 : sizeof(m_ied.functions[i].addrofname); + uiSizeOrdinals += (m_ied.functions[i].funcname.empty()) ? 0 : sizeof(m_ied.functions[i].ordinal); + } + + unsigned int uiFilenameSize = static_cast<unsigned int>(m_ied.name.size()) + 1; + + OutputBuffer obBuffer(vBuffer); + + obBuffer << m_ied.ied.Characteristics; + obBuffer << m_ied.ied.TimeDateStamp; + obBuffer << m_ied.ied.MajorVersion; + obBuffer << m_ied.ied.MinorVersion; + obBuffer << dwRva + uiSizeDirectory; + obBuffer << m_ied.ied.Base; + obBuffer << static_cast<unsigned int>(m_ied.functions.size()); + + // TODO: Not correct but sufficient for now. (Update: I forgot what this comment refers to, but I'll leave it in) + obBuffer << static_cast<unsigned int>(m_ied.functions.size()); + obBuffer << dwRva + uiSizeDirectory + uiFilenameSize; + obBuffer << dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs; + obBuffer << dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs + uiSizeAddrNames; + + obBuffer.add(m_ied.name.c_str(), static_cast<unsigned int>(m_ied.name.size())+1); + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + obBuffer << m_ied.functions[i].addroffunc; + } + + unsigned int ulFuncCounter = dwRva + uiSizeDirectory + uiFilenameSize + uiSizeAddrFuncs + uiSizeAddrNames + uiSizeOrdinals; + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + if (!m_ied.functions[i].funcname.empty()) + { + obBuffer << ulFuncCounter; + ulFuncCounter += static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1; + } + } + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + if (!m_ied.functions[i].funcname.empty()) + { + obBuffer << m_ied.functions[i].ordinal; + } + } + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + if (m_ied.functions[i].funcname.empty() && m_ied.functions[i].addroffunc) + { + obBuffer << m_ied.functions[i].ordinal; + } + } + + for (unsigned int i=0;i<m_ied.functions.size();i++) + { + if (!m_ied.functions[i].funcname.empty()) + { + obBuffer.add(m_ied.functions[i].funcname.c_str(), static_cast<unsigned int>(m_ied.functions[i].funcname.size()) + 1); + } + } + } + + /** + * @return Size of the current export directory. + **/ + unsigned int ExportDirectory::size() const + { + return m_ied.size(); + } + + /** + * @param strFilename Name of the file. + * @param uiOffset File offset the export directory will be written to. + * @param uiRva RVA of the export directory. + * \todo Check if ofFile.write succeeded. + **/ + int ExportDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + rebuild(vBuffer, uiRva); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } + + /** + * Changes the filename according to the export directory. + * @param strFilename New filename. + **/ + void ExportDirectory::setNameString(const std::string& strFilename) + { + m_ied.name = strFilename; + } + + std::string ExportDirectory::getNameString() const + { + return m_ied.name; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @return The name of that function. + **/ + std::string ExportDirectory::getFunctionName(dword dwIndex) const + { + return m_ied.functions[dwIndex].funcname; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @return The ordinal of that function. + **/ + word ExportDirectory::getFunctionOrdinal(dword dwIndex) const + { + return m_ied.functions[dwIndex].ordinal; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @return The RVA of the name string of that function. + **/ + dword ExportDirectory::getAddressOfName(dword dwIndex) const + { + return m_ied.functions[dwIndex].addrofname; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @return The RVA of that function. + **/ + dword ExportDirectory::getAddressOfFunction(dword dwIndex) const + { + return m_ied.functions[dwIndex].addroffunc; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @param strName The name of that function. + **/ + void ExportDirectory::setFunctionName(dword dwIndex, const std::string& strName) + { + m_ied.functions[dwIndex].funcname = strName; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @param wValue The ordinal of that function. + **/ + void ExportDirectory::setFunctionOrdinal(dword dwIndex, word wValue) + { + m_ied.functions[dwIndex].ordinal = wValue; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @param dwValue The RVA of the name string of that function. + **/ + void ExportDirectory::setAddressOfName(dword dwIndex, dword dwValue) + { + m_ied.functions[dwIndex].addrofname = dwValue; + } + + /** + * @param dwIndex Number which identifies an exported function. + * @param dwValue The RVA of that function. + **/ + void ExportDirectory::setAddressOfFunction(dword dwIndex, dword dwValue) + { + m_ied.functions[dwIndex].addroffunc = dwValue; + } + + /** + * @return The ordinal base of the export directory. + **/ + dword ExportDirectory::getBase() const + { + return m_ied.ied.Base; + } + + /** + * @return The characteristics of the export directory. + **/ + dword ExportDirectory::getCharacteristics() const + { + return m_ied.ied.Characteristics; + } + + /** + * @return The time/date stamp of the export directory. + **/ + dword ExportDirectory::getTimeDateStamp() const + { + return m_ied.ied.TimeDateStamp; + } + + /** + * @return The MajorVersion of the export directory. + **/ + word ExportDirectory::getMajorVersion() const + { + return m_ied.ied.MajorVersion; + } + + /** + * @return The MinorVersion of the export directory. + **/ + word ExportDirectory::getMinorVersion() const + { + return m_ied.ied.MinorVersion; + } + + /** + * @return The RVA of the name of the file. + **/ + dword ExportDirectory::getName() const + { + return m_ied.ied.Name; + } + + /** + * @return The NumberOfFunctions of the export directory. + **/ + dword ExportDirectory::getNumberOfFunctions() const + { + return m_ied.ied.NumberOfFunctions; + } + + /** + * @return The NumberOfNames of the export directory. + **/ + dword ExportDirectory::getNumberOfNames() const + { + return m_ied.ied.NumberOfNames; + } + + /** + * @return The AddressOfFunctions of the export directory. + **/ + dword ExportDirectory::getAddressOfFunctions() const + { + return m_ied.ied.AddressOfFunctions; + } + + /** + * @return The AddressOfNames of the export directory. + **/ + dword ExportDirectory::getAddressOfNames() const + { + return m_ied.ied.AddressOfNames; + } + +/* dword ExportDirectory::getNumberOfNameOrdinals() const + { + return static_cast<dword>(m_ied.functions.size()); + } + + dword ExportDirectory::getNumberOfAddressOfFunctionNames() const + { + return static_cast<dword>(m_ied.functions.size()); + } + + dword ExportDirectory::getNumberOfAddressOfFunctions() const + { + return static_cast<dword>(m_ied.functions.size()); + } +*/ + /** + * @return The AddressOfNameOrdinals of the export directory. + **/ + dword ExportDirectory::getAddressOfNameOrdinals() const + { + return m_ied.ied.AddressOfNameOrdinals; + } + + /** + * @param dwValue The ordinal base of the export directory. + **/ + void ExportDirectory::setBase(dword dwValue) + { + m_ied.ied.Base = dwValue; + } + + /** + * @param dwValue The Characteristics of the export directory. + **/ + void ExportDirectory::setCharacteristics(dword dwValue) + { + m_ied.ied.Characteristics = dwValue; + } + + /** + * @param dwValue The TimeDateStamp of the export directory. + **/ + void ExportDirectory::setTimeDateStamp(dword dwValue) + { + m_ied.ied.TimeDateStamp = dwValue; + } + + /** + * @param wValue The MajorVersion of the export directory. + **/ + void ExportDirectory::setMajorVersion(word wValue) + { + m_ied.ied.MajorVersion = wValue; + } + + /** + * @param wValue The MinorVersion of the export directory. + **/ + void ExportDirectory::setMinorVersion(word wValue) + { + m_ied.ied.MinorVersion = wValue; + } + + /** + * @param dwValue The Name of the export directory. + **/ + void ExportDirectory::setName(dword dwValue) + { + m_ied.ied.Name = dwValue; + } + + /** + * @param dwValue The NumberOfFunctions of the export directory. + **/ + void ExportDirectory::setNumberOfFunctions(dword dwValue) + { + m_ied.ied.NumberOfFunctions = dwValue; + } + + /** + * @param dwValue The NumberOfNames of the export directory. + **/ + void ExportDirectory::setNumberOfNames(dword dwValue) + { + m_ied.ied.NumberOfNames = dwValue; + } + + /** + * @param dwValue The AddressOfFunctions of the export directory. + **/ + void ExportDirectory::setAddressOfFunctions(dword dwValue) + { + m_ied.ied.AddressOfFunctions = dwValue; + } + + /** + * @param dwValue The AddressOfNames of the export directory. + **/ + void ExportDirectory::setAddressOfNames(dword dwValue) + { + m_ied.ied.AddressOfNames = dwValue; + } + + void ExportDirectory::setAddressOfNameOrdinals(dword value) + { + m_ied.ied.AddressOfNameOrdinals = value; + } +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.h index 17a7e57020..19609b65a7 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ExportDirectory.h @@ -1,133 +1,133 @@ -/*
-* ExportDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef EXPORTDIRECTORY_H
-#define EXPORTDIRECTORY_H
-#include "PeHeader.h"
-
-namespace PeLib
-{
- /// Class that handles the export directory.
- /**
- * This class handles the export directory.
- * \todo getNameString
- **/
-// template<int bits>
- class ExportDirectory
- {
- private:
- /// Used to store all necessary information about a file's exported functions.
- PELIB_IMAGE_EXP_DIRECTORY m_ied;
-
- public:
- /// Add another function to be exported.
- void addFunction(const std::string& strFuncname, dword dwFuncAddr); // EXPORT
- unsigned int calcNumberOfFunctions() const; // EXPORT
- void clear(); // EXPORT
- /// Identifies a function through it's name.
- int getFunctionIndex(const std::string& strFunctionName) const; // EXPORT
- /// Read a file's export directory.
- int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeader& pehHeader); // EXPORT
- /// Rebuild the current export directory.
- void rebuild(std::vector<byte>& vBuffer, dword dwRva) const; // EXPORT
- void removeFunction(unsigned int index); // EXPORT
- /// Returns the size of the current export directory.
- unsigned int size() const; // EXPORT
- /// Writes the current export directory to a file.
- int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const; // EXPORT
-
- /// Changes the name of the file (according to the export directory).
- void setNameString(const std::string& strFilename); // EXPORT
- std::string getNameString() const; // EXPORT
-
- /// Get the name of an exported function.
- std::string getFunctionName(unsigned int index) const; // EXPORT
- /// Get the ordinal of an exported function.
- word getFunctionOrdinal(unsigned int index) const; // EXPORT
- /// Get the address of the name of an exported function.
- dword getAddressOfName(unsigned int index) const; // EXPORT
- /// Get the address of an exported function.
- dword getAddressOfFunction(unsigned int index) const; // EXPORT
-
- /// Change the name of an exported function.
- void setFunctionName(unsigned int index, const std::string& strName); // EXPORT
- /// Change the ordinal of an exported function.
- void setFunctionOrdinal(unsigned int index, word wValue); // EXPORT
- /// Change the address of the name of an exported function.
- void setAddressOfName(unsigned int index, dword dwValue); // EXPORT
- /// Change the address of an exported function.
- void setAddressOfFunction(unsigned int index, dword dwValue); // EXPORT
-
- /*
- word getFunctionOrdinal(std::string strFuncname) const;
- dword getAddressOfName(std::string strFuncname) const;
- dword getAddressOfFunction(std::string strFuncname) const;
-
- void setFunctionOrdinal(std::string strFuncname, word wValue);
- void setAddressOfName(std::string strFuncname, dword dwValue);
- void setAddressOfFunction(std::string strFuncname, dword dwValue);
- */
-
- /// Return the Base value of the export directory.
- dword getBase() const; // EXPORT
- /// Return the Characteristics value of the export directory.
- dword getCharacteristics() const; // EXPORT
- /// Return the TimeDateStamp value of the export directory.
- dword getTimeDateStamp() const; // EXPORT
- /// Return the MajorVersion value of the export directory.
- word getMajorVersion() const; // EXPORT
- /// Return the MinorVersion value of the export directory.
- word getMinorVersion() const; // EXPORT
- /// Return the Name value of the export directory.
- dword getName() const; // EXPORT
- /// Return the NumberOfFunctions value of the export directory.
- dword getNumberOfFunctions() const; // EXPORT
- /// Return the NumberOfNames value of the export directory.
- dword getNumberOfNames() const; // EXPORT
- /// Return the AddressOfFunctions value of the export directory.
- dword getAddressOfFunctions() const; // EXPORT
- /// Return the AddressOfNames value of the export directory.
- dword getAddressOfNames() const; // EXPORT
- /// Returns the AddressOfNameOrdinals value.
- dword getAddressOfNameOrdinals() const; // EXPORT
-
-/* /// Returns the number of NameOrdinals.
- dword getNumberOfNameOrdinals() const; // EXPORT
- /// Returns the number of AddressOfFunctionNames values.
- dword getNumberOfAddressOfFunctionNames() const; // EXPORT
- /// Returns the number of AddressOfFunction values.
- dword getNumberOfAddressOfFunctions() const; // EXPORT
-*/
- /// Set the Base value of the export directory.
- void setBase(dword dwValue); // EXPORT
- /// Set the Characteristics value of the export directory.
- void setCharacteristics(dword dwValue); // EXPORT
- /// Set the TimeDateStamp value of the export directory.
- void setTimeDateStamp(dword dwValue); // EXPORT
- /// Set the MajorVersion value of the export directory.
- void setMajorVersion(word wValue); // EXPORT
- /// Set the MinorVersion value of the export directory.
- void setMinorVersion(word wValue); // EXPORT
- /// Set the Name value of the export directory.
- void setName(dword dwValue); // EXPORT
- /// Set the NumberOfFunctions value of the export directory.
- void setNumberOfFunctions(dword dwValue); // EXPORT
- /// Set the NumberOfNames value of the export directory.
- void setNumberOfNames(dword dwValue); // EXPORT
- /// Set the AddressOfFunctions value of the export directory.
- void setAddressOfFunctions(dword dwValue); // EXPORT
- /// Set the AddressOfNames value of the export directory.
- void setAddressOfNames(dword dwValue); // EXPORT
- void setAddressOfNameOrdinals(dword value); // EXPORT
- };
-}
-#endif
+/* +* ExportDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef EXPORTDIRECTORY_H +#define EXPORTDIRECTORY_H +#include "PeHeader.h" + +namespace PeLib +{ + /// Class that handles the export directory. + /** + * This class handles the export directory. + * \todo getNameString + **/ +// template<int bits> + class ExportDirectory + { + private: + /// Used to store all necessary information about a file's exported functions. + PELIB_IMAGE_EXP_DIRECTORY m_ied; + + public: + /// Add another function to be exported. + void addFunction(const std::string& strFuncname, dword dwFuncAddr); // EXPORT + unsigned int calcNumberOfFunctions() const; // EXPORT + void clear(); // EXPORT + /// Identifies a function through it's name. + int getFunctionIndex(const std::string& strFunctionName) const; // EXPORT + /// Read a file's export directory. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeader& pehHeader); // EXPORT + /// Rebuild the current export directory. + void rebuild(std::vector<byte>& vBuffer, dword dwRva) const; // EXPORT + void removeFunction(unsigned int index); // EXPORT + /// Returns the size of the current export directory. + unsigned int size() const; // EXPORT + /// Writes the current export directory to a file. + int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const; // EXPORT + + /// Changes the name of the file (according to the export directory). + void setNameString(const std::string& strFilename); // EXPORT + std::string getNameString() const; // EXPORT + + /// Get the name of an exported function. + std::string getFunctionName(unsigned int index) const; // EXPORT + /// Get the ordinal of an exported function. + word getFunctionOrdinal(unsigned int index) const; // EXPORT + /// Get the address of the name of an exported function. + dword getAddressOfName(unsigned int index) const; // EXPORT + /// Get the address of an exported function. + dword getAddressOfFunction(unsigned int index) const; // EXPORT + + /// Change the name of an exported function. + void setFunctionName(unsigned int index, const std::string& strName); // EXPORT + /// Change the ordinal of an exported function. + void setFunctionOrdinal(unsigned int index, word wValue); // EXPORT + /// Change the address of the name of an exported function. + void setAddressOfName(unsigned int index, dword dwValue); // EXPORT + /// Change the address of an exported function. + void setAddressOfFunction(unsigned int index, dword dwValue); // EXPORT + + /* + word getFunctionOrdinal(std::string strFuncname) const; + dword getAddressOfName(std::string strFuncname) const; + dword getAddressOfFunction(std::string strFuncname) const; + + void setFunctionOrdinal(std::string strFuncname, word wValue); + void setAddressOfName(std::string strFuncname, dword dwValue); + void setAddressOfFunction(std::string strFuncname, dword dwValue); + */ + + /// Return the Base value of the export directory. + dword getBase() const; // EXPORT + /// Return the Characteristics value of the export directory. + dword getCharacteristics() const; // EXPORT + /// Return the TimeDateStamp value of the export directory. + dword getTimeDateStamp() const; // EXPORT + /// Return the MajorVersion value of the export directory. + word getMajorVersion() const; // EXPORT + /// Return the MinorVersion value of the export directory. + word getMinorVersion() const; // EXPORT + /// Return the Name value of the export directory. + dword getName() const; // EXPORT + /// Return the NumberOfFunctions value of the export directory. + dword getNumberOfFunctions() const; // EXPORT + /// Return the NumberOfNames value of the export directory. + dword getNumberOfNames() const; // EXPORT + /// Return the AddressOfFunctions value of the export directory. + dword getAddressOfFunctions() const; // EXPORT + /// Return the AddressOfNames value of the export directory. + dword getAddressOfNames() const; // EXPORT + /// Returns the AddressOfNameOrdinals value. + dword getAddressOfNameOrdinals() const; // EXPORT + +/* /// Returns the number of NameOrdinals. + dword getNumberOfNameOrdinals() const; // EXPORT + /// Returns the number of AddressOfFunctionNames values. + dword getNumberOfAddressOfFunctionNames() const; // EXPORT + /// Returns the number of AddressOfFunction values. + dword getNumberOfAddressOfFunctions() const; // EXPORT +*/ + /// Set the Base value of the export directory. + void setBase(dword dwValue); // EXPORT + /// Set the Characteristics value of the export directory. + void setCharacteristics(dword dwValue); // EXPORT + /// Set the TimeDateStamp value of the export directory. + void setTimeDateStamp(dword dwValue); // EXPORT + /// Set the MajorVersion value of the export directory. + void setMajorVersion(word wValue); // EXPORT + /// Set the MinorVersion value of the export directory. + void setMinorVersion(word wValue); // EXPORT + /// Set the Name value of the export directory. + void setName(dword dwValue); // EXPORT + /// Set the NumberOfFunctions value of the export directory. + void setNumberOfFunctions(dword dwValue); // EXPORT + /// Set the NumberOfNames value of the export directory. + void setNumberOfNames(dword dwValue); // EXPORT + /// Set the AddressOfFunctions value of the export directory. + void setAddressOfFunctions(dword dwValue); // EXPORT + /// Set the AddressOfNames value of the export directory. + void setAddressOfNames(dword dwValue); // EXPORT + void setAddressOfNameOrdinals(dword value); // EXPORT + }; +} +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.cpp index 36482fcbeb..b32cfb2a8e 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.cpp @@ -1,179 +1,179 @@ -/*
-* IatDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "IatDirectory.h"
-
-namespace PeLib
-{
- int IatDirectory::read(InputBuffer& inputBuffer, unsigned int size)
- {
- dword dwAddr;
-
- std::vector<dword> vIat;
-
- for (unsigned int i=0;i<size/sizeof(dword);i++)
- {
- inputBuffer >> dwAddr;
- vIat.push_back(dwAddr);
- }
-
- std::swap(vIat, m_vIat);
-
- return NO_ERROR;
- }
-
- /**
- * Reads the Import Address table from a file.
- * @param strFilename Name of the file.
- * @param dwOffset File offset of the IAT (see #PeFile::PeHeader::getIDIatRVA).
- * @param dwSize Size of the IAT (see #PeFile::PeHeader::getIDIatSize).
- **/
- int IatDirectory::read(const std::string& strFilename, unsigned int dwOffset, unsigned int dwSize)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios::binary);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- if (fileSize(ifFile) < dwOffset + dwSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(dwOffset, std::ios::beg);
-
- std::vector<byte> vBuffer(dwSize);
- ifFile.read(reinterpret_cast<char*>(&vBuffer[0]), dwSize);
-
- InputBuffer inpBuffer(vBuffer);
- return read(inpBuffer, dwSize);
- }
-
- int IatDirectory::read(unsigned char* buffer, unsigned int buffersize)
- {
- std::vector<byte> vBuffer(buffer, buffer + buffersize);
- InputBuffer inpBuffer(vBuffer);
- return read(inpBuffer, buffersize);
- }
-
- /**
- * Returns the number of fields in the IAT. This is equivalent to the number of
- * imported functions.
- * @return Number of fields in the IAT.
- **/
- unsigned int IatDirectory::calcNumberOfAddresses() const
- {
- return static_cast<unsigned int>(m_vIat.size());
- }
-
- /**
- * Returns the dwValue of a field in the IAT.
- * @param dwAddrnr Number identifying the field.
- * @return dwValue of the field.
- **/
- dword IatDirectory::getAddress(unsigned int index) const
- {
- return m_vIat[index];
- }
-
- /**
- * Updates the dwValue of a field in the IAT.
- * @param dwAddrnr Number identifying the field.
- * @param dwValue New dwValue of the field.
- **/
- void IatDirectory::setAddress(dword dwAddrnr, dword dwValue)
- {
- m_vIat[dwAddrnr] = dwValue;
- }
-
- /**
- * Adds another field to the IAT.
- * @param dwValue dwValue of the new field.
- **/
- void IatDirectory::addAddress(dword dwValue)
- {
- m_vIat.push_back(dwValue);
- }
-
- /**
- * Removes an address from the IAT.
- * @param dwAddrnr Number identifying the field.
- **/
- void IatDirectory::removeAddress(unsigned int index)
- {
- std::vector<dword>::iterator pos = m_vIat.begin() + index;
- m_vIat.erase(pos);
- }
-
- /**
- * Delete all entries from the IAT.
- **/
- void IatDirectory::clear()
- {
- m_vIat.clear();
- }
-
- /**
- * Rebuilds the complete Import Address Table.
- * @param vBuffer Buffer where the rebuilt IAT will be stored.
- **/
- void IatDirectory::rebuild(std::vector<byte>& vBuffer) const
- {
- vBuffer.reserve(size());
- OutputBuffer obBuffer(vBuffer);
-
- for (unsigned int i=0;i<m_vIat.size();i++)
- {
- obBuffer << m_vIat[i];
- }
- }
-
- unsigned int IatDirectory::size() const
- {
- return static_cast<unsigned int>(m_vIat.size())* sizeof(dword);
- }
-
- /// Writes the current IAT to a file.
- int IatDirectory::write(const std::string& strFilename, unsigned int uiOffset) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(uiOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
- rebuild(vBuffer);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-}
+/* +* IatDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "IatDirectory.h" + +namespace PeLib +{ + int IatDirectory::read(InputBuffer& inputBuffer, unsigned int size) + { + dword dwAddr; + + std::vector<dword> vIat; + + for (unsigned int i=0;i<size/sizeof(dword);i++) + { + inputBuffer >> dwAddr; + vIat.push_back(dwAddr); + } + + std::swap(vIat, m_vIat); + + return NO_ERROR; + } + + /** + * Reads the Import Address table from a file. + * @param strFilename Name of the file. + * @param dwOffset File offset of the IAT (see #PeFile::PeHeader::getIDIatRVA). + * @param dwSize Size of the IAT (see #PeFile::PeHeader::getIDIatSize). + **/ + int IatDirectory::read(const std::string& strFilename, unsigned int dwOffset, unsigned int dwSize) + { + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + if (fileSize(ifFile) < dwOffset + dwSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(dwOffset, std::ios::beg); + + std::vector<byte> vBuffer(dwSize); + ifFile.read(reinterpret_cast<char*>(&vBuffer[0]), dwSize); + + InputBuffer inpBuffer(vBuffer); + return read(inpBuffer, dwSize); + } + + int IatDirectory::read(unsigned char* buffer, unsigned int buffersize) + { + std::vector<byte> vBuffer(buffer, buffer + buffersize); + InputBuffer inpBuffer(vBuffer); + return read(inpBuffer, buffersize); + } + + /** + * Returns the number of fields in the IAT. This is equivalent to the number of + * imported functions. + * @return Number of fields in the IAT. + **/ + unsigned int IatDirectory::calcNumberOfAddresses() const + { + return static_cast<unsigned int>(m_vIat.size()); + } + + /** + * Returns the dwValue of a field in the IAT. + * @param dwAddrnr Number identifying the field. + * @return dwValue of the field. + **/ + dword IatDirectory::getAddress(unsigned int index) const + { + return m_vIat[index]; + } + + /** + * Updates the dwValue of a field in the IAT. + * @param dwAddrnr Number identifying the field. + * @param dwValue New dwValue of the field. + **/ + void IatDirectory::setAddress(dword dwAddrnr, dword dwValue) + { + m_vIat[dwAddrnr] = dwValue; + } + + /** + * Adds another field to the IAT. + * @param dwValue dwValue of the new field. + **/ + void IatDirectory::addAddress(dword dwValue) + { + m_vIat.push_back(dwValue); + } + + /** + * Removes an address from the IAT. + * @param dwAddrnr Number identifying the field. + **/ + void IatDirectory::removeAddress(unsigned int index) + { + std::vector<dword>::iterator pos = m_vIat.begin() + index; + m_vIat.erase(pos); + } + + /** + * Delete all entries from the IAT. + **/ + void IatDirectory::clear() + { + m_vIat.clear(); + } + + /** + * Rebuilds the complete Import Address Table. + * @param vBuffer Buffer where the rebuilt IAT will be stored. + **/ + void IatDirectory::rebuild(std::vector<byte>& vBuffer) const + { + vBuffer.reserve(size()); + OutputBuffer obBuffer(vBuffer); + + for (unsigned int i=0;i<m_vIat.size();i++) + { + obBuffer << m_vIat[i]; + } + } + + unsigned int IatDirectory::size() const + { + return static_cast<unsigned int>(m_vIat.size())* sizeof(dword); + } + + /// Writes the current IAT to a file. + int IatDirectory::write(const std::string& strFilename, unsigned int uiOffset) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + rebuild(vBuffer); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.h index 81ef77ed6a..26c5d4009c 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/IatDirectory.h @@ -1,58 +1,58 @@ -/*
-* IatDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef IATDIRECTORY_H
-#define IATDIRECTORY_H
-
-#include "PeLibInc.h"
-
-namespace PeLib
-{
- /// Class that handles the Import Address Table (IAT)
- /**
- * This class can read and modify the Import Address Table of a PE file.
- **/
- class IatDirectory
- {
- private:
- std::vector<dword> m_vIat; ///< Stores the individual IAT fields.
-
- int read(InputBuffer& inputBuffer, unsigned int size);
-
- public:
- /// Reads the Import Address Table from a PE file.
- int read(const std::string& strFilename, unsigned int dwOffset, unsigned int dwSize); // EXPORT
- int read(unsigned char* buffer, unsigned int buffersize); // EXPORT
- /// Returns the number of fields in the IAT.
- unsigned int calcNumberOfAddresses() const; // EXPORT
- /// Adds another address to the IAT.
- void addAddress(dword dwValue); // EXPORT
- /// Removes an address from the IAT.
- void removeAddress(unsigned int index); // EXPORT
- /// Empties the IAT.
- void clear(); // EXPORT
- // Rebuilds the IAT.
- void rebuild(std::vector<byte>& vBuffer) const; // EXPORT
- /// Returns the size of the current IAT.
- unsigned int size() const; // EXPORT
- /// Writes the current IAT to a file.
- int write(const std::string& strFilename, unsigned int uiOffset) const; // EXPORT
-
- /// Retrieve the value of a field in the IAT.
- dword getAddress(unsigned int index) const; // EXPORT
- /// Change the value of a field in the IAT.
- void setAddress(dword dwAddrnr, dword dwValue); // EXPORT
- };
-}
-
-#endif
-
+/* +* IatDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef IATDIRECTORY_H +#define IATDIRECTORY_H + +#include "PeLibInc.h" + +namespace PeLib +{ + /// Class that handles the Import Address Table (IAT) + /** + * This class can read and modify the Import Address Table of a PE file. + **/ + class IatDirectory + { + private: + std::vector<dword> m_vIat; ///< Stores the individual IAT fields. + + int read(InputBuffer& inputBuffer, unsigned int size); + + public: + /// Reads the Import Address Table from a PE file. + int read(const std::string& strFilename, unsigned int dwOffset, unsigned int dwSize); // EXPORT + int read(unsigned char* buffer, unsigned int buffersize); // EXPORT + /// Returns the number of fields in the IAT. + unsigned int calcNumberOfAddresses() const; // EXPORT + /// Adds another address to the IAT. + void addAddress(dword dwValue); // EXPORT + /// Removes an address from the IAT. + void removeAddress(unsigned int index); // EXPORT + /// Empties the IAT. + void clear(); // EXPORT + // Rebuilds the IAT. + void rebuild(std::vector<byte>& vBuffer) const; // EXPORT + /// Returns the size of the current IAT. + unsigned int size() const; // EXPORT + /// Writes the current IAT to a file. + int write(const std::string& strFilename, unsigned int uiOffset) const; // EXPORT + + /// Retrieve the value of a field in the IAT. + dword getAddress(unsigned int index) const; // EXPORT + /// Change the value of a field in the IAT. + void setAddress(dword dwAddrnr, dword dwValue); // EXPORT + }; +} + +#endif + diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h index 6578f0712a..42526f0c3c 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h @@ -1,1139 +1,1139 @@ -/*
-* ImportDirectory.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef IMPORTDIRECTORY_H
-#define IMPORTDIRECTORY_H
-
-#include "PeLibAux.h"
-#include "PeHeader.h"
-
-namespace PeLib
-{
- /// Parameter for functions that can operate on the OLDDIR or new import directory.
- enum currdir {OLDDIR = 1, NEWDIR};
-
- class PeLibException;
-
- /// Class that handles import directories.
- /**
- * This class can read import directories from existing PE files or start completely from scratch.
- * Modifying import directories and writing them to files is also possible.
- * It's worthy to note that many functions require an extra parameter of type currdir
- * because the structure of import directories make it necessary that the OLDDIR import directory
- * must be preserved. That's why some functions (like adding and removing) imported functions
- * only exist for the new import directory, not for the one which is already written to the file.
- * \todo Adding functions by ordinal doesn't work yet (rebuild needs to be changed).
- * \todo Somehow store the rvas of the chunks in the file.
- **/
- template<int bits>
- class ImportDirectory
- {
- typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::iterator ImpDirFileIterator;
- typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::const_iterator ConstImpDirFileIterator;
-
- private:
- /// Stores information about already imported DLLs.
- std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vOldiid;
- /// Stores information about imported DLLs which will be added.
- std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vNewiid;
-
- // I can't convince Borland C++ to compile the function outside of the class declaration.
- // That's why the function definition is here.
- /// Tests if a certain function is imported.
- template<typename T> bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA<bits>::* comp)(T) const) const
- {
- ConstImpDirFileIterator FileIter = m_vOldiid.begin();
- ConstImpDirFileIterator EndIter = m_vOldiid.end();
-
- for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid
- {
- do
- {
- FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
-
- if (FileIter != EndIter)
- {
- typename std::vector<PELIB_THUNK_DATA<bits> >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value));
- if (Iter != FileIter->originalfirstthunk.end())
- {
- return true;
- }
- ++FileIter;
- }
- }
- while (FileIter != EndIter);
-
- FileIter = m_vNewiid.begin();
- EndIter = m_vNewiid.end();
- }
-
- return false;
- }
-
-
- public:
-
- /// Add a function to the import directory.
- int addFunction(const std::string& strFilename, word wHint); // EXPORT _byHint
- /// Add a function to the import directory.
- int addFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName
-
- /// Get the ID of a file through it's name.
- unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; // EXPORT
- /// Get the ID of a function through it's name.
- unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; // EXPORT
-
- /// Get the name of an imported file.
- std::string getFileName(dword dwFilenr, currdir cdDir) const; // EXPORT
-
- void setFileName(dword filenr, currdir dir, const std::string& name); // EXPORT
-
- /// Get the hint of an imported function.
- word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT
- void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); // EXPORT
- /// Get the name of an imported function.
- std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT
- void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); // EXPORT
- /// Get the number of files which are imported.
- dword getNumberOfFiles(currdir cdDir) const; // EXPORT
- /// Get the number of fucntions which are imported by a specific file.
- dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; // EXPORT
- /// Read a file's import directory.
- int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader); // EXPORT
- /// Rebuild the import directory.
- void rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries = true) const; // EXPORT
- /// Remove a file from the import directory.
- int removeFile(const std::string& strFilename); // EXPORT
- /// Remove a function from the import directory.
- int removeFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName
- /// Remove a function from the import directory.
- int removeFunction(const std::string& strFilename, word wHint); // EXPORT _byHint
- /// Returns the size of the current import directory.
- unsigned int size() const; // EXPORT
- /// Writes the import directory to a file.
- int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); // EXPORT
-
- /// Returns the FirstThunk value of a function.
- dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber
- void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT _byNumber
- /// Returns the OriginalFirstThunk value of a function.
- dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber
- void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT
-
-// dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
-// dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
-
- /// Returns the FirstThunk value of a file.
- dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
- /// Returns the OriginalFirstThunk value of a file.
- dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
- /// Returns the ForwarderChain value of a file.
- dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
- dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
- /// Returns the TimeDateStamp value of a file.
- dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
-
- /// Returns the FirstThunk value of a file.
- dword getFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT
- void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
- /// Returns the OriginalFirstThunk value of a file.
- dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT
- void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
- /// Returns the ForwarderChain value of a file.
- dword getForwarderChain(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber
- void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
- dword getRvaOfName(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber
- void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); // EXPORT
- /// Returns the TimeDateStamp value of a file.
- dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; // EXPORT
- void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber
-
-// word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
- };
-
- /**
- * Add another import (by Ordinal) to the current file. Note that the import table is not automatically updated.
- * The new imported functions will be added when you recalculate the import table as it's necessary
- * to specify the address the import table will have in the file.
- * @param strFilename The name of a DLL.
- * @param wHint The ordinal of the function in the DLL.
- **/
- template<int bits>
- int ImportDirectory<bits>::addFunction(const std::string& strFilename, word wHint)
- {
- if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA<bits>::equalHint))
- {
- return ERROR_DUPLICATE_ENTRY;
- }
-
- // Find the imported file.
- ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
-
- PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid;
- PELIB_THUNK_DATA<bits> td;
- td.hint = wHint;
- td.itd.Ordinal = wHint | PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG;
- iid.name = strFilename;
- if (FileIter == m_vNewiid.end())
- {
- iid.originalfirstthunk.push_back(td);
- iid.firstthunk.push_back(td);
- m_vNewiid.push_back(iid);
- }
- else
- {
- FileIter->originalfirstthunk.push_back(td);
- FileIter->firstthunk.push_back(td);
- }
-
- return NO_ERROR;
- }
-
- /**
- * Add a function to the Import Directory.
- * @param strFilename Name of the file which will be imported
- * @param strFuncname Name of the function which will be imported.
- **/
- template<int bits>
- int ImportDirectory<bits>::addFunction(const std::string& strFilename, const std::string& strFuncname)
- {
- if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA<bits>::equalFunctionName))
- {
- return ERROR_DUPLICATE_ENTRY;
- }
-
- // Find the imported file.
- ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
-
- PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid;
- PELIB_THUNK_DATA<bits> td;
- td.fname = strFuncname;
- iid.name = strFilename;
- if (FileIter == m_vNewiid.end())
- {
- iid.originalfirstthunk.push_back(td);
- iid.firstthunk.push_back(td);
- m_vNewiid.push_back(iid);
- }
- else
- {
- FileIter->originalfirstthunk.push_back(td);
- FileIter->firstthunk.push_back(td);
- }
-
- return NO_ERROR;
- }
-
- /**
- * Searches through the import directory and returns the number of the import
- * directory entry which belongs to the given filename.
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return The ID of an imported file.
- **/
- template<int bits>
- unsigned int ImportDirectory<bits>::getFileIndex(const std::string& strFilename, currdir cdDir) const
- {
- const std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >* currDir;
-
- if (cdDir == OLDDIR)
- {
- currDir = &m_vOldiid;
- }
- else
- {
- currDir = &m_vNewiid;
- }
-
- ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
-
- if (FileIter != currDir->end())
- {
- return static_cast<unsigned int>(std::distance(currDir->begin(), FileIter));
- }
- else
- {
- return -1;
- // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__);
- }
-
- return NO_ERROR;
- }
-
- /**
- * Searches through an imported file for a specific function.
- * @param strFilename Name of the imported file.
- * @param strFuncname Name of the imported function.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return ID of the imported function.
- **/
- template<int bits>
- unsigned int ImportDirectory<bits>::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const
- {
- unsigned int uiFile = getFileIndex(strFilename, cdDir);
-
- for (unsigned int i=0;i<getNumberOfFunctions(uiFile, cdDir);i++)
- {
- if (getFunctionName(uiFile, i, cdDir) == strFuncname) return i;
- }
-
- return -1;
- }
-
- /**
- * Get the name of an imported file.
- * @param dwFilenr Identifies which file should be checked.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return Name of an imported file.
- **/
- template<int bits>
- std::string ImportDirectory<bits>::getFileName(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name;
- else return m_vNewiid[dwFilenr].name;
- }
-
- template<int bits>
- void ImportDirectory<bits>::setFileName(dword filenr, currdir dir, const std::string& name)
- {
- if (dir == OLDDIR) m_vOldiid[filenr].name = name;
- else m_vNewiid[filenr].name = name;
- }
-
- /**
- * Get the name of an imported function.
- * @param dwFilenr Identifies which file should be checked.
- * @param dwFuncnr Identifies which function should be checked.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return Name of an imported function.
- * \todo Marked line is unsafe (function should be rewritten).
- **/
- template<int bits>
- std::string ImportDirectory<bits>::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- // Unsafe
- if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname;
- }
- else
- {
- return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname;
- }
- }
- else
- {
- if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname;
- }
- else
- {
- return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname;
- }
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName)
- {
- if (cdDir == OLDDIR)
- {
- // Unsafe
- if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName;
- }
- else
- {
- m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName;
- }
- }
- else
- {
- if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName;
- }
- else
- {
- m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName;
- }
- }
- }
-
- /**
- * Get the hint of an imported function.
- * @param dwFilenr Identifies which file should be checked.
- * @param dwFuncnr Identifies which function should be checked.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return Hint of an imported function.
- **/
- template<int bits>
- word ImportDirectory<bits>::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint;
- }
- else
- {
- return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint;
- }
- }
- else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint;
- }
-
- template<int bits>
- void ImportDirectory<bits>::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value)
- {
- if (cdDir == OLDDIR)
- {
- if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
- {
- m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value;
- }
- else
- {
- m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value;
- }
- }
- else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value;
- }
-
- /**
- * Get the number of files which are currently being imported.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return Number of files which are currently being imported.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getNumberOfFiles(currdir cdDir) const
- {
- if (cdDir == OLDDIR) return static_cast<dword>(m_vOldiid.size());
- else return static_cast<dword>(m_vNewiid.size());
- }
-
- /**
- * Get the number of functions which are currently being imported from a specific file.
- * @param dwFilenr Identifies which file should be checked.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return Number of functions which are currently being imported from a specific file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR) return static_cast<unsigned int>(m_vOldiid[dwFilenr].firstthunk.size());
- else return static_cast<unsigned int>(m_vNewiid[dwFilenr].firstthunk.size());
- }
-
- /**
- * Read an import directory from a file.
- * \todo Check if streams failed.
- * @param strFilename Name of the file which will be read.
- * @param uiOffset Offset of the import directory (see #PeLib::PeHeader::getIDImportRVA).
- * @param uiSize Size of the import directory (see #PeLib::PeHeader::getIDImportSize).
- * @param pehHeader A valid PE header.
- **/
- template<int bits>
- int ImportDirectory<bits>::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- unsigned int uiFileSize = fileSize(ifFile);
-
- if (uiFileSize < uiOffset + uiSize)
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(uiOffset, std::ios_base::beg);
-
- std::vector<unsigned char> vImportdirectory(uiSize);
- ifFile.read(reinterpret_cast<char*>(&vImportdirectory[0]), uiSize);
-
- PELIB_IMAGE_IMPORT_DIRECTORY<bits> iidCurr;
- unsigned int uiDesccounter = 0;
-
- InputBuffer inpBuffer(vImportdirectory);
-
- std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > vOldIidCurr;
-
- do // Read and store all descriptors
- {
- inpBuffer >> iidCurr.impdesc.OriginalFirstThunk;
- inpBuffer >> iidCurr.impdesc.TimeDateStamp;
- inpBuffer >> iidCurr.impdesc.ForwarderChain;
- inpBuffer >> iidCurr.impdesc.Name;
- inpBuffer >> iidCurr.impdesc.FirstThunk;
-
- if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 ||
- iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0)
- {
- vOldIidCurr.push_back(iidCurr);
- }
-
- uiDesccounter++;
-
- if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break;
- } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 ||
- iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0);
-
- char namebuffer[2] = {0};
-
- // Name
- for (unsigned int i=0;i<vOldIidCurr.size();i++)
- {
- ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg);
-
- std::string dllname = "";
-
- do
- {
- ifFile.read(namebuffer, 1);
- if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
- dllname += namebuffer;
- } while (true);
-
- vOldIidCurr[i].name = dllname;
-
- }
-
- // OriginalFirstThunk
- for (unsigned int i=0;i<vOldIidCurr.size();i++)
- {
- PELIB_THUNK_DATA<bits> tdCurr;
- dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk;
-
- if (!uiVaoft)
- {
- continue;
- }
-
- ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg);
-
- do
- {
- if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal))
- {
- return ERROR_INVALID_FILE;
- }
- uiVaoft += sizeof(tdCurr.itd.Ordinal);
-
- ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal));
- if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr);
- } while (tdCurr.itd.Ordinal);
- }
-
- // FirstThunk
- for (unsigned int i=0;i<vOldIidCurr.size();i++)
- {
- dword uiVaoft = vOldIidCurr[i].impdesc.FirstThunk;
- PELIB_THUNK_DATA<bits> tdCurr;
-
- ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg);
-
- do
- {
- if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal))
- {
- return ERROR_INVALID_FILE;
- }
-
- uiVaoft += sizeof(tdCurr.itd.Ordinal);
-
- ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal));
- if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr);
- } while (tdCurr.itd.Ordinal);
- }
-
- // Names
- for (unsigned int i=0;i<vOldIidCurr.size();i++)
- {
- if (vOldIidCurr[i].impdesc.OriginalFirstThunk)
- {
- for (unsigned int j=0;j<vOldIidCurr[i].originalfirstthunk.size();j++)
- {
- if (vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG)
- {
- vOldIidCurr[i].originalfirstthunk[j].hint = 0;
- continue;
- }
-
- ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg);
-
- ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- std::string funcname = "";
- do
- {
- ifFile.read(namebuffer, 1);
- if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
- funcname += namebuffer;
- } while (true);
-
- vOldIidCurr[i].originalfirstthunk[j].fname = funcname;
- }
- }
- else
- {
- for (unsigned int j=0;j<vOldIidCurr[i].firstthunk.size();j++)
- {
- if (vOldIidCurr[i].firstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG)
- {
- continue;
- }
-
- ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg);
-
- ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint));
-
- if (!ifFile)
- return ERROR_INVALID_FILE;
-
- std::string funcname = "";
- do
- {
- ifFile.read(namebuffer, 1);
- if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
- funcname += namebuffer;
- } while (true);
-
- vOldIidCurr[i].firstthunk[j].fname = funcname;
- }
- }
- }
- std::swap(vOldIidCurr, m_vOldiid);
- return NO_ERROR;
- }
-
- /**
- * Rebuilds the import directory.
- * @param vBuffer Buffer the rebuilt import directory will be written to.
- * @param dwRva The RVA of the ImportDirectory in the file.
- * \todo uiSizeoffuncnames is not used.
- **/
- template<int bits>
- void ImportDirectory<bits>::rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries) const
- {
- unsigned int uiImprva = dwRva;
- unsigned int uiSizeofdescriptors = (static_cast<unsigned int>(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size();
-
- unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0;
- unsigned int uiSizeofoft = 0;
-
- for (unsigned int i=0;i<m_vNewiid.size();i++)
- {
- uiSizeofdllnames += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1;
- uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
-
- for(unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
- {
- // +3 for hint (word) and 00-byte
- uiSizeoffuncnames += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3);
- }
- }
-
-// for (unsigned int i=0;i<m_vNewiid.size();i++)
-// {
-// uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
-// }
-
- OutputBuffer obBuffer(vBuffer);
-
- // Rebuild IMAGE_IMPORT_DESCRIPTORS
- for (unsigned int i=0;i<m_vOldiid.size();i++)
- {
- obBuffer << m_vOldiid[i].impdesc.OriginalFirstThunk;
- obBuffer << m_vOldiid[i].impdesc.TimeDateStamp;
- obBuffer << m_vOldiid[i].impdesc.ForwarderChain;
- obBuffer << m_vOldiid[i].impdesc.Name;
- obBuffer << m_vOldiid[i].impdesc.FirstThunk;
- }
-
- unsigned int dllsize = 0;
-
- for (unsigned int i=0;i<m_vNewiid.size();i++)
- {
- dword dwPoft = uiSizeofdescriptors + uiImprva;
-
- for (unsigned int j=1;j<=i;j++)
- {
- dwPoft += (static_cast<unsigned int>(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
- }
-
- obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk);
- obBuffer << m_vNewiid[i].impdesc.TimeDateStamp;
- obBuffer << m_vNewiid[i].impdesc.ForwarderChain;
- dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize;
- obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name);
- obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk);
-
- dllsize += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1;
- }
-
- obBuffer << (dword)0;
- obBuffer << (dword)0;
- obBuffer << (dword)0;
- obBuffer << (dword)0;
- obBuffer << (dword)0;
-
- unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva;
-
- // Rebuild original first thunk
- for (unsigned int i=0;i<m_vNewiid.size();i++)
- {
- for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
- {
- if (m_vNewiid[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG
- || fixEntries == false)
- {
- obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal;
- }
- else
- {
- obBuffer << uiPfunc;
- }
- uiPfunc += static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3;
- }
- obBuffer << (dword)0;
- }
-
- // Write dllnames into import directory
- for (unsigned int i=0;i<m_vNewiid.size();i++)
- {
- obBuffer.add(m_vNewiid[i].name.c_str(), static_cast<unsigned int>(m_vNewiid[i].name.size())+1);
- }
-
- // Write function names into directory
- for (unsigned int i=0;i<m_vNewiid.size();i++)
- {
- for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
- {
- obBuffer << m_vNewiid[i].originalfirstthunk[j].hint;
- obBuffer.add(m_vNewiid[i].originalfirstthunk[j].fname.c_str(), static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1);
- }
- }
- }
-
- /**
- * Removes a specific file and all functions of it from the import directory.
- * @param strFilename Name of the file which will be removed.
- **/
- template<int bits>
- int ImportDirectory<bits>::removeFile(const std::string& strFilename)
- {
- unsigned int oldSize = static_cast<unsigned int>(m_vNewiid.size());
-
- m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)), m_vNewiid.end());
-
- return oldSize == m_vNewiid.size() ? 1 : 0;
- }
-
- /**
- * Removes a specific function from the import directory.
- * @param strFilename Name of the file which exports the function.
- * @param strFuncname Name of the imported function.
- **/
- template<int bits>
- int ImportDirectory<bits>::removeFunction(const std::string& strFilename, const std::string& strFuncname)
- {
- ImpDirFileIterator viPos = m_vNewiid.begin();
-
- int notFound = 1;
-
- while (viPos != m_vNewiid.end())
- {
- if (isEqualNc(viPos->name, strFilename))
- {
- unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size());
- viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end());
- //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy<PELIB_THUNK_DATA, std::string>(), strFuncname)));
- if (viPos->originalfirstthunk.size() != oldSize) notFound = 0;
- }
- ++viPos;
- }
-
- return notFound;
- }
-
- /**
- * Removes a specific function from the import directory.
- * @param strFilename Name of the file which exports the function.
- * @param wHint The hint of the function.
- **/
- template<int bits>
- int ImportDirectory<bits>::removeFunction(const std::string& strFilename, word wHint)
- {
- ImpDirFileIterator viPos = m_vNewiid.begin();
- int notFound = 1;
-
- while (viPos != m_vNewiid.end())
- {
- if (isEqualNc(viPos->name, strFilename))
- {
- unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size());
- viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalHint), wHint)), viPos->originalfirstthunk.end());
- unsigned int newPos = static_cast<unsigned int>(viPos->originalfirstthunk.size());
- if (viPos->originalfirstthunk.size() != oldSize) notFound = 0;
- }
- ++viPos;
- }
-
- return notFound;
- }
-
- /**
- * Writes the current import directory to a file.
- * @param strFilename Name of the file.
- * @param uiOffset File Offset of the new import directory.
- * @param uiRva RVA which belongs to that file offset.
- **/
- template<int bits>
- int ImportDirectory<bits>::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva)
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(uiOffset, std::ios_base::beg);
-
- std::vector<byte> vBuffer;
-
- rebuild(vBuffer, uiRva);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), vBuffer.size());
- ofFile.close();
-
- std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid));
- m_vNewiid.clear();
-
- return NO_ERROR;
- }
-
- /**
- * Returns the size of the import directory.
- * @return Size of the import directory.
- **/
- template<int bits>
- unsigned int ImportDirectory<bits>::size() const
- {
- // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to.
- return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >)
- + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size();
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return FirstThunk value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getFirstThunk(const std::string& strFilename, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk;
- }
- else
- {
- return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return OriginalFirstThunk value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk;
- }
- else
- {
- return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return ForwarderChain value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getForwarderChain(const std::string& strFilename, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain;
- }
- else
- {
- return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return TimeDateStamp value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp;
- }
- else
- {
- return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp;
- }
- }
-
- template<int bits>
- dword ImportDirectory<bits>::getRvaOfName(const std::string& strFilename, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name;
- }
- else
- {
- return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return FirstThunk value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[dwFilenr].impdesc.FirstThunk;
- }
- else
- {
- return m_vNewiid[dwFilenr].impdesc.FirstThunk;
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR)
- {
- m_vOldiid[dwFilenr].impdesc.FirstThunk = value;
- }
- else
- {
- m_vNewiid[dwFilenr].impdesc.FirstThunk = value;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return OriginalFirstThunk value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk;
- }
- else
- {
- return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk;
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR)
- {
- m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value;
- }
- else
- {
- m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return ForwarderChain value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getForwarderChain(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[dwFilenr].impdesc.ForwarderChain;
- }
- else
- {
- return m_vNewiid[dwFilenr].impdesc.ForwarderChain;
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setForwarderChain(dword dwFilenr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR)
- {
- m_vOldiid[dwFilenr].impdesc.ForwarderChain = value;
- }
- else
- {
- m_vNewiid[dwFilenr].impdesc.ForwarderChain = value;
- }
- }
-
- /**
- * @param strFilename Name of the imported file.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return TimeDateStamp value of an imported file.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getTimeDateStamp(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[dwFilenr].impdesc.TimeDateStamp;
- }
- else
- {
- return m_vNewiid[dwFilenr].impdesc.TimeDateStamp;
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR)
- {
- m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value;
- }
- else
- {
- m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value;
- }
- }
-
- template<int bits>
- dword ImportDirectory<bits>::getRvaOfName(dword dwFilenr, currdir cdDir) const
- {
- if (cdDir == OLDDIR)
- {
- return m_vOldiid[dwFilenr].impdesc.Name;
- }
- else
- {
- return m_vNewiid[dwFilenr].impdesc.Name;
- }
- }
-
- template<int bits>
- void ImportDirectory<bits>::setRvaOfName(dword dwFilenr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR)
- {
- m_vOldiid[dwFilenr].impdesc.Name = value;
- }
- else
- {
- m_vNewiid[dwFilenr].impdesc.Name = value;
- }
- }
-
- /**
- * @param dwFilenr ID of the imported file.
- * @param dwFuncnr ID of the imported function.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return FirstThunk value of an imported function.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
- {
- if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal;
- else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal;
- }
-
- template<int bits>
- void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value;
- else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value;
- }
-
- /**
- * @param dwFilenr ID of the imported file.
- * @param dwFuncnr ID of the imported function.
- * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
- * @return OriginalFirstThunk value of an imported function.
- **/
- template<int bits>
- dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
- {
- if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal;
- else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal;
- }
-
- template<int bits>
- void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value)
- {
- if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value;
- else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value;
- }
-
- typedef ImportDirectory<32> ImportDirectory32;
- typedef ImportDirectory<64> ImportDirectory64;
-}
-
-#endif
+/* +* ImportDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef IMPORTDIRECTORY_H +#define IMPORTDIRECTORY_H + +#include "PeLibAux.h" +#include "PeHeader.h" + +namespace PeLib +{ + /// Parameter for functions that can operate on the OLDDIR or new import directory. + enum currdir {OLDDIR = 1, NEWDIR}; + + class PeLibException; + + /// Class that handles import directories. + /** + * This class can read import directories from existing PE files or start completely from scratch. + * Modifying import directories and writing them to files is also possible. + * It's worthy to note that many functions require an extra parameter of type currdir + * because the structure of import directories make it necessary that the OLDDIR import directory + * must be preserved. That's why some functions (like adding and removing) imported functions + * only exist for the new import directory, not for the one which is already written to the file. + * \todo Adding functions by ordinal doesn't work yet (rebuild needs to be changed). + * \todo Somehow store the rvas of the chunks in the file. + **/ + template<int bits> + class ImportDirectory + { + typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::iterator ImpDirFileIterator; + typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::const_iterator ConstImpDirFileIterator; + + private: + /// Stores information about already imported DLLs. + std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vOldiid; + /// Stores information about imported DLLs which will be added. + std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vNewiid; + + // I can't convince Borland C++ to compile the function outside of the class declaration. + // That's why the function definition is here. + /// Tests if a certain function is imported. + template<typename T> bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA<bits>::* comp)(T) const) const + { + ConstImpDirFileIterator FileIter = m_vOldiid.begin(); + ConstImpDirFileIterator EndIter = m_vOldiid.end(); + + for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid + { + do + { + FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); + + if (FileIter != EndIter) + { + typename std::vector<PELIB_THUNK_DATA<bits> >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value)); + if (Iter != FileIter->originalfirstthunk.end()) + { + return true; + } + ++FileIter; + } + } + while (FileIter != EndIter); + + FileIter = m_vNewiid.begin(); + EndIter = m_vNewiid.end(); + } + + return false; + } + + + public: + + /// Add a function to the import directory. + int addFunction(const std::string& strFilename, word wHint); // EXPORT _byHint + /// Add a function to the import directory. + int addFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName + + /// Get the ID of a file through it's name. + unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; // EXPORT + /// Get the ID of a function through it's name. + unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; // EXPORT + + /// Get the name of an imported file. + std::string getFileName(dword dwFilenr, currdir cdDir) const; // EXPORT + + void setFileName(dword filenr, currdir dir, const std::string& name); // EXPORT + + /// Get the hint of an imported function. + word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT + void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); // EXPORT + /// Get the name of an imported function. + std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT + void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); // EXPORT + /// Get the number of files which are imported. + dword getNumberOfFiles(currdir cdDir) const; // EXPORT + /// Get the number of fucntions which are imported by a specific file. + dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; // EXPORT + /// Read a file's import directory. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader); // EXPORT + /// Rebuild the import directory. + void rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries = true) const; // EXPORT + /// Remove a file from the import directory. + int removeFile(const std::string& strFilename); // EXPORT + /// Remove a function from the import directory. + int removeFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName + /// Remove a function from the import directory. + int removeFunction(const std::string& strFilename, word wHint); // EXPORT _byHint + /// Returns the size of the current import directory. + unsigned int size() const; // EXPORT + /// Writes the import directory to a file. + int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); // EXPORT + + /// Returns the FirstThunk value of a function. + dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber + void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT _byNumber + /// Returns the OriginalFirstThunk value of a function. + dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber + void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT + +// dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); +// dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); + + /// Returns the FirstThunk value of a file. + dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the OriginalFirstThunk value of a file. + dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the ForwarderChain value of a file. + dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the TimeDateStamp value of a file. + dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + + /// Returns the FirstThunk value of a file. + dword getFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT + void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + /// Returns the OriginalFirstThunk value of a file. + dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT + void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + /// Returns the ForwarderChain value of a file. + dword getForwarderChain(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber + void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + dword getRvaOfName(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber + void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); // EXPORT + /// Returns the TimeDateStamp value of a file. + dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; // EXPORT + void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber + +// word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); + }; + + /** + * Add another import (by Ordinal) to the current file. Note that the import table is not automatically updated. + * The new imported functions will be added when you recalculate the import table as it's necessary + * to specify the address the import table will have in the file. + * @param strFilename The name of a DLL. + * @param wHint The ordinal of the function in the DLL. + **/ + template<int bits> + int ImportDirectory<bits>::addFunction(const std::string& strFilename, word wHint) + { + if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA<bits>::equalHint)) + { + return ERROR_DUPLICATE_ENTRY; + } + + // Find the imported file. + ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); + + PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid; + PELIB_THUNK_DATA<bits> td; + td.hint = wHint; + td.itd.Ordinal = wHint | PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG; + iid.name = strFilename; + if (FileIter == m_vNewiid.end()) + { + iid.originalfirstthunk.push_back(td); + iid.firstthunk.push_back(td); + m_vNewiid.push_back(iid); + } + else + { + FileIter->originalfirstthunk.push_back(td); + FileIter->firstthunk.push_back(td); + } + + return NO_ERROR; + } + + /** + * Add a function to the Import Directory. + * @param strFilename Name of the file which will be imported + * @param strFuncname Name of the function which will be imported. + **/ + template<int bits> + int ImportDirectory<bits>::addFunction(const std::string& strFilename, const std::string& strFuncname) + { + if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA<bits>::equalFunctionName)) + { + return ERROR_DUPLICATE_ENTRY; + } + + // Find the imported file. + ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); + + PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid; + PELIB_THUNK_DATA<bits> td; + td.fname = strFuncname; + iid.name = strFilename; + if (FileIter == m_vNewiid.end()) + { + iid.originalfirstthunk.push_back(td); + iid.firstthunk.push_back(td); + m_vNewiid.push_back(iid); + } + else + { + FileIter->originalfirstthunk.push_back(td); + FileIter->firstthunk.push_back(td); + } + + return NO_ERROR; + } + + /** + * Searches through the import directory and returns the number of the import + * directory entry which belongs to the given filename. + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return The ID of an imported file. + **/ + template<int bits> + unsigned int ImportDirectory<bits>::getFileIndex(const std::string& strFilename, currdir cdDir) const + { + const std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >* currDir; + + if (cdDir == OLDDIR) + { + currDir = &m_vOldiid; + } + else + { + currDir = &m_vNewiid; + } + + ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); + + if (FileIter != currDir->end()) + { + return static_cast<unsigned int>(std::distance(currDir->begin(), FileIter)); + } + else + { + return -1; + // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__); + } + + return NO_ERROR; + } + + /** + * Searches through an imported file for a specific function. + * @param strFilename Name of the imported file. + * @param strFuncname Name of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ID of the imported function. + **/ + template<int bits> + unsigned int ImportDirectory<bits>::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const + { + unsigned int uiFile = getFileIndex(strFilename, cdDir); + + for (unsigned int i=0;i<getNumberOfFunctions(uiFile, cdDir);i++) + { + if (getFunctionName(uiFile, i, cdDir) == strFuncname) return i; + } + + return -1; + } + + /** + * Get the name of an imported file. + * @param dwFilenr Identifies which file should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Name of an imported file. + **/ + template<int bits> + std::string ImportDirectory<bits>::getFileName(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name; + else return m_vNewiid[dwFilenr].name; + } + + template<int bits> + void ImportDirectory<bits>::setFileName(dword filenr, currdir dir, const std::string& name) + { + if (dir == OLDDIR) m_vOldiid[filenr].name = name; + else m_vNewiid[filenr].name = name; + } + + /** + * Get the name of an imported function. + * @param dwFilenr Identifies which file should be checked. + * @param dwFuncnr Identifies which function should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Name of an imported function. + * \todo Marked line is unsafe (function should be rewritten). + **/ + template<int bits> + std::string ImportDirectory<bits>::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + // Unsafe + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; + } + else + { + return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname; + } + } + else + { + if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; + } + else + { + return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname; + } + } + } + + template<int bits> + void ImportDirectory<bits>::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName) + { + if (cdDir == OLDDIR) + { + // Unsafe + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; + } + else + { + m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; + } + } + else + { + if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; + } + else + { + m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; + } + } + } + + /** + * Get the hint of an imported function. + * @param dwFilenr Identifies which file should be checked. + * @param dwFuncnr Identifies which function should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Hint of an imported function. + **/ + template<int bits> + word ImportDirectory<bits>::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; + } + else + { + return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint; + } + } + else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; + } + + template<int bits> + void ImportDirectory<bits>::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value) + { + if (cdDir == OLDDIR) + { + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; + } + else + { + m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value; + } + } + else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; + } + + /** + * Get the number of files which are currently being imported. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Number of files which are currently being imported. + **/ + template<int bits> + dword ImportDirectory<bits>::getNumberOfFiles(currdir cdDir) const + { + if (cdDir == OLDDIR) return static_cast<dword>(m_vOldiid.size()); + else return static_cast<dword>(m_vNewiid.size()); + } + + /** + * Get the number of functions which are currently being imported from a specific file. + * @param dwFilenr Identifies which file should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Number of functions which are currently being imported from a specific file. + **/ + template<int bits> + dword ImportDirectory<bits>::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) return static_cast<unsigned int>(m_vOldiid[dwFilenr].firstthunk.size()); + else return static_cast<unsigned int>(m_vNewiid[dwFilenr].firstthunk.size()); + } + + /** + * Read an import directory from a file. + * \todo Check if streams failed. + * @param strFilename Name of the file which will be read. + * @param uiOffset Offset of the import directory (see #PeLib::PeHeader::getIDImportRVA). + * @param uiSize Size of the import directory (see #PeLib::PeHeader::getIDImportSize). + * @param pehHeader A valid PE header. + **/ + template<int bits> + int ImportDirectory<bits>::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader) + { + std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + unsigned int uiFileSize = fileSize(ifFile); + + if (uiFileSize < uiOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(uiOffset, std::ios_base::beg); + + std::vector<unsigned char> vImportdirectory(uiSize); + ifFile.read(reinterpret_cast<char*>(&vImportdirectory[0]), uiSize); + + PELIB_IMAGE_IMPORT_DIRECTORY<bits> iidCurr; + unsigned int uiDesccounter = 0; + + InputBuffer inpBuffer(vImportdirectory); + + std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > vOldIidCurr; + + do // Read and store all descriptors + { + inpBuffer >> iidCurr.impdesc.OriginalFirstThunk; + inpBuffer >> iidCurr.impdesc.TimeDateStamp; + inpBuffer >> iidCurr.impdesc.ForwarderChain; + inpBuffer >> iidCurr.impdesc.Name; + inpBuffer >> iidCurr.impdesc.FirstThunk; + + if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || + iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0) + { + vOldIidCurr.push_back(iidCurr); + } + + uiDesccounter++; + + if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break; + } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || + iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0); + + char namebuffer[2] = {0}; + + // Name + for (unsigned int i=0;i<vOldIidCurr.size();i++) + { + ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg); + + std::string dllname = ""; + + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + dllname += namebuffer; + } while (true); + + vOldIidCurr[i].name = dllname; + + } + + // OriginalFirstThunk + for (unsigned int i=0;i<vOldIidCurr.size();i++) + { + PELIB_THUNK_DATA<bits> tdCurr; + dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk; + + if (!uiVaoft) + { + continue; + } + + ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); + + do + { + if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) + { + return ERROR_INVALID_FILE; + } + uiVaoft += sizeof(tdCurr.itd.Ordinal); + + ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); + if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr); + } while (tdCurr.itd.Ordinal); + } + + // FirstThunk + for (unsigned int i=0;i<vOldIidCurr.size();i++) + { + dword uiVaoft = vOldIidCurr[i].impdesc.FirstThunk; + PELIB_THUNK_DATA<bits> tdCurr; + + ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); + + do + { + if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) + { + return ERROR_INVALID_FILE; + } + + uiVaoft += sizeof(tdCurr.itd.Ordinal); + + ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); + if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr); + } while (tdCurr.itd.Ordinal); + } + + // Names + for (unsigned int i=0;i<vOldIidCurr.size();i++) + { + if (vOldIidCurr[i].impdesc.OriginalFirstThunk) + { + for (unsigned int j=0;j<vOldIidCurr[i].originalfirstthunk.size();j++) + { + if (vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG) + { + vOldIidCurr[i].originalfirstthunk[j].hint = 0; + continue; + } + + ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg); + + ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + std::string funcname = ""; + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + funcname += namebuffer; + } while (true); + + vOldIidCurr[i].originalfirstthunk[j].fname = funcname; + } + } + else + { + for (unsigned int j=0;j<vOldIidCurr[i].firstthunk.size();j++) + { + if (vOldIidCurr[i].firstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG) + { + continue; + } + + ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg); + + ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + std::string funcname = ""; + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + funcname += namebuffer; + } while (true); + + vOldIidCurr[i].firstthunk[j].fname = funcname; + } + } + } + std::swap(vOldIidCurr, m_vOldiid); + return NO_ERROR; + } + + /** + * Rebuilds the import directory. + * @param vBuffer Buffer the rebuilt import directory will be written to. + * @param dwRva The RVA of the ImportDirectory in the file. + * \todo uiSizeoffuncnames is not used. + **/ + template<int bits> + void ImportDirectory<bits>::rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries) const + { + unsigned int uiImprva = dwRva; + unsigned int uiSizeofdescriptors = (static_cast<unsigned int>(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); + + unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0; + unsigned int uiSizeofoft = 0; + + for (unsigned int i=0;i<m_vNewiid.size();i++) + { + uiSizeofdllnames += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1; + uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); + + for(unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) + { + // +3 for hint (word) and 00-byte + uiSizeoffuncnames += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3); + } + } + +// for (unsigned int i=0;i<m_vNewiid.size();i++) +// { +// uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); +// } + + OutputBuffer obBuffer(vBuffer); + + // Rebuild IMAGE_IMPORT_DESCRIPTORS + for (unsigned int i=0;i<m_vOldiid.size();i++) + { + obBuffer << m_vOldiid[i].impdesc.OriginalFirstThunk; + obBuffer << m_vOldiid[i].impdesc.TimeDateStamp; + obBuffer << m_vOldiid[i].impdesc.ForwarderChain; + obBuffer << m_vOldiid[i].impdesc.Name; + obBuffer << m_vOldiid[i].impdesc.FirstThunk; + } + + unsigned int dllsize = 0; + + for (unsigned int i=0;i<m_vNewiid.size();i++) + { + dword dwPoft = uiSizeofdescriptors + uiImprva; + + for (unsigned int j=1;j<=i;j++) + { + dwPoft += (static_cast<unsigned int>(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); + } + + obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk); + obBuffer << m_vNewiid[i].impdesc.TimeDateStamp; + obBuffer << m_vNewiid[i].impdesc.ForwarderChain; + dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize; + obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name); + obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk); + + dllsize += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1; + } + + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + + unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva; + + // Rebuild original first thunk + for (unsigned int i=0;i<m_vNewiid.size();i++) + { + for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) + { + if (m_vNewiid[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG + || fixEntries == false) + { + obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal; + } + else + { + obBuffer << uiPfunc; + } + uiPfunc += static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3; + } + obBuffer << (dword)0; + } + + // Write dllnames into import directory + for (unsigned int i=0;i<m_vNewiid.size();i++) + { + obBuffer.add(m_vNewiid[i].name.c_str(), static_cast<unsigned int>(m_vNewiid[i].name.size())+1); + } + + // Write function names into directory + for (unsigned int i=0;i<m_vNewiid.size();i++) + { + for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) + { + obBuffer << m_vNewiid[i].originalfirstthunk[j].hint; + obBuffer.add(m_vNewiid[i].originalfirstthunk[j].fname.c_str(), static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1); + } + } + } + + /** + * Removes a specific file and all functions of it from the import directory. + * @param strFilename Name of the file which will be removed. + **/ + template<int bits> + int ImportDirectory<bits>::removeFile(const std::string& strFilename) + { + unsigned int oldSize = static_cast<unsigned int>(m_vNewiid.size()); + + m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)), m_vNewiid.end()); + + return oldSize == m_vNewiid.size() ? 1 : 0; + } + + /** + * Removes a specific function from the import directory. + * @param strFilename Name of the file which exports the function. + * @param strFuncname Name of the imported function. + **/ + template<int bits> + int ImportDirectory<bits>::removeFunction(const std::string& strFilename, const std::string& strFuncname) + { + ImpDirFileIterator viPos = m_vNewiid.begin(); + + int notFound = 1; + + while (viPos != m_vNewiid.end()) + { + if (isEqualNc(viPos->name, strFilename)) + { + unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size()); + viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end()); + //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy<PELIB_THUNK_DATA, std::string>(), strFuncname))); + if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; + } + ++viPos; + } + + return notFound; + } + + /** + * Removes a specific function from the import directory. + * @param strFilename Name of the file which exports the function. + * @param wHint The hint of the function. + **/ + template<int bits> + int ImportDirectory<bits>::removeFunction(const std::string& strFilename, word wHint) + { + ImpDirFileIterator viPos = m_vNewiid.begin(); + int notFound = 1; + + while (viPos != m_vNewiid.end()) + { + if (isEqualNc(viPos->name, strFilename)) + { + unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size()); + viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalHint), wHint)), viPos->originalfirstthunk.end()); + unsigned int newPos = static_cast<unsigned int>(viPos->originalfirstthunk.size()); + if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; + } + ++viPos; + } + + return notFound; + } + + /** + * Writes the current import directory to a file. + * @param strFilename Name of the file. + * @param uiOffset File Offset of the new import directory. + * @param uiRva RVA which belongs to that file offset. + **/ + template<int bits> + int ImportDirectory<bits>::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios_base::beg); + + std::vector<byte> vBuffer; + + rebuild(vBuffer, uiRva); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), vBuffer.size()); + ofFile.close(); + + std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid)); + m_vNewiid.clear(); + + return NO_ERROR; + } + + /** + * Returns the size of the import directory. + * @return Size of the import directory. + **/ + template<int bits> + unsigned int ImportDirectory<bits>::size() const + { + // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to. + return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >) + + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getFirstThunk(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ForwarderChain value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getForwarderChain(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return TimeDateStamp value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; + } + } + + template<int bits> + dword ImportDirectory<bits>::getRvaOfName(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.FirstThunk; + } + else + { + return m_vNewiid[dwFilenr].impdesc.FirstThunk; + } + } + + template<int bits> + void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.FirstThunk = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.FirstThunk = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk; + } + else + { + return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk; + } + } + + template<int bits> + void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ForwarderChain value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getForwarderChain(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.ForwarderChain; + } + else + { + return m_vNewiid[dwFilenr].impdesc.ForwarderChain; + } + } + + template<int bits> + void ImportDirectory<bits>::setForwarderChain(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.ForwarderChain = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.ForwarderChain = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return TimeDateStamp value of an imported file. + **/ + template<int bits> + dword ImportDirectory<bits>::getTimeDateStamp(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.TimeDateStamp; + } + else + { + return m_vNewiid[dwFilenr].impdesc.TimeDateStamp; + } + } + + template<int bits> + void ImportDirectory<bits>::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value; + } + } + + template<int bits> + dword ImportDirectory<bits>::getRvaOfName(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.Name; + } + else + { + return m_vNewiid[dwFilenr].impdesc.Name; + } + } + + template<int bits> + void ImportDirectory<bits>::setRvaOfName(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.Name = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.Name = value; + } + } + + /** + * @param dwFilenr ID of the imported file. + * @param dwFuncnr ID of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported function. + **/ + template<int bits> + dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; + else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; + } + + template<int bits> + void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; + else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; + } + + /** + * @param dwFilenr ID of the imported file. + * @param dwFuncnr ID of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported function. + **/ + template<int bits> + dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; + else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; + } + + template<int bits> + void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; + else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; + } + + typedef ImportDirectory<32> ImportDirectory32; + typedef ImportDirectory<64> ImportDirectory64; +} + +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.cpp index 39fe54d80d..3a2119b7ac 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.cpp @@ -1,584 +1,584 @@ -/*
-* MzHeader.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "MzHeader.h"
-#include <iostream>
-
-namespace PeLib
-{
- /**
- * Reads data from an InputBuffer into the struct that represents the MZ header.
- * It's required that the size of the input buffer is at least as big as the
- * size of a MZ header. Otherwise we get undefined behaviour.
- * @param ibBuffer InputBuffer that holds the data.
- * @return A non-zero value is returned if a problem occured.
- **/
- void MzHeader::read(InputBuffer& ibBuffer)
- {
- ibBuffer >> m_idhHeader.e_magic;
- ibBuffer >> m_idhHeader.e_cblp;
- ibBuffer >> m_idhHeader.e_cp;
- ibBuffer >> m_idhHeader.e_crlc;
- ibBuffer >> m_idhHeader.e_cparhdr;
- ibBuffer >> m_idhHeader.e_minalloc;
- ibBuffer >> m_idhHeader.e_maxalloc;
- ibBuffer >> m_idhHeader.e_ss;
- ibBuffer >> m_idhHeader.e_sp;
- ibBuffer >> m_idhHeader.e_csum;
- ibBuffer >> m_idhHeader.e_ip;
- ibBuffer >> m_idhHeader.e_cs;
- ibBuffer >> m_idhHeader.e_lfarlc;
- ibBuffer >> m_idhHeader.e_ovno;
-
- for (unsigned int i=0;i<sizeof(m_idhHeader.e_res)/sizeof(m_idhHeader.e_res[0]);i++)
- {
- ibBuffer >> m_idhHeader.e_res[i];
- }
-
- ibBuffer >> m_idhHeader.e_oemid;
- ibBuffer >> m_idhHeader.e_oeminfo;
-
- for (unsigned int i=0;i<sizeof(m_idhHeader.e_res2)/sizeof(m_idhHeader.e_res2[0]);i++)
- {
- ibBuffer >> m_idhHeader.e_res2[i];
- }
-
- ibBuffer >> m_idhHeader.e_lfanew;
- }
-
- /**
- * Tests if the currently loaded MZ header is a valid MZ header.
- * Note that this function does not check if the address to the PE header is valid as this is not possible.
- * Actually, the only thing this function checks is if the e_magic value is set to 0x5A4D (IMAGE_DOS_SIGNATURE).
- * Everything else is not relevant for Windows 2000 and that's the system PeLib is focusing on for now.
- * @return A boolean value that indicates if the MZ header is correct or not.
- **/
- bool MzHeader::isValid() const
- {
- // The only thing that matters on Windows 2K is the e_magic value. The entire rest is for DOS compatibility.
- return isValid(e_magic);
- }
-
- bool MzHeader::isValid(Field f) const
- {
- if (f == e_magic)
- {
- return m_idhHeader.e_magic == PELIB_IMAGE_DOS_SIGNATURE;
- }
- else
- {
- return true;
- }
- }
-
- /**
- * Corrects all erroneous values of the current MZ header. Note that this function does not correct the
- * pointer to the PE header.
- * Actually, the only thing this function corrects is the e_magic value.
- * Everything else is not relevant for Windows 2000 and that's the system PeLib is focusing on for now.
- **/
- void MzHeader::makeValid()
- {
- // The only thing that matters on Windows is the e_magic value. The entire rest is for DOS compatibility.
- setMagicNumber(PELIB_IMAGE_DOS_SIGNATURE);
- }
-
- void MzHeader::makeValid(Field f)
- {
- if (f == e_magic)
- {
- setMagicNumber(PELIB_IMAGE_DOS_SIGNATURE);
- }
- }
-
- /**
- * Reads the MZ header from a file. Note that this function does not verify if a file is actually a MZ file.
- * For this purpose see #PeFile::MzHeader::isValid. The reason for this is simple: Otherwise it might not
- * be possible to load damaged PE files to repair them.
- * @param strFilename Name of the file which will be read.
- * @return A non-zero value is returned if a problem occured.
- **/
- int MzHeader::read(const std::string& strFilename)
- {
- std::ifstream ifFile(strFilename.c_str(), std::ios::binary);
-
- if (!ifFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- if (fileSize(ifFile) < PELIB_IMAGE_DOS_HEADER::size())
- {
- return ERROR_INVALID_FILE;
- }
-
- ifFile.seekg(0, std::ios::beg);
-
- originalOffset = 0;
-
- std::vector<byte> vBuffer(PELIB_IMAGE_DOS_HEADER::size());
- ifFile.read(reinterpret_cast<char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
- ifFile.close();
-
- InputBuffer ibBuffer(vBuffer);
- read(ibBuffer);
- return NO_ERROR;
- }
-
- /**
- * Reads the MZ header from memory. A pointer to a location in memory is passed and the data
- * at this location is treated like a MZ header structure. The MZ header does not need to be valid.
- * @param pcBuffer Pointer to a MZ header.
- * @param uiSize Length of the buffer.
- * @return A non-zero value is returned if a problem occured.
- **/
- int MzHeader::read(unsigned char* pcBuffer, unsigned int uiSize, unsigned int originalOffs)
- {
- if (uiSize < PELIB_IMAGE_DOS_HEADER::size())
- {
- return ERROR_INVALID_FILE;
- }
-
- std::vector<byte> vBuffer(pcBuffer, pcBuffer + uiSize);
- for (int i=0;i<0x40;i++) std::cout << std::hex << (int)vBuffer[i] << " ";
-
- originalOffset = originalOffs;
-
- InputBuffer ibBuffer(vBuffer);
- read(ibBuffer);
- return NO_ERROR;
- }
-
- /**
- * Rebuilds the MZ header so that it can be written to a file. It's not guaranteed that the
- * MZ header will be valid. If you want to make sure that the MZ header will be valid you
- * must call #PeLib::MzHeader::makeValid first.
- * @param vBuffer Buffer where the rebuilt MZ header will be stored.
- **/
- void MzHeader::rebuild(std::vector<byte>& vBuffer) const
- {
- OutputBuffer obBuffer(vBuffer);
-
- obBuffer << m_idhHeader.e_magic;
- obBuffer << m_idhHeader.e_cblp;
- obBuffer << m_idhHeader.e_cp;
- obBuffer << m_idhHeader.e_crlc;
- obBuffer << m_idhHeader.e_cparhdr;
- obBuffer << m_idhHeader.e_minalloc;
- obBuffer << m_idhHeader.e_maxalloc;
- obBuffer << m_idhHeader.e_ss;
- obBuffer << m_idhHeader.e_sp;
- obBuffer << m_idhHeader.e_csum;
- obBuffer << m_idhHeader.e_ip;
- obBuffer << m_idhHeader.e_cs;
- obBuffer << m_idhHeader.e_lfarlc;
- obBuffer << m_idhHeader.e_ovno;
-
- for (unsigned int i=0;i<sizeof(m_idhHeader.e_res)/sizeof(m_idhHeader.e_res[0]);i++)
- {
- obBuffer << m_idhHeader.e_res[i];
- }
-
- obBuffer << m_idhHeader.e_oemid;
- obBuffer << m_idhHeader.e_oeminfo;
-
- for (unsigned int i=0;i<sizeof(m_idhHeader.e_res2)/sizeof(m_idhHeader.e_res2[0]);i++)
- {
- obBuffer << m_idhHeader.e_res2[i];
- }
-
- obBuffer << m_idhHeader.e_lfanew;
- }
-
- /**
- * Returns the size of the MZ header. This size is actually always sizeof(IMAGE_DOS_HEADER) (== 0x40)
- * because the MZ header is a header of constant size if you disregard the dos stub. If you want to know the
- * size of the MZ header + the size of the dos stub check #PeLib::MzHeader::getAddressOfPeHeader.
- * @return Size of the MZ header.
- **/
- unsigned int MzHeader::size() const
- {
- return sizeof(m_idhHeader);
- }
-
- /**
- * Writes the current MZ header to a file. The file does not have to exist. If it doesn't exist
- * it will be created.
- * @param strFilename Name of the file the header will be written to.
- * @param dwOffset Offset the header will be written to (defaults to 0).
- * @return A non-zero value is returned if a problem occured.
- **/
- int MzHeader::write(const std::string& strFilename, dword dwOffset = 0) const
- {
- std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
-
- if (!ofFile)
- {
- ofFile.clear();
- ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
- }
- else
- {
- ofFile.close();
- ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- }
-
- if (!ofFile)
- {
- return ERROR_OPENING_FILE;
- }
-
- ofFile.seekp(dwOffset, std::ios::beg);
-
- std::vector<unsigned char> vBuffer;
-
- rebuild(vBuffer);
-
- ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size()));
-
- ofFile.close();
-
- return NO_ERROR;
- }
-
- /**
- * Returns the MZ header's e_magic value.
- **/
- word MzHeader::getMagicNumber() const
- {
- return m_idhHeader.e_magic;
- }
-
- /**
- * Returns the MZ header's e_cblp value.
- **/
- word MzHeader::getBytesOnLastPage() const
- {
- return m_idhHeader.e_cblp;
- }
-
- /**
- * Returns the MZ header's e_cp value.
- **/
- word MzHeader::getPagesInFile() const
- {
- return m_idhHeader.e_cp;
- }
-
- /**
- * Returns the MZ header's e_crlc value.
- **/
- word MzHeader::getRelocations() const
- {
- return m_idhHeader.e_crlc;
- }
-
- /**
- * Returns the MZ header's e_cparhdr value.
- **/
- word MzHeader::getSizeOfHeader() const
- {
- return m_idhHeader.e_cparhdr;
- }
-
- /**
- * Returns the MZ header's e_minalloc value.
- **/
- word MzHeader::getMinExtraParagraphs() const
- {
- return m_idhHeader.e_minalloc;
- }
-
- /**
- * Returns the MZ header's e_maxalloc value.
- **/
- word MzHeader::getMaxExtraParagraphs() const
- {
- return m_idhHeader.e_maxalloc;
- }
-
- /**
- * Returns the MZ header's e_ss value.
- **/
- word MzHeader::getSsValue() const
- {
- return m_idhHeader.e_ss;
- }
-
- /**
- * Returns the MZ header's e_sp value.
- **/
- word MzHeader::getSpValue() const
- {
- return m_idhHeader.e_sp;
- }
-
- /**
- * Returns the MZ header's e_csum value.
- **/
- word MzHeader::getChecksum() const
- {
- return m_idhHeader.e_csum;
- }
-
- /**
- * Returns the MZ header's e_ip value.
- **/
- word MzHeader::getIpValue() const
- {
- return m_idhHeader.e_ip;
- }
-
- /**
- * Returns the MZ header's e_cs value.
- **/
- word MzHeader::getCsValue() const
- {
- return m_idhHeader.e_cs;
- }
-
- /**
- * Returns the MZ header's e_lfarlc value.
- **/
- word MzHeader::getAddrOfRelocationTable() const
- {
- return m_idhHeader.e_lfarlc;
- }
-
- /**
- * Returns the MZ header's e_ovno value.
- **/
- word MzHeader::getOverlayNumber() const
- {
- return m_idhHeader.e_ovno;
- }
-
- /**
- * Returns the MZ header's e_oemid value.
- **/
- word MzHeader::getOemIdentifier() const
- {
- return m_idhHeader.e_oemid;
- }
-
- /**
- * Returns the MZ header's e_oeminfo value.
- **/
- word MzHeader::getOemInformation() const
- {
- return m_idhHeader.e_oeminfo;
- }
-
- /**
- * Returns the MZ header's e_lfanew value.
- **/
- dword MzHeader::getAddressOfPeHeader() const
- {
- return m_idhHeader.e_lfanew;
- }
-
- /**
- * Returns the MZ header's e_res[uiNr] value. If the parameter uiNr is out of range
- * you will get undefined behaviour.
- * @param uiNr The index of the word in the e_res array (valid range: 0-3)
- **/
- word MzHeader::getReservedWords1(unsigned int uiNr) const
- {
- return m_idhHeader.e_res[uiNr];
- }
-
- /**
- * Returns the MZ header's e_res2[uiNr] value. If the parameter uiNr is out of range
- * you will get undefined behaviour.
- * @param uiNr The index of the word in the e_res array (valid range: 0-9)
- **/
- word MzHeader::getReservedWords2(unsigned int uiNr) const
- {
- return m_idhHeader.e_res2[uiNr];
- }
-
- /**
- * Sets the MZ header's e_magic value.
- * @param wValue The new value of e_magic.
- **/
- void MzHeader::setMagicNumber(word wValue)
- {
- m_idhHeader.e_magic = wValue;
- }
-
- /**
- * Sets the MZ header's e_cblp value.
- * @param wValue The new value of e_cblp.
- **/
- void MzHeader::setBytesOnLastPage(word wValue)
- {
- m_idhHeader.e_cblp = wValue;
- }
-
- /**
- * Sets the MZ header's e_cp value.
- * @param wValue The new value of e_cp.
- **/
- void MzHeader::setPagesInFile(word wValue)
- {
- m_idhHeader.e_cp = wValue;
- }
-
- /**
- * Sets the MZ header's e_crlc value.
- * @param wValue The new value of e_crlc.
- **/
- void MzHeader::setRelocations(word wValue)
- {
- m_idhHeader.e_crlc = wValue;
- }
-
- /**
- * Sets the MZ header's e_cparhdr value.
- * @param wValue The new value of e_cparhdr.
- **/
- void MzHeader::setSizeOfHeader(word wValue)
- {
- m_idhHeader.e_cparhdr = wValue;
- }
-
- /**
- * Sets the MZ header's e_minalloc value.
- * @param wValue The new value of e_minalloc.
- **/
- void MzHeader::setMinExtraParagraphs(word wValue)
- {
- m_idhHeader.e_minalloc = wValue;
- }
-
- /**
- * Sets the MZ header's e_maxalloc value.
- * @param wValue The new value of e_maxalloc.
- **/
- void MzHeader::setMaxExtraParagraphs(word wValue)
- {
- m_idhHeader.e_maxalloc = wValue;
- }
-
- /**
- * Sets the MZ header's e_ss value.
- * @param wValue The new value of e_ss.
- **/
- void MzHeader::setSsValue(word wValue)
- {
- m_idhHeader.e_ss = wValue;
- }
-
- /**
- * Sets the MZ header's e_sp value.
- * @param wValue The new value of e_sp.
- **/
- void MzHeader::setSpValue(word wValue)
- {
- m_idhHeader.e_sp = wValue;
- }
-
- /**
- * Sets the MZ header's e_csum value.
- * @param wValue The new value of e_csum.
- **/
- void MzHeader::setChecksum(word wValue)
- {
- m_idhHeader.e_csum = wValue;
- }
-
- /**
- * Sets the MZ header's e_ip value.
- * @param wValue The new value of e_ip.
- **/
- void MzHeader::setIpValue(word wValue)
- {
- m_idhHeader.e_ip = wValue;
- }
-
- /**
- * Sets the MZ header's e_cs value.
- * @param wValue The new value of e_cs.
- **/
- void MzHeader::setCsValue(word wValue)
- {
- m_idhHeader.e_cs = wValue;
- }
-
- /**
- * Sets the MZ header's e_lfarlc value.
- * @param wValue The new value of e_lfarlc.
- **/
- void MzHeader::setAddrOfRelocationTable(word wValue)
- {
- m_idhHeader.e_lfarlc = wValue;
- }
-
- /**
- * Sets the MZ header's e_ovno value.
- * @param wValue The new value of e_ovno.
- **/
- void MzHeader::setOverlayNumber(word wValue)
- {
- m_idhHeader.e_ovno = wValue;
- }
-
- /**
- * Sets the MZ header's e_oemid value.
- * @param wValue The new value of e_oemid.
- **/
- void MzHeader::setOemIdentifier(word wValue)
- {
- m_idhHeader.e_oemid = wValue;
- }
-
- /**
- * Sets the MZ header's e_oeminfo value.
- * @param wValue The new value of e_oeminfo.
- **/
- void MzHeader::setOemInformation(word wValue)
- {
- m_idhHeader.e_oeminfo = wValue;
- }
-
- /**
- * Sets the MZ header's e_lfanew value.
- * @param lValue The new value of e_lfanew.
- **/
- void MzHeader::setAddressOfPeHeader(dword lValue)
- {
- m_idhHeader.e_lfanew = lValue;
- }
-
- /**
- * Sets the MZ header's e_res[uiNr] value. If the parameter uiNr is out of range
- * you will get undefined behaviour.
- * @param uiNr The index of the word in the e_res array (valid range: 0-3)
- * @param wValue The new value of e_res[nr].
- **/
- void MzHeader::setReservedWords1(unsigned int uiNr, word wValue)
- {
- m_idhHeader.e_res[uiNr] = wValue;
- }
-
- /**
- * Sets the MZ header's e_res2[uiNr] value. If the parameter uiNr is out of range
- * you will get undefined behaviour.
- * @param uiNr The index of the word in the e_res2 array (valid range: 0-9)
- * @param wValue The new value of e_res[nr].
- **/
- void MzHeader::setReservedWords2(unsigned int uiNr, word wValue)
- {
- m_idhHeader.e_res2[uiNr] = wValue;
- }
-
-}
+/* +* MzHeader.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "MzHeader.h" +#include <iostream> + +namespace PeLib +{ + /** + * Reads data from an InputBuffer into the struct that represents the MZ header. + * It's required that the size of the input buffer is at least as big as the + * size of a MZ header. Otherwise we get undefined behaviour. + * @param ibBuffer InputBuffer that holds the data. + * @return A non-zero value is returned if a problem occured. + **/ + void MzHeader::read(InputBuffer& ibBuffer) + { + ibBuffer >> m_idhHeader.e_magic; + ibBuffer >> m_idhHeader.e_cblp; + ibBuffer >> m_idhHeader.e_cp; + ibBuffer >> m_idhHeader.e_crlc; + ibBuffer >> m_idhHeader.e_cparhdr; + ibBuffer >> m_idhHeader.e_minalloc; + ibBuffer >> m_idhHeader.e_maxalloc; + ibBuffer >> m_idhHeader.e_ss; + ibBuffer >> m_idhHeader.e_sp; + ibBuffer >> m_idhHeader.e_csum; + ibBuffer >> m_idhHeader.e_ip; + ibBuffer >> m_idhHeader.e_cs; + ibBuffer >> m_idhHeader.e_lfarlc; + ibBuffer >> m_idhHeader.e_ovno; + + for (unsigned int i=0;i<sizeof(m_idhHeader.e_res)/sizeof(m_idhHeader.e_res[0]);i++) + { + ibBuffer >> m_idhHeader.e_res[i]; + } + + ibBuffer >> m_idhHeader.e_oemid; + ibBuffer >> m_idhHeader.e_oeminfo; + + for (unsigned int i=0;i<sizeof(m_idhHeader.e_res2)/sizeof(m_idhHeader.e_res2[0]);i++) + { + ibBuffer >> m_idhHeader.e_res2[i]; + } + + ibBuffer >> m_idhHeader.e_lfanew; + } + + /** + * Tests if the currently loaded MZ header is a valid MZ header. + * Note that this function does not check if the address to the PE header is valid as this is not possible. + * Actually, the only thing this function checks is if the e_magic value is set to 0x5A4D (IMAGE_DOS_SIGNATURE). + * Everything else is not relevant for Windows 2000 and that's the system PeLib is focusing on for now. + * @return A boolean value that indicates if the MZ header is correct or not. + **/ + bool MzHeader::isValid() const + { + // The only thing that matters on Windows 2K is the e_magic value. The entire rest is for DOS compatibility. + return isValid(e_magic); + } + + bool MzHeader::isValid(Field f) const + { + if (f == e_magic) + { + return m_idhHeader.e_magic == PELIB_IMAGE_DOS_SIGNATURE; + } + else + { + return true; + } + } + + /** + * Corrects all erroneous values of the current MZ header. Note that this function does not correct the + * pointer to the PE header. + * Actually, the only thing this function corrects is the e_magic value. + * Everything else is not relevant for Windows 2000 and that's the system PeLib is focusing on for now. + **/ + void MzHeader::makeValid() + { + // The only thing that matters on Windows is the e_magic value. The entire rest is for DOS compatibility. + setMagicNumber(PELIB_IMAGE_DOS_SIGNATURE); + } + + void MzHeader::makeValid(Field f) + { + if (f == e_magic) + { + setMagicNumber(PELIB_IMAGE_DOS_SIGNATURE); + } + } + + /** + * Reads the MZ header from a file. Note that this function does not verify if a file is actually a MZ file. + * For this purpose see #PeFile::MzHeader::isValid. The reason for this is simple: Otherwise it might not + * be possible to load damaged PE files to repair them. + * @param strFilename Name of the file which will be read. + * @return A non-zero value is returned if a problem occured. + **/ + int MzHeader::read(const std::string& strFilename) + { + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + if (fileSize(ifFile) < PELIB_IMAGE_DOS_HEADER::size()) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(0, std::ios::beg); + + originalOffset = 0; + + std::vector<byte> vBuffer(PELIB_IMAGE_DOS_HEADER::size()); + ifFile.read(reinterpret_cast<char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + ifFile.close(); + + InputBuffer ibBuffer(vBuffer); + read(ibBuffer); + return NO_ERROR; + } + + /** + * Reads the MZ header from memory. A pointer to a location in memory is passed and the data + * at this location is treated like a MZ header structure. The MZ header does not need to be valid. + * @param pcBuffer Pointer to a MZ header. + * @param uiSize Length of the buffer. + * @return A non-zero value is returned if a problem occured. + **/ + int MzHeader::read(unsigned char* pcBuffer, unsigned int uiSize, unsigned int originalOffs) + { + if (uiSize < PELIB_IMAGE_DOS_HEADER::size()) + { + return ERROR_INVALID_FILE; + } + + std::vector<byte> vBuffer(pcBuffer, pcBuffer + uiSize); + for (int i=0;i<0x40;i++) std::cout << std::hex << (int)vBuffer[i] << " "; + + originalOffset = originalOffs; + + InputBuffer ibBuffer(vBuffer); + read(ibBuffer); + return NO_ERROR; + } + + /** + * Rebuilds the MZ header so that it can be written to a file. It's not guaranteed that the + * MZ header will be valid. If you want to make sure that the MZ header will be valid you + * must call #PeLib::MzHeader::makeValid first. + * @param vBuffer Buffer where the rebuilt MZ header will be stored. + **/ + void MzHeader::rebuild(std::vector<byte>& vBuffer) const + { + OutputBuffer obBuffer(vBuffer); + + obBuffer << m_idhHeader.e_magic; + obBuffer << m_idhHeader.e_cblp; + obBuffer << m_idhHeader.e_cp; + obBuffer << m_idhHeader.e_crlc; + obBuffer << m_idhHeader.e_cparhdr; + obBuffer << m_idhHeader.e_minalloc; + obBuffer << m_idhHeader.e_maxalloc; + obBuffer << m_idhHeader.e_ss; + obBuffer << m_idhHeader.e_sp; + obBuffer << m_idhHeader.e_csum; + obBuffer << m_idhHeader.e_ip; + obBuffer << m_idhHeader.e_cs; + obBuffer << m_idhHeader.e_lfarlc; + obBuffer << m_idhHeader.e_ovno; + + for (unsigned int i=0;i<sizeof(m_idhHeader.e_res)/sizeof(m_idhHeader.e_res[0]);i++) + { + obBuffer << m_idhHeader.e_res[i]; + } + + obBuffer << m_idhHeader.e_oemid; + obBuffer << m_idhHeader.e_oeminfo; + + for (unsigned int i=0;i<sizeof(m_idhHeader.e_res2)/sizeof(m_idhHeader.e_res2[0]);i++) + { + obBuffer << m_idhHeader.e_res2[i]; + } + + obBuffer << m_idhHeader.e_lfanew; + } + + /** + * Returns the size of the MZ header. This size is actually always sizeof(IMAGE_DOS_HEADER) (== 0x40) + * because the MZ header is a header of constant size if you disregard the dos stub. If you want to know the + * size of the MZ header + the size of the dos stub check #PeLib::MzHeader::getAddressOfPeHeader. + * @return Size of the MZ header. + **/ + unsigned int MzHeader::size() const + { + return sizeof(m_idhHeader); + } + + /** + * Writes the current MZ header to a file. The file does not have to exist. If it doesn't exist + * it will be created. + * @param strFilename Name of the file the header will be written to. + * @param dwOffset Offset the header will be written to (defaults to 0). + * @return A non-zero value is returned if a problem occured. + **/ + int MzHeader::write(const std::string& strFilename, dword dwOffset = 0) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(dwOffset, std::ios::beg); + + std::vector<unsigned char> vBuffer; + + rebuild(vBuffer); + + ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), static_cast<unsigned int>(vBuffer.size())); + + ofFile.close(); + + return NO_ERROR; + } + + /** + * Returns the MZ header's e_magic value. + **/ + word MzHeader::getMagicNumber() const + { + return m_idhHeader.e_magic; + } + + /** + * Returns the MZ header's e_cblp value. + **/ + word MzHeader::getBytesOnLastPage() const + { + return m_idhHeader.e_cblp; + } + + /** + * Returns the MZ header's e_cp value. + **/ + word MzHeader::getPagesInFile() const + { + return m_idhHeader.e_cp; + } + + /** + * Returns the MZ header's e_crlc value. + **/ + word MzHeader::getRelocations() const + { + return m_idhHeader.e_crlc; + } + + /** + * Returns the MZ header's e_cparhdr value. + **/ + word MzHeader::getSizeOfHeader() const + { + return m_idhHeader.e_cparhdr; + } + + /** + * Returns the MZ header's e_minalloc value. + **/ + word MzHeader::getMinExtraParagraphs() const + { + return m_idhHeader.e_minalloc; + } + + /** + * Returns the MZ header's e_maxalloc value. + **/ + word MzHeader::getMaxExtraParagraphs() const + { + return m_idhHeader.e_maxalloc; + } + + /** + * Returns the MZ header's e_ss value. + **/ + word MzHeader::getSsValue() const + { + return m_idhHeader.e_ss; + } + + /** + * Returns the MZ header's e_sp value. + **/ + word MzHeader::getSpValue() const + { + return m_idhHeader.e_sp; + } + + /** + * Returns the MZ header's e_csum value. + **/ + word MzHeader::getChecksum() const + { + return m_idhHeader.e_csum; + } + + /** + * Returns the MZ header's e_ip value. + **/ + word MzHeader::getIpValue() const + { + return m_idhHeader.e_ip; + } + + /** + * Returns the MZ header's e_cs value. + **/ + word MzHeader::getCsValue() const + { + return m_idhHeader.e_cs; + } + + /** + * Returns the MZ header's e_lfarlc value. + **/ + word MzHeader::getAddrOfRelocationTable() const + { + return m_idhHeader.e_lfarlc; + } + + /** + * Returns the MZ header's e_ovno value. + **/ + word MzHeader::getOverlayNumber() const + { + return m_idhHeader.e_ovno; + } + + /** + * Returns the MZ header's e_oemid value. + **/ + word MzHeader::getOemIdentifier() const + { + return m_idhHeader.e_oemid; + } + + /** + * Returns the MZ header's e_oeminfo value. + **/ + word MzHeader::getOemInformation() const + { + return m_idhHeader.e_oeminfo; + } + + /** + * Returns the MZ header's e_lfanew value. + **/ + dword MzHeader::getAddressOfPeHeader() const + { + return m_idhHeader.e_lfanew; + } + + /** + * Returns the MZ header's e_res[uiNr] value. If the parameter uiNr is out of range + * you will get undefined behaviour. + * @param uiNr The index of the word in the e_res array (valid range: 0-3) + **/ + word MzHeader::getReservedWords1(unsigned int uiNr) const + { + return m_idhHeader.e_res[uiNr]; + } + + /** + * Returns the MZ header's e_res2[uiNr] value. If the parameter uiNr is out of range + * you will get undefined behaviour. + * @param uiNr The index of the word in the e_res array (valid range: 0-9) + **/ + word MzHeader::getReservedWords2(unsigned int uiNr) const + { + return m_idhHeader.e_res2[uiNr]; + } + + /** + * Sets the MZ header's e_magic value. + * @param wValue The new value of e_magic. + **/ + void MzHeader::setMagicNumber(word wValue) + { + m_idhHeader.e_magic = wValue; + } + + /** + * Sets the MZ header's e_cblp value. + * @param wValue The new value of e_cblp. + **/ + void MzHeader::setBytesOnLastPage(word wValue) + { + m_idhHeader.e_cblp = wValue; + } + + /** + * Sets the MZ header's e_cp value. + * @param wValue The new value of e_cp. + **/ + void MzHeader::setPagesInFile(word wValue) + { + m_idhHeader.e_cp = wValue; + } + + /** + * Sets the MZ header's e_crlc value. + * @param wValue The new value of e_crlc. + **/ + void MzHeader::setRelocations(word wValue) + { + m_idhHeader.e_crlc = wValue; + } + + /** + * Sets the MZ header's e_cparhdr value. + * @param wValue The new value of e_cparhdr. + **/ + void MzHeader::setSizeOfHeader(word wValue) + { + m_idhHeader.e_cparhdr = wValue; + } + + /** + * Sets the MZ header's e_minalloc value. + * @param wValue The new value of e_minalloc. + **/ + void MzHeader::setMinExtraParagraphs(word wValue) + { + m_idhHeader.e_minalloc = wValue; + } + + /** + * Sets the MZ header's e_maxalloc value. + * @param wValue The new value of e_maxalloc. + **/ + void MzHeader::setMaxExtraParagraphs(word wValue) + { + m_idhHeader.e_maxalloc = wValue; + } + + /** + * Sets the MZ header's e_ss value. + * @param wValue The new value of e_ss. + **/ + void MzHeader::setSsValue(word wValue) + { + m_idhHeader.e_ss = wValue; + } + + /** + * Sets the MZ header's e_sp value. + * @param wValue The new value of e_sp. + **/ + void MzHeader::setSpValue(word wValue) + { + m_idhHeader.e_sp = wValue; + } + + /** + * Sets the MZ header's e_csum value. + * @param wValue The new value of e_csum. + **/ + void MzHeader::setChecksum(word wValue) + { + m_idhHeader.e_csum = wValue; + } + + /** + * Sets the MZ header's e_ip value. + * @param wValue The new value of e_ip. + **/ + void MzHeader::setIpValue(word wValue) + { + m_idhHeader.e_ip = wValue; + } + + /** + * Sets the MZ header's e_cs value. + * @param wValue The new value of e_cs. + **/ + void MzHeader::setCsValue(word wValue) + { + m_idhHeader.e_cs = wValue; + } + + /** + * Sets the MZ header's e_lfarlc value. + * @param wValue The new value of e_lfarlc. + **/ + void MzHeader::setAddrOfRelocationTable(word wValue) + { + m_idhHeader.e_lfarlc = wValue; + } + + /** + * Sets the MZ header's e_ovno value. + * @param wValue The new value of e_ovno. + **/ + void MzHeader::setOverlayNumber(word wValue) + { + m_idhHeader.e_ovno = wValue; + } + + /** + * Sets the MZ header's e_oemid value. + * @param wValue The new value of e_oemid. + **/ + void MzHeader::setOemIdentifier(word wValue) + { + m_idhHeader.e_oemid = wValue; + } + + /** + * Sets the MZ header's e_oeminfo value. + * @param wValue The new value of e_oeminfo. + **/ + void MzHeader::setOemInformation(word wValue) + { + m_idhHeader.e_oeminfo = wValue; + } + + /** + * Sets the MZ header's e_lfanew value. + * @param lValue The new value of e_lfanew. + **/ + void MzHeader::setAddressOfPeHeader(dword lValue) + { + m_idhHeader.e_lfanew = lValue; + } + + /** + * Sets the MZ header's e_res[uiNr] value. If the parameter uiNr is out of range + * you will get undefined behaviour. + * @param uiNr The index of the word in the e_res array (valid range: 0-3) + * @param wValue The new value of e_res[nr]. + **/ + void MzHeader::setReservedWords1(unsigned int uiNr, word wValue) + { + m_idhHeader.e_res[uiNr] = wValue; + } + + /** + * Sets the MZ header's e_res2[uiNr] value. If the parameter uiNr is out of range + * you will get undefined behaviour. + * @param uiNr The index of the word in the e_res2 array (valid range: 0-9) + * @param wValue The new value of e_res[nr]. + **/ + void MzHeader::setReservedWords2(unsigned int uiNr, word wValue) + { + m_idhHeader.e_res2[uiNr] = wValue; + } + +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.h b/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.h index 5aca6bfe59..4acb819727 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/MzHeader.h @@ -1,148 +1,148 @@ -/*
-* MzHeader.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef MZHEADER_H
-#define MZHEADER_H
-
-#include "PeLibInc.h"
-
-namespace PeLib
-{
- /// Class that handles the MZ header of files.
- /**
- * This class can read and modify MZ headers. It provides set- and get functions to access
- * all individual members of a MZ header. Furthermore it's possible to validate and rebuild
- * MZ headers.
- **/
- class MzHeader
- {
- private:
- PELIB_IMAGE_DOS_HEADER m_idhHeader; ///< Stores all MZ header information.
-
- /// Reads data from an InputBuffer into a MZ header struct.
- void read(InputBuffer& ibBuffer);
-
- /// Offset of the MZ header in the original file.
- unsigned int originalOffset;
-
- public:
-
- enum Field {e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc,
- e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno, e_res, e_oemid,
- e_oeminfo, e_res2, e_lfanew};
-
- /// Checks if the current MZ header is valid.
- bool isValid() const; // EXPORT
-
- bool isValid(Field field) const; // EXPORT _field
-
- /// Corrects the current MZ header.
- void makeValid(); // EXPORT
-
- void makeValid(Field field); // EXPORT _field
-
- /// Reads the MZ header of a file.
- int read(const std::string& strFilename); // EXPORT
-
- /// Reads the MZ header from a memory location.
- int read(unsigned char* pcBuffer, unsigned int uiSize, unsigned int originalOffs = 0); // EXPORT _fromMemory
-
- /// Rebuild the MZ header.
- void rebuild(std::vector<byte>& vBuffer) const; // EXPORT
-
- /// Returns the size of the current MZ header.
- unsigned int size() const; // EXPORT
-
- /// Writes the current MZ header to offset 0 of a file.
- int write(const std::string& strFilename, dword dwOffset) const; // EXPORT
-
- /// Gets the e_magic value of the MZ header.
- word getMagicNumber() const; // EXPORT
- /// Gets the e_cblp value of the MZ header.
- word getBytesOnLastPage() const; // EXPORT
- /// Gets the e_cp value of the MZ header.
- word getPagesInFile() const; // EXPORT
- /// Gets the e_crlc value of the MZ header.
- word getRelocations() const; // EXPORT
- /// Gets the e_cparhdr value of the MZ header.
- word getSizeOfHeader() const; // EXPORT
- /// Gets the e_minalloc value of the MZ header.
- word getMinExtraParagraphs() const; // EXPORT
- /// Gets the e_maxalloc value of the MZ header.
- word getMaxExtraParagraphs() const; // EXPORT
- /// Gets the e_ss value of the MZ header.
- word getSsValue() const; // EXPORT
- /// Gets the e_sp value of the MZ header.
- word getSpValue() const; // EXPORT
- /// Gets the e_csum value of the MZ header.
- word getChecksum() const; // EXPORT
- /// Gets the e_ip value of the MZ header.
- word getIpValue() const; // EXPORT
- /// Gets the e_cs value of the MZ header.
- word getCsValue() const; // EXPORT
- /// Gets the e_lfarlc value of the MZ header.
- word getAddrOfRelocationTable() const; // EXPORT
- /// Gets the e_ovnovalue of the MZ header.
- word getOverlayNumber() const; // EXPORT
- /// Gets the e_oemid value of the MZ header.
- word getOemIdentifier() const; // EXPORT
- /// Gets the e_oeminfo value of the MZ header.
- word getOemInformation() const; // EXPORT
- /// Gets the e_lfanew value of the MZ header.
- dword getAddressOfPeHeader() const; // EXPORT
- /// Gets the e_res of the MZ header.
- word getReservedWords1(unsigned int uiNr) const; // EXPORT
- /// Gets the e_res2 of the MZ header.
- word getReservedWords2(unsigned int uiNr) const; // EXPORT
-
- /// Sets the e_magic value of the MZ header.
- void setMagicNumber(word wValue); // EXPORT
- /// Sets the e_cblp value of the MZ header.
- void setBytesOnLastPage(word wValue); // EXPORT
- /// Sets the e_cp value of the MZ header.
- void setPagesInFile(word wValue); // EXPORT
- /// Sets the e_crlc value of the MZ header.
- void setRelocations(word wValue); // EXPORT
- /// Sets the e_cparhdr value of the MZ header.
- void setSizeOfHeader(word wValue); // EXPORT
- /// Sets the e_minalloc value of the MZ header.
- void setMinExtraParagraphs(word wValue); // EXPORT
- /// Sets the e_maxalloc value of the MZ header.
- void setMaxExtraParagraphs(word wValue); // EXPORT
- /// Sets the e_ss value of the MZ header.
- void setSsValue(word wValue); // EXPORT
- /// Sets the e_sp value of the MZ header.
- void setSpValue(word wValue); // EXPORT
- /// Sets the e_csum value of the MZ header.
- void setChecksum(word wValue); // EXPORT
- /// Sets the e_ip value of the MZ header.
- void setIpValue(word wValue); // EXPORT
- /// Sets the e_cs value of the MZ header.
- void setCsValue(word wValue); // EXPORT
- /// Sets the e_lfarlc value of the MZ header.
- void setAddrOfRelocationTable(word wValue); // EXPORT
- /// Sets the e_ovno value of the MZ header.
- void setOverlayNumber(word wValue); // EXPORT
- /// Sets the e_oemid value of the MZ header.
- void setOemIdentifier(word wValue); // EXPORT
- /// Sets the e_oeminfo value of the MZ header.
- void setOemInformation(word wValue); // EXPORT
- /// Sets the e_lfanew value of the MZ header.
- void setAddressOfPeHeader(dword dwValue); // EXPORT
- /// Sets the e_res value of the MZ header.
- void setReservedWords1(unsigned int uiNr, word wValue); // EXPORT
- /// Sets the e_res2 value of the MZ header.
- void setReservedWords2(unsigned int uiNr, word wValue); // EXPORT
- };
-}
-
-#endif
+/* +* MzHeader.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef MZHEADER_H +#define MZHEADER_H + +#include "PeLibInc.h" + +namespace PeLib +{ + /// Class that handles the MZ header of files. + /** + * This class can read and modify MZ headers. It provides set- and get functions to access + * all individual members of a MZ header. Furthermore it's possible to validate and rebuild + * MZ headers. + **/ + class MzHeader + { + private: + PELIB_IMAGE_DOS_HEADER m_idhHeader; ///< Stores all MZ header information. + + /// Reads data from an InputBuffer into a MZ header struct. + void read(InputBuffer& ibBuffer); + + /// Offset of the MZ header in the original file. + unsigned int originalOffset; + + public: + + enum Field {e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc, + e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno, e_res, e_oemid, + e_oeminfo, e_res2, e_lfanew}; + + /// Checks if the current MZ header is valid. + bool isValid() const; // EXPORT + + bool isValid(Field field) const; // EXPORT _field + + /// Corrects the current MZ header. + void makeValid(); // EXPORT + + void makeValid(Field field); // EXPORT _field + + /// Reads the MZ header of a file. + int read(const std::string& strFilename); // EXPORT + + /// Reads the MZ header from a memory location. + int read(unsigned char* pcBuffer, unsigned int uiSize, unsigned int originalOffs = 0); // EXPORT _fromMemory + + /// Rebuild the MZ header. + void rebuild(std::vector<byte>& vBuffer) const; // EXPORT + + /// Returns the size of the current MZ header. + unsigned int size() const; // EXPORT + + /// Writes the current MZ header to offset 0 of a file. + int write(const std::string& strFilename, dword dwOffset) const; // EXPORT + + /// Gets the e_magic value of the MZ header. + word getMagicNumber() const; // EXPORT + /// Gets the e_cblp value of the MZ header. + word getBytesOnLastPage() const; // EXPORT + /// Gets the e_cp value of the MZ header. + word getPagesInFile() const; // EXPORT + /// Gets the e_crlc value of the MZ header. + word getRelocations() const; // EXPORT + /// Gets the e_cparhdr value of the MZ header. + word getSizeOfHeader() const; // EXPORT + /// Gets the e_minalloc value of the MZ header. + word getMinExtraParagraphs() const; // EXPORT + /// Gets the e_maxalloc value of the MZ header. + word getMaxExtraParagraphs() const; // EXPORT + /// Gets the e_ss value of the MZ header. + word getSsValue() const; // EXPORT + /// Gets the e_sp value of the MZ header. + word getSpValue() const; // EXPORT + /// Gets the e_csum value of the MZ header. + word getChecksum() const; // EXPORT + /// Gets the e_ip value of the MZ header. + word getIpValue() const; // EXPORT + /// Gets the e_cs value of the MZ header. + word getCsValue() const; // EXPORT + /// Gets the e_lfarlc value of the MZ header. + word getAddrOfRelocationTable() const; // EXPORT + /// Gets the e_ovnovalue of the MZ header. + word getOverlayNumber() const; // EXPORT + /// Gets the e_oemid value of the MZ header. + word getOemIdentifier() const; // EXPORT + /// Gets the e_oeminfo value of the MZ header. + word getOemInformation() const; // EXPORT + /// Gets the e_lfanew value of the MZ header. + dword getAddressOfPeHeader() const; // EXPORT + /// Gets the e_res of the MZ header. + word getReservedWords1(unsigned int uiNr) const; // EXPORT + /// Gets the e_res2 of the MZ header. + word getReservedWords2(unsigned int uiNr) const; // EXPORT + + /// Sets the e_magic value of the MZ header. + void setMagicNumber(word wValue); // EXPORT + /// Sets the e_cblp value of the MZ header. + void setBytesOnLastPage(word wValue); // EXPORT + /// Sets the e_cp value of the MZ header. + void setPagesInFile(word wValue); // EXPORT + /// Sets the e_crlc value of the MZ header. + void setRelocations(word wValue); // EXPORT + /// Sets the e_cparhdr value of the MZ header. + void setSizeOfHeader(word wValue); // EXPORT + /// Sets the e_minalloc value of the MZ header. + void setMinExtraParagraphs(word wValue); // EXPORT + /// Sets the e_maxalloc value of the MZ header. + void setMaxExtraParagraphs(word wValue); // EXPORT + /// Sets the e_ss value of the MZ header. + void setSsValue(word wValue); // EXPORT + /// Sets the e_sp value of the MZ header. + void setSpValue(word wValue); // EXPORT + /// Sets the e_csum value of the MZ header. + void setChecksum(word wValue); // EXPORT + /// Sets the e_ip value of the MZ header. + void setIpValue(word wValue); // EXPORT + /// Sets the e_cs value of the MZ header. + void setCsValue(word wValue); // EXPORT + /// Sets the e_lfarlc value of the MZ header. + void setAddrOfRelocationTable(word wValue); // EXPORT + /// Sets the e_ovno value of the MZ header. + void setOverlayNumber(word wValue); // EXPORT + /// Sets the e_oemid value of the MZ header. + void setOemIdentifier(word wValue); // EXPORT + /// Sets the e_oeminfo value of the MZ header. + void setOemInformation(word wValue); // EXPORT + /// Sets the e_lfanew value of the MZ header. + void setAddressOfPeHeader(dword dwValue); // EXPORT + /// Sets the e_res value of the MZ header. + void setReservedWords1(unsigned int uiNr, word wValue); // EXPORT + /// Sets the e_res2 value of the MZ header. + void setReservedWords2(unsigned int uiNr, word wValue); // EXPORT + }; +} + +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.cpp index 39f2488b81..9e9f2d8691 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.cpp @@ -1,169 +1,169 @@ -/*
-* PeLib.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "PeFile.h"
-
-namespace PeLib
-{
- PeFile::~PeFile()
- {
- }
-
- PeFile32::PeFile32() : PeFileT<32>()
- {
- }
-
- PeFile32::PeFile32(const std::string& strFlename) : PeFileT<32>(strFlename)
- {
- }
-
- PeFile64::PeFile64() : PeFileT<64>()
- {
- }
-
- PeFile64::PeFile64(const std::string& strFlename) : PeFileT<64>(strFlename)
- {
- }
-
- /**
- * @return A reference to the file's MZ header.
- **/
-
- const MzHeader& PeFile::mzHeader() const
- {
- return m_mzh;
- }
-
- /**
- * @return A reference to the file's MZ header.
- **/
-
- MzHeader& PeFile::mzHeader()
- {
- return m_mzh;
- }
-
- /**
- * @return A reference to the file's export directory.
- **/
-
- const ExportDirectory& PeFile::expDir() const
- {
- return m_expdir;
- }
-
- /**
- * @return A reference to the file's export directory.
- **/
-
- ExportDirectory& PeFile::expDir()
- {
- return m_expdir;
- }
-
- /**
- * @return A reference to the file's bound import directory.
- **/
-
- const BoundImportDirectory& PeFile::boundImpDir() const
- {
- return m_boundimpdir;
- }
-
- /**
- * @return A reference to the file's bound import directory.
- **/
-
- BoundImportDirectory& PeFile::boundImpDir()
- {
- return m_boundimpdir;
- }
-
- /**
- * @return A reference to the file's resource directory.
- **/
-
- const ResourceDirectory& PeFile::resDir() const
- {
- return m_resdir;
- }
-
- /**
- * @return A reference to the file's resource directory.
- **/
-
- ResourceDirectory& PeFile::resDir()
- {
- return m_resdir;
- }
-
- /**
- * @return A reference to the file's relocations directory.
- **/
-
- const RelocationsDirectory& PeFile::relocDir() const
- {
- return m_relocs;
- }
-
- /**
- * @return A reference to the file's relocations directory.
- **/
-
- RelocationsDirectory& PeFile::relocDir()
- {
- return m_relocs;
- }
-
- /**
- * @return A reference to the file's COM+ descriptor directory.
- **/
-
- const ComHeaderDirectory& PeFile::comDir() const
- {
- return m_comdesc;
- }
-
- /**
- * @return A reference to the file's COM+ descriptor directory.
- **/
-
- ComHeaderDirectory & PeFile::comDir()
- {
- return m_comdesc;
- }
-
-
- const IatDirectory& PeFile::iatDir() const
- {
- return m_iat;
- }
-
-
- IatDirectory& PeFile::iatDir()
- {
- return m_iat;
- }
-
-
- const DebugDirectory& PeFile::debugDir() const
- {
- return m_debugdir;
- }
-
-
- DebugDirectory& PeFile::debugDir()
- {
- return m_debugdir;
- }
-
-}
+/* +* PeLib.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "PeFile.h" + +namespace PeLib +{ + PeFile::~PeFile() + { + } + + PeFile32::PeFile32() : PeFileT<32>() + { + } + + PeFile32::PeFile32(const std::string& strFlename) : PeFileT<32>(strFlename) + { + } + + PeFile64::PeFile64() : PeFileT<64>() + { + } + + PeFile64::PeFile64(const std::string& strFlename) : PeFileT<64>(strFlename) + { + } + + /** + * @return A reference to the file's MZ header. + **/ + + const MzHeader& PeFile::mzHeader() const + { + return m_mzh; + } + + /** + * @return A reference to the file's MZ header. + **/ + + MzHeader& PeFile::mzHeader() + { + return m_mzh; + } + + /** + * @return A reference to the file's export directory. + **/ + + const ExportDirectory& PeFile::expDir() const + { + return m_expdir; + } + + /** + * @return A reference to the file's export directory. + **/ + + ExportDirectory& PeFile::expDir() + { + return m_expdir; + } + + /** + * @return A reference to the file's bound import directory. + **/ + + const BoundImportDirectory& PeFile::boundImpDir() const + { + return m_boundimpdir; + } + + /** + * @return A reference to the file's bound import directory. + **/ + + BoundImportDirectory& PeFile::boundImpDir() + { + return m_boundimpdir; + } + + /** + * @return A reference to the file's resource directory. + **/ + + const ResourceDirectory& PeFile::resDir() const + { + return m_resdir; + } + + /** + * @return A reference to the file's resource directory. + **/ + + ResourceDirectory& PeFile::resDir() + { + return m_resdir; + } + + /** + * @return A reference to the file's relocations directory. + **/ + + const RelocationsDirectory& PeFile::relocDir() const + { + return m_relocs; + } + + /** + * @return A reference to the file's relocations directory. + **/ + + RelocationsDirectory& PeFile::relocDir() + { + return m_relocs; + } + + /** + * @return A reference to the file's COM+ descriptor directory. + **/ + + const ComHeaderDirectory& PeFile::comDir() const + { + return m_comdesc; + } + + /** + * @return A reference to the file's COM+ descriptor directory. + **/ + + ComHeaderDirectory & PeFile::comDir() + { + return m_comdesc; + } + + + const IatDirectory& PeFile::iatDir() const + { + return m_iat; + } + + + IatDirectory& PeFile::iatDir() + { + return m_iat; + } + + + const DebugDirectory& PeFile::debugDir() const + { + return m_debugdir; + } + + + DebugDirectory& PeFile::debugDir() + { + return m_debugdir; + } + +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.h b/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.h index a2b02cdfa8..e08d8da309 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/PeFile.h @@ -1,451 +1,451 @@ -/*
-* PeFile.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef PEFILE_H
-#define PEFILE_H
-
-#include "PeLibInc.h"
-#include "MzHeader.h"
-#include "PeHeader.h"
-#include "ImportDirectory.h"
-#include "ExportDirectory.h"
-#include "BoundImportDirectory.h"
-#include "ResourceDirectory.h"
-#include "RelocationsDirectory.h"
-#include "ComHeaderDirectory.h"
-#include "IatDirectory.h"
-#include "DebugDirectory.h"
-#include "TlsDirectory.h"
-
-namespace PeLib
-{
- class PeFile32;
- class PeFile64;
-
- /**
- * Visitor base class for PeFiles.
- **/
- class PeFileVisitor
- {
- public:
- virtual void callback(PeFile32 &file){}
- virtual void callback(PeFile64 &file){}
- virtual ~PeFileVisitor(){}
- };
-
- /**
- * Traits class that's used to decide of what type the PeHeader in a PeFile is.
- **/
- template<int>
- struct PeFile_Traits;
-
- template<>
- struct PeFile_Traits<32>
- {
- typedef PeHeader32 PeHeader32_64;
- };
-
- template<>
- struct PeFile_Traits<64>
- {
- typedef PeHeader64 PeHeader32_64;
- };
-
- /**
- * This class represents the common structures of PE and PE+ files.
- **/
- class PeFile
- {
- protected:
- std::string m_filename; ///< Name of the current file.
- MzHeader m_mzh; ///< MZ header of the current file.
- ExportDirectory m_expdir; ///< Export directory of the current file.
- BoundImportDirectory m_boundimpdir; ///< BoundImportDirectory of the current file.
- ResourceDirectory m_resdir; ///< ResourceDirectory of the current file.
- RelocationsDirectory m_relocs; ///< Relocations directory of the current file.
- ComHeaderDirectory m_comdesc; ///< COM+ descriptor directory of the current file.
- IatDirectory m_iat; ///< Import address table of the current file.
- DebugDirectory m_debugdir;
- public:
- virtual ~PeFile();
-
- /// Returns the name of the current file.
- virtual std::string getFileName() const = 0; // EXPORT
- /// Changes the name of the current file.
- virtual void setFileName(std::string strFilename) = 0; // EXPORT
-
- virtual void visit(PeFileVisitor &v) = 0;
-
- /// Reads the MZ header of the current file from disc.
- virtual int readMzHeader() = 0; // EXPORT
- /// Reads the export directory of the current file from disc.
- virtual int readExportDirectory() = 0; // EXPORT
- /// Reads the PE header of the current file from disc.
- virtual int readPeHeader() = 0; // EXPORT
- /// Reads the import directory of the current file from disc.
- virtual int readImportDirectory() = 0; // EXPORT
- /// Reads the bound import directory of the current file from disc.
- virtual int readBoundImportDirectory() = 0; // EXPORT
- /// Reads the resource directory of the current file from disc.
- virtual int readResourceDirectory() = 0; // EXPORT
- /// Reads the relocations directory of the current file from disc.
- virtual int readRelocationsDirectory() = 0; // EXPORT
- /// Reads the COM+ descriptor directory of the current file from disc.
- virtual int readComHeaderDirectory() = 0; // EXPORT
- /// Reads the IAT directory of the current file from disc.
- virtual int readIatDirectory() = 0; // EXPORT
- /// Reads the Debug directory of the current file.
- virtual int readDebugDirectory() = 0; // EXPORT
- virtual int readTlsDirectory() = 0; // EXPORT
-
- virtual unsigned int getBits() const = 0;
-
- /// Accessor function for the MZ header.
- const MzHeader& mzHeader() const;
- /// Accessor function for the MZ header.
- MzHeader& mzHeader(); // EXPORT
-
- /// Accessor function for the export directory.
- const ExportDirectory& expDir() const;
- /// Accessor function for the export directory.
- ExportDirectory& expDir(); // EXPORT
-
- /// Accessor function for the bound import directory.
- const BoundImportDirectory& boundImpDir() const;
- /// Accessor function for the bound import directory.
- BoundImportDirectory& boundImpDir(); // EXPORT
-
- /// Accessor function for the resource directory.
- const ResourceDirectory& resDir() const;
- /// Accessor function for the resource directory.
- ResourceDirectory& resDir(); // EXPORT
-
- /// Accessor function for the relocations directory.
- const RelocationsDirectory& relocDir() const;
- /// Accessor function for the relocations directory.
- RelocationsDirectory& relocDir(); // EXPORT
-
- /// Accessor function for the COM+ descriptor directory.
- const ComHeaderDirectory& comDir() const;
- /// Accessor function for the COM+ descriptor directory.
- ComHeaderDirectory& comDir(); // EXPORT
-
- /// Accessor function for the IAT directory.
- const IatDirectory& iatDir() const;
- /// Accessor function for the IAT directory.
- IatDirectory& iatDir(); // EXPORT
-
- /// Accessor function for the debug directory.
- const DebugDirectory& debugDir() const;
- /// Accessor function for the debug directory.
- DebugDirectory& debugDir(); // EXPORT
-
- };
-
- /**
- * This class implements the common structures of PE and PE+ files.
- **/
- template<int bits>
- class PeFileT : public PeFile
- {
- typedef typename PeFile_Traits<bits>::PeHeader32_64 PeHeader32_64;
-
- private:
- PeHeader32_64 m_peh; ///< PE header of the current file.
- ImportDirectory<bits> m_impdir; ///< Import directory of the current file.
- TlsDirectory<bits> m_tlsdir;
-
- public:
- /// Default constructor which exists only for the sake of allowing to construct files without filenames.
- PeFileT();
-
- virtual ~PeFileT() {}
-
- /// Initializes a PeFile with a filename
- explicit PeFileT(const std::string& strFilename);
-
- /// Returns the name of the current file.
- std::string getFileName() const;
- /// Changes the name of the current file.
- void setFileName(std::string strFilename);
-
- /// Reads the MZ header of the current file from disc.
- int readMzHeader() ;
- /// Reads the export directory of the current file from disc.
- int readExportDirectory() ;
- /// Reads the PE header of the current file from disc.
- int readPeHeader() ;
- /// Reads the import directory of the current file from disc.
- int readImportDirectory() ;
- /// Reads the bound import directory of the current file from disc.
- int readBoundImportDirectory() ;
- /// Reads the resource directory of the current file from disc.
- int readResourceDirectory() ;
- /// Reads the relocations directory of the current file from disc.
- int readRelocationsDirectory() ;
- /// Reads the COM+ descriptor directory of the current file from disc.
- int readComHeaderDirectory() ;
- /// Reads the IAT directory of the current file from disc.
- int readIatDirectory() ;
- /// Reads the Debug directory of the current file.
- int readDebugDirectory() ;
- int readTlsDirectory() ;
-
- unsigned int getBits() const
- {
- return bits;
- }
-
- /// Accessor function for the PE header.
- const PeHeader32_64& peHeader() const;
- /// Accessor function for the PE header.
- PeHeader32_64& peHeader();
-
- /// Accessor function for the import directory.
- const ImportDirectory<bits>& impDir() const;
- /// Accessor function for the import directory.
- ImportDirectory<bits>& impDir();
-
- const TlsDirectory<bits>& tlsDir() const;
- TlsDirectory<bits>& tlsDir();
- };
-
- /**
- * This class is the main class for handling PE files.
- **/
- class PeFile32 : public PeFileT<32>
- {
- public:
- /// Default constructor which exists only for the sake of allowing to construct files without filenames.
- PeFile32();
-
- /// Initializes a PeFile with a filename
- explicit PeFile32(const std::string& strFlename);
- virtual void visit(PeFileVisitor &v) { v.callback( *this ); }
- };
-
- /**
- * This class is the main class for handling PE+ files.
- **/
- class PeFile64 : public PeFileT<64>
- {
- public:
- /// Default constructor which exists only for the sake of allowing to construct files without filenames.
- PeFile64();
-
- /// Initializes a PeFile with a filename
- explicit PeFile64(const std::string& strFlename);
- virtual void visit(PeFileVisitor &v) { v.callback( *this ); }
- };
-
- //typedef PeFileT<32> PeFile32;
- //typedef PeFileT<64> PeFile64;
-
- /**
- * @param strFilename Name of the current file.
- **/
- template<int bits>
- PeFileT<bits>::PeFileT(const std::string& strFilename)
- {
- m_filename = strFilename;
- }
-
- template<int bits>
- PeFileT<bits>::PeFileT()
- {
- }
-
- template<int bits>
- int PeFileT<bits>::readPeHeader()
- {
- return peHeader().read(getFileName(), mzHeader().getAddressOfPeHeader());
- }
-
-
- template<int bits>
- int PeFileT<bits>::readImportDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 2
- && peHeader().getIddImportRva()
- && peHeader().getIddImportSize())
- {
- return impDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddImportRva())), peHeader().getIddImportSize(), peHeader());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- /**
- * @return A reference to the file's PE header.
- **/
- template<int bits>
- const typename PeFile_Traits<bits>::PeHeader32_64& PeFileT<bits>::peHeader() const
- {
- return m_peh;
- }
-
- /**
- * @return A reference to the file's PE header.
- **/
- template<int bits>
- typename PeFile_Traits<bits>::PeHeader32_64& PeFileT<bits>::peHeader()
- {
- return m_peh;
- }
-
- /**
- * @return A reference to the file's import directory.
- **/
- template<int bits>
- const ImportDirectory<bits>& PeFileT<bits>::impDir() const
- {
- return m_impdir;
- }
-
- /**
- * @return A reference to the file's import directory.
- **/
- template<int bits>
- ImportDirectory<bits>& PeFileT<bits>::impDir()
- {
- return m_impdir;
- }
-
- template<int bits>
- const TlsDirectory<bits>& PeFileT<bits>::tlsDir() const
- {
- return m_tlsdir;
- }
-
- template<int bits>
- TlsDirectory<bits>& PeFileT<bits>::tlsDir()
- {
- return m_tlsdir;
- }
-
- /**
- * @return Filename of the current file.
- **/
- template<int bits>
- std::string PeFileT<bits>::getFileName() const
- {
- return m_filename;
- }
-
- /**
- * @param strFilename New filename.
- **/
- template<int bits>
- void PeFileT<bits>::setFileName(std::string strFilename)
- {
- m_filename = strFilename;
- }
-
- template<int bits>
- int PeFileT<bits>::readMzHeader()
- {
- return mzHeader().read(getFileName());
- }
-
- template<int bits>
- int PeFileT<bits>::readExportDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 1
- && peHeader().getIddExportRva() && peHeader().getIddExportSize())
- {
- return expDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddExportRva())), peHeader().getIddExportSize(), peHeader());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
-
- template<int bits>
- int PeFileT<bits>::readBoundImportDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 12
- && peHeader().getIddBoundImportRva() && peHeader().getIddBoundImportSize())
- {
- return boundImpDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddBoundImportRva())), peHeader().getIddBoundImportSize());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readResourceDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 3
- && peHeader().getIddResourceRva() && peHeader().getIddResourceSize())
- {
- return resDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddResourceRva())), peHeader().getIddResourceSize(), peHeader().getIddResourceRva());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readRelocationsDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 6
- && peHeader().getIddBaseRelocRva() && peHeader().getIddBaseRelocSize())
- {
- return relocDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddBaseRelocRva())), peHeader().getIddBaseRelocSize());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readComHeaderDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 15
- && peHeader().getIddComHeaderRva() && peHeader().getIddComHeaderSize())
- {
- return comDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddComHeaderRva())), peHeader().getIddComHeaderSize());
- }
- std::cout << peHeader().getIddComHeaderRva() << std::endl;
- std::exit(0);
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readIatDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 13
- && peHeader().getIddIatRva() && peHeader().getIddIatSize())
- {
- return iatDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddIatRva())), peHeader().getIddIatSize());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readDebugDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 7
- && peHeader().getIddDebugRva() && peHeader().getIddDebugSize())
- {
- return debugDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddDebugRva())), peHeader().getIddDebugSize());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
- template<int bits>
- int PeFileT<bits>::readTlsDirectory()
- {
- if (peHeader().calcNumberOfRvaAndSizes() >= 10
- && peHeader().getIddTlsRva() && peHeader().getIddTlsSize())
- {
- return tlsDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddTlsRva())), peHeader().getIddTlsSize());
- }
- return ERROR_DIRECTORY_DOES_NOT_EXIST;
- }
-
-}
-
-#endif
+/* +* PeFile.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef PEFILE_H +#define PEFILE_H + +#include "PeLibInc.h" +#include "MzHeader.h" +#include "PeHeader.h" +#include "ImportDirectory.h" +#include "ExportDirectory.h" +#include "BoundImportDirectory.h" +#include "ResourceDirectory.h" +#include "RelocationsDirectory.h" +#include "ComHeaderDirectory.h" +#include "IatDirectory.h" +#include "DebugDirectory.h" +#include "TlsDirectory.h" + +namespace PeLib +{ + class PeFile32; + class PeFile64; + + /** + * Visitor base class for PeFiles. + **/ + class PeFileVisitor + { + public: + virtual void callback(PeFile32 &file){} + virtual void callback(PeFile64 &file){} + virtual ~PeFileVisitor(){} + }; + + /** + * Traits class that's used to decide of what type the PeHeader in a PeFile is. + **/ + template<int> + struct PeFile_Traits; + + template<> + struct PeFile_Traits<32> + { + typedef PeHeader32 PeHeader32_64; + }; + + template<> + struct PeFile_Traits<64> + { + typedef PeHeader64 PeHeader32_64; + }; + + /** + * This class represents the common structures of PE and PE+ files. + **/ + class PeFile + { + protected: + std::string m_filename; ///< Name of the current file. + MzHeader m_mzh; ///< MZ header of the current file. + ExportDirectory m_expdir; ///< Export directory of the current file. + BoundImportDirectory m_boundimpdir; ///< BoundImportDirectory of the current file. + ResourceDirectory m_resdir; ///< ResourceDirectory of the current file. + RelocationsDirectory m_relocs; ///< Relocations directory of the current file. + ComHeaderDirectory m_comdesc; ///< COM+ descriptor directory of the current file. + IatDirectory m_iat; ///< Import address table of the current file. + DebugDirectory m_debugdir; + public: + virtual ~PeFile(); + + /// Returns the name of the current file. + virtual std::string getFileName() const = 0; // EXPORT + /// Changes the name of the current file. + virtual void setFileName(std::string strFilename) = 0; // EXPORT + + virtual void visit(PeFileVisitor &v) = 0; + + /// Reads the MZ header of the current file from disc. + virtual int readMzHeader() = 0; // EXPORT + /// Reads the export directory of the current file from disc. + virtual int readExportDirectory() = 0; // EXPORT + /// Reads the PE header of the current file from disc. + virtual int readPeHeader() = 0; // EXPORT + /// Reads the import directory of the current file from disc. + virtual int readImportDirectory() = 0; // EXPORT + /// Reads the bound import directory of the current file from disc. + virtual int readBoundImportDirectory() = 0; // EXPORT + /// Reads the resource directory of the current file from disc. + virtual int readResourceDirectory() = 0; // EXPORT + /// Reads the relocations directory of the current file from disc. + virtual int readRelocationsDirectory() = 0; // EXPORT + /// Reads the COM+ descriptor directory of the current file from disc. + virtual int readComHeaderDirectory() = 0; // EXPORT + /// Reads the IAT directory of the current file from disc. + virtual int readIatDirectory() = 0; // EXPORT + /// Reads the Debug directory of the current file. + virtual int readDebugDirectory() = 0; // EXPORT + virtual int readTlsDirectory() = 0; // EXPORT + + virtual unsigned int getBits() const = 0; + + /// Accessor function for the MZ header. + const MzHeader& mzHeader() const; + /// Accessor function for the MZ header. + MzHeader& mzHeader(); // EXPORT + + /// Accessor function for the export directory. + const ExportDirectory& expDir() const; + /// Accessor function for the export directory. + ExportDirectory& expDir(); // EXPORT + + /// Accessor function for the bound import directory. + const BoundImportDirectory& boundImpDir() const; + /// Accessor function for the bound import directory. + BoundImportDirectory& boundImpDir(); // EXPORT + + /// Accessor function for the resource directory. + const ResourceDirectory& resDir() const; + /// Accessor function for the resource directory. + ResourceDirectory& resDir(); // EXPORT + + /// Accessor function for the relocations directory. + const RelocationsDirectory& relocDir() const; + /// Accessor function for the relocations directory. + RelocationsDirectory& relocDir(); // EXPORT + + /// Accessor function for the COM+ descriptor directory. + const ComHeaderDirectory& comDir() const; + /// Accessor function for the COM+ descriptor directory. + ComHeaderDirectory& comDir(); // EXPORT + + /// Accessor function for the IAT directory. + const IatDirectory& iatDir() const; + /// Accessor function for the IAT directory. + IatDirectory& iatDir(); // EXPORT + + /// Accessor function for the debug directory. + const DebugDirectory& debugDir() const; + /// Accessor function for the debug directory. + DebugDirectory& debugDir(); // EXPORT + + }; + + /** + * This class implements the common structures of PE and PE+ files. + **/ + template<int bits> + class PeFileT : public PeFile + { + typedef typename PeFile_Traits<bits>::PeHeader32_64 PeHeader32_64; + + private: + PeHeader32_64 m_peh; ///< PE header of the current file. + ImportDirectory<bits> m_impdir; ///< Import directory of the current file. + TlsDirectory<bits> m_tlsdir; + + public: + /// Default constructor which exists only for the sake of allowing to construct files without filenames. + PeFileT(); + + virtual ~PeFileT() {} + + /// Initializes a PeFile with a filename + explicit PeFileT(const std::string& strFilename); + + /// Returns the name of the current file. + std::string getFileName() const; + /// Changes the name of the current file. + void setFileName(std::string strFilename); + + /// Reads the MZ header of the current file from disc. + int readMzHeader() ; + /// Reads the export directory of the current file from disc. + int readExportDirectory() ; + /// Reads the PE header of the current file from disc. + int readPeHeader() ; + /// Reads the import directory of the current file from disc. + int readImportDirectory() ; + /// Reads the bound import directory of the current file from disc. + int readBoundImportDirectory() ; + /// Reads the resource directory of the current file from disc. + int readResourceDirectory() ; + /// Reads the relocations directory of the current file from disc. + int readRelocationsDirectory() ; + /// Reads the COM+ descriptor directory of the current file from disc. + int readComHeaderDirectory() ; + /// Reads the IAT directory of the current file from disc. + int readIatDirectory() ; + /// Reads the Debug directory of the current file. + int readDebugDirectory() ; + int readTlsDirectory() ; + + unsigned int getBits() const + { + return bits; + } + + /// Accessor function for the PE header. + const PeHeader32_64& peHeader() const; + /// Accessor function for the PE header. + PeHeader32_64& peHeader(); + + /// Accessor function for the import directory. + const ImportDirectory<bits>& impDir() const; + /// Accessor function for the import directory. + ImportDirectory<bits>& impDir(); + + const TlsDirectory<bits>& tlsDir() const; + TlsDirectory<bits>& tlsDir(); + }; + + /** + * This class is the main class for handling PE files. + **/ + class PeFile32 : public PeFileT<32> + { + public: + /// Default constructor which exists only for the sake of allowing to construct files without filenames. + PeFile32(); + + /// Initializes a PeFile with a filename + explicit PeFile32(const std::string& strFlename); + virtual void visit(PeFileVisitor &v) { v.callback( *this ); } + }; + + /** + * This class is the main class for handling PE+ files. + **/ + class PeFile64 : public PeFileT<64> + { + public: + /// Default constructor which exists only for the sake of allowing to construct files without filenames. + PeFile64(); + + /// Initializes a PeFile with a filename + explicit PeFile64(const std::string& strFlename); + virtual void visit(PeFileVisitor &v) { v.callback( *this ); } + }; + + //typedef PeFileT<32> PeFile32; + //typedef PeFileT<64> PeFile64; + + /** + * @param strFilename Name of the current file. + **/ + template<int bits> + PeFileT<bits>::PeFileT(const std::string& strFilename) + { + m_filename = strFilename; + } + + template<int bits> + PeFileT<bits>::PeFileT() + { + } + + template<int bits> + int PeFileT<bits>::readPeHeader() + { + return peHeader().read(getFileName(), mzHeader().getAddressOfPeHeader()); + } + + + template<int bits> + int PeFileT<bits>::readImportDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 2 + && peHeader().getIddImportRva() + && peHeader().getIddImportSize()) + { + return impDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddImportRva())), peHeader().getIddImportSize(), peHeader()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + /** + * @return A reference to the file's PE header. + **/ + template<int bits> + const typename PeFile_Traits<bits>::PeHeader32_64& PeFileT<bits>::peHeader() const + { + return m_peh; + } + + /** + * @return A reference to the file's PE header. + **/ + template<int bits> + typename PeFile_Traits<bits>::PeHeader32_64& PeFileT<bits>::peHeader() + { + return m_peh; + } + + /** + * @return A reference to the file's import directory. + **/ + template<int bits> + const ImportDirectory<bits>& PeFileT<bits>::impDir() const + { + return m_impdir; + } + + /** + * @return A reference to the file's import directory. + **/ + template<int bits> + ImportDirectory<bits>& PeFileT<bits>::impDir() + { + return m_impdir; + } + + template<int bits> + const TlsDirectory<bits>& PeFileT<bits>::tlsDir() const + { + return m_tlsdir; + } + + template<int bits> + TlsDirectory<bits>& PeFileT<bits>::tlsDir() + { + return m_tlsdir; + } + + /** + * @return Filename of the current file. + **/ + template<int bits> + std::string PeFileT<bits>::getFileName() const + { + return m_filename; + } + + /** + * @param strFilename New filename. + **/ + template<int bits> + void PeFileT<bits>::setFileName(std::string strFilename) + { + m_filename = strFilename; + } + + template<int bits> + int PeFileT<bits>::readMzHeader() + { + return mzHeader().read(getFileName()); + } + + template<int bits> + int PeFileT<bits>::readExportDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 1 + && peHeader().getIddExportRva() && peHeader().getIddExportSize()) + { + return expDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddExportRva())), peHeader().getIddExportSize(), peHeader()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + + template<int bits> + int PeFileT<bits>::readBoundImportDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 12 + && peHeader().getIddBoundImportRva() && peHeader().getIddBoundImportSize()) + { + return boundImpDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddBoundImportRva())), peHeader().getIddBoundImportSize()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readResourceDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 3 + && peHeader().getIddResourceRva() && peHeader().getIddResourceSize()) + { + return resDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddResourceRva())), peHeader().getIddResourceSize(), peHeader().getIddResourceRva()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readRelocationsDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 6 + && peHeader().getIddBaseRelocRva() && peHeader().getIddBaseRelocSize()) + { + return relocDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddBaseRelocRva())), peHeader().getIddBaseRelocSize()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readComHeaderDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 15 + && peHeader().getIddComHeaderRva() && peHeader().getIddComHeaderSize()) + { + return comDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddComHeaderRva())), peHeader().getIddComHeaderSize()); + } + std::cout << peHeader().getIddComHeaderRva() << std::endl; + std::exit(0); + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readIatDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 13 + && peHeader().getIddIatRva() && peHeader().getIddIatSize()) + { + return iatDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddIatRva())), peHeader().getIddIatSize()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readDebugDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 7 + && peHeader().getIddDebugRva() && peHeader().getIddDebugSize()) + { + return debugDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddDebugRva())), peHeader().getIddDebugSize()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + + template<int bits> + int PeFileT<bits>::readTlsDirectory() + { + if (peHeader().calcNumberOfRvaAndSizes() >= 10 + && peHeader().getIddTlsRva() && peHeader().getIddTlsSize()) + { + return tlsDir().read(getFileName(), static_cast<unsigned int>(peHeader().rvaToOffset(peHeader().getIddTlsRva())), peHeader().getIddTlsSize()); + } + return ERROR_DIRECTORY_DOES_NOT_EXIST; + } + +} + +#endif diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.cpp index fe7011072c..1199e6bdd1 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.cpp @@ -1,90 +1,90 @@ -/*
-* PeHeader.cpp - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#include "PeLibInc.h"
-#include "PeHeader.h"
-
-namespace PeLib
-{
- template<>
- void PeHeaderT<32>::readBaseOfData(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<32>& header) const
- {
- ibBuffer >> header.OptionalHeader.BaseOfData;
- }
-
- template<>
- void PeHeaderT<64>::readBaseOfData(InputBuffer&, PELIB_IMAGE_NT_HEADERS<64>&) const
- {
- }
-
- template<>
- void PeHeaderT<32>::rebuildBaseOfData(OutputBuffer& obBuffer) const
- {
- obBuffer << m_inthHeader.OptionalHeader.BaseOfData;
- }
-
- template<>
- void PeHeaderT<64>::rebuildBaseOfData(OutputBuffer&) const
- {
- }
-
- template<>
- bool PeHeaderT<32>::isValid() const
- {
- return true;
- }
-
- template<>
- bool PeHeaderT<64>::isValid() const
- {
- return true;
- }
-
- template<>
- bool PeHeaderT<32>::isValid(unsigned int pehf) const
- {
- /*
- if (pehf == NtSignature)
- {
- return m_inthHeader.Signature == IMAGE_NT_SIGNATURE;
- }
- else if (pehf == NumberOfSections)
- {
- return getNumberOfSections() == calcNumberOfSections();
- } */
- return false;
- }
-
- template<>
- bool PeHeaderT<64>::isValid(unsigned int pehf) const
- {
- return false;
- }
-
- /**
- * @return The BaseOfData value from the PE header.
- **/
- dword PeHeader32::getBaseOfData() const
- {
- return m_inthHeader.OptionalHeader.BaseOfData;
- }
-
- /**
- * Changes the file's BaseOfData.
- * @param dwValue New value.
- **/
- void PeHeader32::setBaseOfData(dword dwValue)
- {
- m_inthHeader.OptionalHeader.BaseOfData = dwValue;
- }
-
-}
+/* +* PeHeader.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "PeLibInc.h" +#include "PeHeader.h" + +namespace PeLib +{ + template<> + void PeHeaderT<32>::readBaseOfData(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<32>& header) const + { + ibBuffer >> header.OptionalHeader.BaseOfData; + } + + template<> + void PeHeaderT<64>::readBaseOfData(InputBuffer&, PELIB_IMAGE_NT_HEADERS<64>&) const + { + } + + template<> + void PeHeaderT<32>::rebuildBaseOfData(OutputBuffer& obBuffer) const + { + obBuffer << m_inthHeader.OptionalHeader.BaseOfData; + } + + template<> + void PeHeaderT<64>::rebuildBaseOfData(OutputBuffer&) const + { + } + + template<> + bool PeHeaderT<32>::isValid() const + { + return true; + } + + template<> + bool PeHeaderT<64>::isValid() const + { + return true; + } + + template<> + bool PeHeaderT<32>::isValid(unsigned int pehf) const + { + /* + if (pehf == NtSignature) + { + return m_inthHeader.Signature == IMAGE_NT_SIGNATURE; + } + else if (pehf == NumberOfSections) + { + return getNumberOfSections() == calcNumberOfSections(); + } */ + return false; + } + + template<> + bool PeHeaderT<64>::isValid(unsigned int pehf) const + { + return false; + } + + /** + * @return The BaseOfData value from the PE header. + **/ + dword PeHeader32::getBaseOfData() const + { + return m_inthHeader.OptionalHeader.BaseOfData; + } + + /** + * Changes the file's BaseOfData. + * @param dwValue New value. + **/ + void PeHeader32::setBaseOfData(dword dwValue) + { + m_inthHeader.OptionalHeader.BaseOfData = dwValue; + } + +} diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.h b/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.h index 08eaca4072..d5c1748233 100755..100644 --- a/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/PeHeader.h @@ -1,2685 +1,2685 @@ -/*
-* PeHeader.h - Part of the PeLib library.
-*
-* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
-* All rights reserved.
-*
-* This software is licensed under the zlib/libpng License.
-* For more details see http://www.opensource.org/licenses/zlib-license.php
-* or the license information file (license.htm) in the root directory
-* of PeLib.
-*/
-
-#ifndef PEHEADER_H
-#define PEHEADER_H
-
-#include "PeLibAux.h"
-
-namespace PeLib
-{
- class PeHeader
- {
-// protected:
-// virtual void readBaseOfData(InputBuffer& ibBuffer) = 0;
-// virtual void rebuildBaseOfData(OutputBuffer& obBuffer) const = 0;
-
- public:
- virtual ~PeHeader(){};
- };
-
- /// Class that handles the PE header of files.
- /**
- * This class can read and modify PE headers. It provides set- and get functions to access
- * all individual members of a PE header. Furthermore it's possible to validate and rebuild
- * PE headers. A PE header includes the IMAGE_Nt_HEADERS and the section definitions of a PE file.
- * \todo getIdReservedRva
- **/
- template<int x>
- class PeHeaderT : public PeHeader
- {
- private:
- void readBaseOfData(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<x>& header) const;
- void rebuildBaseOfData(OutputBuffer& obBuffer) const;
-
- protected:
- std::vector<PELIB_IMAGE_SECTION_HEADER> m_vIsh; ///< Stores section header information.
- PELIB_IMAGE_NT_HEADERS<x> m_inthHeader; ///< Stores Nt header information.
- dword m_uiOffset; ///< Equivalent to the value returned by #PeLib::MzHeader::getAddressOfPeFile
-
- public:
- typedef typename FieldSizes<x>::VAR4_8 VAR4_8;
-
- PeHeaderT() : m_uiOffset(0)
- {
- }
-
- /// Add a section to the header.
- int addSection(const std::string& strName, dword dwSize); // EXPORT
-
- unsigned int calcSizeOfImage() const; // EXPORT
-
- /// Returns the unused space after the header.
- unsigned int calcSpaceAfterHeader() const; // EXPORT
-
- /// Returns the address of the physically first section (not the first defined section).
- unsigned int calcStartOfCode() const; // EXPORT
-
- /// Calculates the offset for a new section of size uiSize.
- unsigned int calcOffset() const; // EXPORT
-
- /// Calculates the Rva for a new section of size uiSize.
- unsigned int calcRva() const; // EXPORT
-
- /// Returns the number of sections in the current file.
- word calcNumberOfSections() const; // EXPORT
-
- void enlargeLastSection(unsigned int uiSize); // EXPORT
-
- /// Returns the section Id of the section that contains the offset.
- word getSectionWithOffset(VAR4_8 dwOffset) const; // EXPORT
-
- /// Returns the number of the section which the given relative address points to.
- word getSectionWithRva(VAR4_8 rva) const; // EXPORT
-
- bool isValid() const; // EXPORT
- bool isValid(unsigned int foo) const; // EXPORT
-
- /// Corrects the current PE header.
- void makeValid(dword dwOffset); // EXPORT
-
- /// Converts a file offset to a relative virtual offset.
- unsigned int offsetToRva(VAR4_8 dwOffset) const; // EXPORT
-
- /// Converts a file offset to a virtual address.
- unsigned int offsetToVa(VAR4_8 dwOffset) const; // EXPORT
-
- /// Reads the PE header of a file.
- int read(std::string strFilename, unsigned int uiOffset); // EXPORT
-
- int read(const unsigned char* pcBuffer, unsigned int uiSize, unsigned int uiOffset); // EXPORT
-
- void readHeader(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<x>& header) const;
- void readDataDirectories(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<x>& header) const;
- std::vector<PELIB_IMAGE_SECTION_HEADER> readSections(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<x>& header) const;
-
- /// Rebuilds the current PE header.
- void rebuild(std::vector<byte>& vBuffer) const; // EXPORT
-
- /// Converts a relative virtual address to a file offset.
- VAR4_8 rvaToOffset(VAR4_8 dwRva) const; // EXPORT
-
- /// Converts a relative virtual address to a virtual address.
- VAR4_8 rvaToVa(VAR4_8 dwRva) const; // EXPORT
-
- /// Calculates the size for the current PE header including all section definitions.
- unsigned int size() const;
-
- VAR4_8 vaToRva(VAR4_8 dwRva) const; // EXPORT
- VAR4_8 vaToOffset(VAR4_8 dwRva) const; // EXPORT
-
- /// Save the PE header to a file.
- int write(std::string strFilename, unsigned int uiOffset) const; // EXPORT
-
- /// Writes sections to a file.
- int writeSections(const std::string& strFilename) const; // EXPORT
- /// Overwrites a section with new data.
- int writeSectionData(const std::string& strFilename, word wSecnr, const std::vector<byte>& vBuffer) const; // EXPORT
-
-// header getters
- /// Returns the Signature value of the header.
- dword getNtSignature() const; // EXPORT
- /// Returns the Machine value of the header.
- word getMachine() const; // EXPORT
- /// Returns the Sections value of the header.
- word getNumberOfSections() const; // EXPORT
- /// Returns the TimeDateStamp value of the header.
- dword getTimeDateStamp() const; // EXPORT
- /// Returns the PointerToSymbolTable value of the header.
- dword getPointerToSymbolTable() const; // EXPORT
- /// Returns the NumberOfSymbols value of the header.
- dword getNumberOfSymbols() const; // EXPORT
- /// Returns the SizeOfOptionalHeader value of the header.
- word getSizeOfOptionalHeader() const; // EXPORT
- /// Returns the Characteristics value of the header.
- word getCharacteristics() const; // EXPORT
-
- /// Returns the Magic value of the header.
- word getMagic() const; // EXPORT
- /// Returns the MajorLinkerVersion value of the header.
- byte getMajorLinkerVersion() const; // EXPORT
- /// Returns the MinorLinkerVersion value of the header.
- byte getMinorLinkerVersion() const; // EXPORT
- /// Returns the SizeOfCode value of the header.
- dword getSizeOfCode() const; // EXPORT
- /// Returns the SizeOfInitializedData value of the header.
- dword getSizeOfInitializedData() const; // EXPORT
- /// Returns the SizeOfUninitializedData value of the header.
- dword getSizeOfUninitializedData() const; // EXPORT
- /// Returns the AddressOfEntryPoint value of the header.
- dword getAddressOfEntryPoint() const; // EXPORT
- /// Returns the BaseOfCode value of the header.
- dword getBaseOfCode() const; // EXPORT
- /// Returns the ImageBase value of the header.
- VAR4_8 getImageBase() const; // EXPORT
- /// Returns the SectionAlignment value of the header.
- dword getSectionAlignment() const; // EXPORT
- /// Returns the FileAlignment value of the header.
- dword getFileAlignment() const; // EXPORT
- /// Returns the MajorOperatingSystemVersion value of the header.
- word getMajorOperatingSystemVersion() const; // EXPORT
- /// Returns the MinorOperatingSystemVersion value of the header.
- word getMinorOperatingSystemVersion() const; // EXPORT
- /// Returns the MajorImageVersion value of the header.
- word getMajorImageVersion() const; // EXPORT
- /// Returns the MinorImageVersion value of the header.
- word getMinorImageVersion() const; // EXPORT
- /// Returns the MajorSubsystemVersion value of the header.
- word getMajorSubsystemVersion() const; // EXPORT
- /// Returns the MinorSubsystemVersion value of the header.
- word getMinorSubsystemVersion() const; // EXPORT
- /// Returns the Reserved1 value of the header.
- dword getWin32VersionValue() const; // EXPORT
- /// Returns the SizeOfImage value of the header.
- dword getSizeOfImage() const; // EXPORT
- /// Returns the SizeOfHeaders value of the header.
- dword getSizeOfHeaders() const; // EXPORT
- /// Returns the CheckSum value of the header.
- dword getCheckSum() const; // EXPORT
- /// Returns the Subsystem value of the header.
- word getSubsystem() const; // EXPORT
- /// Returns the DllCharacteristics value of the header.
- word getDllCharacteristics() const; // EXPORT
- /// Returns the SizeOfStackReserve value of the header.
- VAR4_8 getSizeOfStackReserve() const; // EXPORT
- /// Returns the SizeOfStackCommit value of the header.
- VAR4_8 getSizeOfStackCommit() const; // EXPORT
- /// Returns the SizeOfHeapReserve value of the header.
- VAR4_8 getSizeOfHeapReserve() const; // EXPORT
- /// Returns the SizeOfHeapCommit value of the header.
- VAR4_8 getSizeOfHeapCommit() const; // EXPORT
- /// Returns the LoaderFlags value of the header.
- dword getLoaderFlags() const; // EXPORT
- /// Returns the NumberOfRvaAndSizes value of the header.
- dword getNumberOfRvaAndSizes() const; // EXPORT
- dword calcNumberOfRvaAndSizes() const; // EXPORT
-
- void addDataDirectory(); // EXPORT
- void removeDataDirectory(dword index); // EXPORT
-
-// image directory getters
- /// Returns the relative virtual address of the image directory Export.
- dword getIddExportRva() const; // EXPORT
- /// Returns the size of the image directory Export.
- dword getIddExportSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Import.
- dword getIddImportRva() const; // EXPORT
- /// Returns the size of the image directory Import.
- dword getIddImportSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Resource.
- dword getIddResourceRva() const; // EXPORT
- /// Returns the size of the image directory Resource.
- dword getIddResourceSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Exception.
- dword getIddExceptionRva() const; // EXPORT
- /// Returns the size of the image directory Exception.
- dword getIddExceptionSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Security.
- dword getIddSecurityRva() const; // EXPORT
- /// Returns the size of the image directory Security.
- dword getIddSecuritySize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Base Reloc.
- dword getIddBaseRelocRva() const; // EXPORT
- /// Returns the size of the image directory Base Reloc.
- dword getIddBaseRelocSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Debug.
- dword getIddDebugRva() const; // EXPORT
- /// Returns the size of the image directory Debug.
- dword getIddDebugSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Architecture.
- dword getIddArchitectureRva() const; // EXPORT
- /// Returns the size of the image directory Architecture.
- dword getIddArchitectureSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory GlobalPtr.
- dword getIddGlobalPtrRva() const; // EXPORT
- /// Returns the size of the image directory GlobalPtr.
- dword getIddGlobalPtrSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Tls.
- dword getIddTlsRva() const; // EXPORT
- /// Returns the size of the image directory Tls.
- dword getIddTlsSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory LoadConfig.
- dword getIddLoadConfigRva() const; // EXPORT
- /// Returns the size of the image directory LoadConfig.
- dword getIddLoadConfigSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory BoundImport.
- dword getIddBoundImportRva() const; // EXPORT
- /// Returns the size of the image directory BoundImport.
- dword getIddBoundImportSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory Iat.
- dword getIddIatRva() const; // EXPORT
- /// Returns the size of the image directory Iat.
- dword getIddIatSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory DelayImport.
- dword getIddDelayImportRva() const; // EXPORT
- /// Returns the size of the image directory DelayImport.
- dword getIddDelayImportSize() const; // EXPORT
- /// Returns the relative virtual address of the image directory COM Descriptor.
- dword getIddComHeaderRva() const; // EXPORT
- /// Returns the size of the image directory COM Descriptor.
- dword getIddComHeaderSize() const; // EXPORT
-
- /// Returns the relative virtual address of an image directory.
- dword getImageDataDirectoryRva(dword dwDirectory) const; // EXPORT
- /// Returns the size of an image directory.
- dword getImageDataDirectorySize(dword dwDirectory) const; // EXPORT
-
- void setImageDataDirectoryRva(dword dwDirectory, dword value); // EXPORT
- void setImageDataDirectorySize(dword dwDirectory, dword value); // EXPORT
-
-// section getters
- /// Returns the name of a section.
- std::string getSectionName(word uiSectionnr) const; // EXPORT
- /// Returns the virtual size of a section.
- dword getVirtualSize(word uiSectionnr) const; // EXPORT
- /// Returns the virtual address of a section.
- dword getVirtualAddress(word uiSectionnr) const; // EXPORT
- /// Returns the size of a section's raw data.
- dword getSizeOfRawData(word uiSectionnr) const; // EXPORT
- /// Returns file offset of the data of a section.
- dword getPointerToRawData(word uiSectionnr) const; // EXPORT
- /// Returns the rva of the relocations of a section.
- dword getPointerToRelocations(word uiSectionnr) const; // EXPORT
- /// Returns the rva of the line numbers of a section.
- dword getPointerToLinenumbers(word uiSectionnr) const; // EXPORT
- /// Returns the number of relocations of a section.
- dword getNumberOfRelocations(word uiSectionnr) const; // EXPORT
- /// Returns the number of line numbers of a section.
- dword getNumberOfLinenumbers(word uiSectionnr) const; // EXPORT
- /// Returns the characteristics of a section.
- dword getCharacteristics(word uiSectionnr) const; // EXPORT _section
-
-// header setters
- /// Sets the Signature value of the header.
- void setNtSignature(dword value); // EXPORT
- /// Sets the Machine value of the header.
- void setMachine(word value); // EXPORT
- /// Sets the Sections value of the header.
- void setNumberOfSections(word value); // EXPORT
- /// Sets the TimeDateStamp value of the header.
- void setTimeDateStamp(dword value); // EXPORT
- /// Sets the PointerToSymbolTable value of the header.
- void setPointerToSymbolTable(dword value); // EXPORT
- /// Sets the NumberOfSymbols value of the header.
- void setNumberOfSymbols(dword value); // EXPORT
- /// Sets the SizeOfOptionalHeader value of the header.
- void setSizeOfOptionalHeader(word value); // EXPORT
- /// Sets the Characteristics value of the header.
- void setCharacteristics(word value); // EXPORT _section
-
- /// Sets the Magic value of the header.
- void setMagic(word value); // EXPORT
- /// Sets the MajorLinkerVersion value of the header.
- void setMajorLinkerVersion(byte value); // EXPORT
- /// Sets the MinorLinkerVersion value of the header.
- void setMinorLinkerVersion(byte value); // EXPORT
- /// Sets the SizeOfCode value of the header.
- void setSizeOfCode(dword value); // EXPORT
- /// Sets the SizeOfInitializedData value of the header.
- void setSizeOfInitializedData(dword value); // EXPORT
- /// Sets the SizeOfUninitializedData value of the header.
- void setSizeOfUninitializedData(dword value); // EXPORT
- /// Sets the AddressOfEntryPoint value of the header.
- void setAddressOfEntryPoint(dword value); // EXPORT
- /// Sets the BaseOfCode value of the header.
- void setBaseOfCode(dword value); // EXPORT
- /// Sets the ImageBase value of the header.
- void setImageBase(VAR4_8 value); // EXPORT
- /// Sets the SectionAlignment value of the header.
- void setSectionAlignment(dword value); // EXPORT
- /// Sets the FileAlignment value of the header.
- void setFileAlignment(dword value); // EXPORT
- /// Sets the MajorOperatingSystemVersion value of the header.
- void setMajorOperatingSystemVersion(word value); // EXPORT
- /// Sets the MinorOperatingSystemVersion value of the header.
- void setMinorOperatingSystemVersion(word value); // EXPORT
- /// Sets the MajorImageVersion value of the header.
- void setMajorImageVersion(word value); // EXPORT
- /// Sets the MinorImageVersion value of the header.
- void setMinorImageVersion(word value); // EXPORT
- /// Sets the MajorSubsystemVersion value of the header.
- void setMajorSubsystemVersion(word value); // EXPORT
- /// Sets the MinorSubsystemVersion value of the header.
- void setMinorSubsystemVersion(word value); // EXPORT
- /// Sets the Reserved1 value of the header.
- void setWin32VersionValue(dword value); // EXPORT
- /// Sets the SizeOfImage value of the header.
- void setSizeOfImage(dword value); // EXPORT
- /// Sets the SizeOfHeaders value of the header.
- void setSizeOfHeaders(dword value); // EXPORT
- /// Sets the CheckSum value of the header.
- void setCheckSum(dword value); // EXPORT
- /// Sets the Subsystem value of the header.
- void setSubsystem(word value); // EXPORT
- /// Sets the DllCharacteristics value of the header.
- void setDllCharacteristics(word value); // EXPORT
- /// Sets the SizeOfStackReserve value of the header.
- void setSizeOfStackReserve(VAR4_8 value); // EXPORT
- /// Sets the SizeOfStackCommit value of the header.
- void setSizeOfStackCommit(VAR4_8 value); // EXPORT
- /// Sets the SizeOfHeapReserve value of the header.
- void setSizeOfHeapReserve(VAR4_8 value); // EXPORT
- /// Sets the SizeOfHeapCommit value of the header.
- void setSizeOfHeapCommit(VAR4_8 value); // EXPORT
- /// Sets the LoaderFlags value of the header.
- void setLoaderFlags(dword value); // EXPORT
- /// Sets the NumberOfRvaAndSizes value of the header.
- void setNumberOfRvaAndSizes(dword value); // EXPORT
-
-// image directory getters
- void setIddDebugRva(dword dwValue); // EXPORT
- void setIddDebugSize(dword dwValue); // EXPORT
- void setIddDelayImportRva(dword dwValue); // EXPORT
- void setIddDelayImportSize(dword dwValue); // EXPORT
- void setIddExceptionRva(dword dwValue); // EXPORT
- void setIddExceptionSize(dword dwValue); // EXPORT
- void setIddGlobalPtrRva(dword dwValue); // EXPORT
- void setIddGlobalPtrSize(dword dwValue); // EXPORT
- void setIddIatRva(dword dwValue); // EXPORT
- void setIddIatSize(dword dwValue); // EXPORT
- void setIddLoadConfigRva(dword dwValue); // EXPORT
- void setIddLoadConfigSize(dword dwValue); // EXPORT
- void setIddResourceRva(dword dwValue); // EXPORT
- void setIddResourceSize(dword dwValue); // EXPORT
- void setIddSecurityRva(dword dwValue); // EXPORT
- void setIddSecuritySize(dword dwValue); // EXPORT
- void setIddTlsRva(dword dwValue); // EXPORT
- void setIddTlsSize(dword dwValue); // EXPORT
-
- void setIddImportRva(dword dwValue); // EXPORT
- void setIddImportSize(dword dwValue); // EXPORT
- void setIddExportRva(dword dwValue); // EXPORT
- void setIddExportSize(dword dwValue); // EXPORT
-
- void setIddBaseRelocRva(dword value); // EXPORT
- void setIddBaseRelocSize(dword value); // EXPORT
- void setIddArchitectureRva(dword value); // EXPORT
- void setIddArchitectureSize(dword value); // EXPORT
- void setIddComHeaderRva(dword value); // EXPORT
- void setIddComHeaderSize(dword value); // EXPORT
-
- /// Set the name of a section.
- void setSectionName(word uiSectionnr, std::string strName); // EXPORT
- /// Set the virtual size of a section.
- void setVirtualSize(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the virtual address of a section.
- void setVirtualAddress(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the size of raw data of a section.
- void setSizeOfRawData(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the file offset of a section.
- void setPointerToRawData(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the pointer to relocations of a section.
- void setPointerToRelocations(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the pointer to linenumbers of a section.
- void setPointerToLinenumbers(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the number of relocations a section.
- void setNumberOfRelocations(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the number of linenumbers section.
- void setNumberOfLinenumbers(word uiSectionnr, dword dwValue); // EXPORT
- /// Set the characteristics of a section.
- void setCharacteristics(word uiSectionnr, dword dwValue); // EXPORT
- };
-
- class PeHeader32 : public PeHeaderT<32>
- {
- public:
- /// Returns the BaseOfData value of the header.
- dword getBaseOfData() const; // EXPORT
- /// Sets the BaseOfData value of the header.
- void setBaseOfData(dword value); // EXPORT
- };
-
- class PeHeader64 : public PeHeaderT<64>
- {
- };
-
- template<int x>
- void PeHeaderT<x>::addDataDirectory()
- {
- m_inthHeader.dataDirectories.push_back(PELIB_IMAGE_DATA_DIRECTORY());
- }
-
- template<int x>
- void PeHeaderT<x>::removeDataDirectory(dword index)
- {
- m_inthHeader.dataDirectories.erase(m_inthHeader.dataDirectories.begin() + index);
- }
-
- /**
- * Adds a new section to the header. The physical and virtual address as well as the virtual
- * size of the section will be determined automatically from the raw size. The section
- * characteristics will be set to IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ |
- * IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_CODE. All other values will be set to 0.
- * Note: It's important that if the current header's FileAlignment and/or SectionAlignment values are
- * 0 this function will fail.
- * @param strName Name of the new section. If this name is longer than 8 bytes only the first 8 bytes will be used.
- * @param dwSize Physical size of the new section in bytes.
- * \todo Better code that handles files with 0 sections.
- **/
- template<int x>
- int PeHeaderT<x>::addSection(const std::string& strName, dword dwSize)
- {
- unsigned int uiSecnr = calcNumberOfSections();
-
- if (!getFileAlignment())
- {
- return ERROR_NO_FILE_ALIGNMENT;
- }
- else if (!getSectionAlignment())
- {
- return ERROR_NO_SECTION_ALIGNMENT;
- }
-
- if (uiSecnr) // Always allow 1 section.
- {
- if (uiSecnr == 0xFFFF)
- {
- return ERROR_TOO_MANY_SECTIONS;
- }
- else if (calcSpaceAfterHeader() < PELIB_IMAGE_SECTION_HEADER::size())
- {
- return ERROR_NOT_ENOUGH_SPACE;
- }
- }
-
- dword dwOffset = calcOffset(/*dwSize*/);
- dword dwRva = calcRva(/*dwSize*/);
-
- PELIB_IMAGE_SECTION_HEADER ishdCurr;
- m_vIsh.push_back(ishdCurr);
-
- setSectionName(uiSecnr, strName);
- setSizeOfRawData(uiSecnr, alignOffset(dwSize, getFileAlignment()));
- setPointerToRawData(uiSecnr, dwOffset);
- setVirtualSize(uiSecnr, alignOffset(dwSize, getSectionAlignment()));
- setVirtualAddress(uiSecnr, dwRva);
- setCharacteristics(uiSecnr, PELIB_IMAGE_SCN_MEM_WRITE | PELIB_IMAGE_SCN_MEM_READ | PELIB_IMAGE_SCN_CNT_INITIALIZED_DATA | PELIB_IMAGE_SCN_CNT_CODE);
-
- return NO_ERROR;
- }
-
- /**
- * Calculates a valid SizeOfImage value given the information from the current PE header.
- * Note that this calculation works in Win2K but probably does not work in Win9X. I didn't test that though.
- * @return Valid SizeOfImage value.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::calcSizeOfImage() const
- {
- // Major note here: It's possible for sections to exist with a Virtual Size of 0.
- // That's why it's necessary to use std::max(Vsize, RawSize) here.
- // An example for such a file is dbeng6.exe (made by Sybase).
- // In this file each and every section has a VSize of 0 but it still runs.
-
- std::vector<PELIB_IMAGE_SECTION_HEADER>::const_iterator ishLastSection = std::max_element(m_vIsh.begin(), m_vIsh.end(), std::mem_fun_ref(&PELIB_IMAGE_SECTION_HEADER::biggerVirtualAddress));
- if (ishLastSection->VirtualSize != 0) return ishLastSection->VirtualAddress + ishLastSection->VirtualSize;
- return ishLastSection->VirtualAddress + std::max(ishLastSection->VirtualSize, ishLastSection->SizeOfRawData);
- }
-
- /**
- * Calculates the space between the last byte of the header and the first byte that's used for something
- * else (that's either the first section or an image directory).
- * @return Unused space after the header.
- * \todo There are PE files with sections beginning at offset 0. They
- * need to be considered.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::calcSpaceAfterHeader() const
- {
- return (calcStartOfCode() > size() + m_uiOffset) ? calcStartOfCode() - (size() + m_uiOffset) : 0;
- }
-
- /**
- * Returns the first offset of the file that's actually used for something different than the header.
- * That something is not necessarily code, it can be a data directory too.
- * This offset can be the beginning of a section or the beginning of a directory.
- * \todo Some optimizization is surely possible here.
- * \todo There are PE files with sections beginning at offset 0. They
- * need to be considered. Returning 0 for these files doesn't really make sense.
- * So far these sections are disregarded.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::calcStartOfCode() const
- {
- unsigned int directories = calcNumberOfRvaAndSizes();
- dword dwMinOffset = 0xFFFFFFFF;
- if (directories >= 1 && getIddExportRva() && rvaToOffset(getIddExportRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddExportRva());
- if (directories >= 2 && getIddImportRva() && rvaToOffset(getIddImportRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddImportRva());
- if (directories >= 3 && getIddResourceRva() && rvaToOffset(getIddResourceRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddResourceRva());
- if (directories >= 4 && getIddExceptionRva() && rvaToOffset(getIddExceptionRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddExceptionRva());
- if (directories >= 5 && getIddSecurityRva() && rvaToOffset(getIddSecurityRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddSecurityRva());
- if (directories >= 6 && getIddBaseRelocRva() && rvaToOffset(getIddBaseRelocRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddBaseRelocRva());
- if (directories >= 7 && getIddDebugRva() && rvaToOffset(getIddDebugRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddDebugRva());
- if (directories >= 8 && getIddArchitectureRva() && rvaToOffset(getIddArchitectureRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddArchitectureRva());
- if (directories >= 9 && getIddGlobalPtrRva() && rvaToOffset(getIddGlobalPtrRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddGlobalPtrRva());
- if (directories >= 10 && getIddTlsRva() && rvaToOffset(getIddTlsRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddTlsRva());
- if (directories >= 11 && getIddLoadConfigRva() && rvaToOffset(getIddLoadConfigRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddLoadConfigRva());
- if (directories >= 12 && getIddBoundImportRva() && rvaToOffset(getIddBoundImportRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddBoundImportRva());
- if (directories >= 13 && getIddIatRva() && rvaToOffset(getIddIatRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddIatRva());
- if (directories >= 14 && getIddDelayImportRva() && rvaToOffset(getIddDelayImportRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddDelayImportRva());
- if (directories >= 15 && getIddComHeaderRva() && rvaToOffset(getIddComHeaderRva()) < dwMinOffset) dwMinOffset = rvaToOffset(getIddComHeaderRva());
-
- for (word i=0;i<calcNumberOfSections();i++)
- {
- if ((getPointerToRawData(i) < dwMinOffset || dwMinOffset == 0xFFFFFFFF) && getSizeOfRawData(i))
- {
- if (getPointerToRawData(i)) dwMinOffset = getPointerToRawData(i);
- }
- }
- return dwMinOffset;
- }
-
- /**
- * Calculates the file offset for a new section. The file offset will already be aligned to the file's FileAlignment.
- * @return Aligned file offset.
- * \todo uiSize isn't used yet. Will be used later on to search for caves.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::calcOffset(/*unsigned int uiSize*/) const
- {
- unsigned int maxoffset = size();
-
- for (word i=0;i<calcNumberOfSections();i++)
- {
- if (getPointerToRawData(i) + getSizeOfRawData(i) > maxoffset) maxoffset = getPointerToRawData(i) + getSizeOfRawData(i);
- }
-
- return alignOffset(maxoffset, getFileAlignment());
- }
-
- /**
- * Calculates the Rva for a new section. The Rva will already be aligned to the file's SectionAlignment.
- * \todo uiSize isn't used yet. Will be used later on to search for caves.
- * @return Aligned Rva.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::calcRva(/*unsigned int uiSize*/) const
- {
- // Major note here: It's possible for sections to exist with a Virtual Size of 0.
- // That's why it's necessary to use std::max(Vsize, RawSize) here.
- // An example for such a file is dbeng6.exe (made by Sybase).
- // In this file each and every section has a VSize of 0 but it still runs.
-
- unsigned int maxoffset = size();
- for (word i=0;i<calcNumberOfSections();i++)
- {
- if (getVirtualAddress(i) + std::max(getVirtualSize(i), getSizeOfRawData(i)) > maxoffset) maxoffset = getVirtualAddress(i) + std::max(getVirtualSize(i), getSizeOfRawData(i));
- }
-
- return alignOffset(maxoffset, getSectionAlignment());
- }
-
- /**
- * Returns the number of currently defined sections. Note that this value can be different from the number
- * of sections according to the header (see #PeLib::PeHeaderT<x>::getNumberOfSections).
- * @return Number of currently defined sections.
- **/
- template<int x>
- word PeHeaderT<x>::calcNumberOfSections() const
- {
- return static_cast<PeLib::word>(m_vIsh.size());
- }
-
- /**
- * Enlarges the physically last section in the file.
- * @param uiSize Additional size that's added to the section's size.
- **/
- template<int x>
- void PeHeaderT<x>::enlargeLastSection(unsigned int uiSize)
- {
- std::vector<PELIB_IMAGE_SECTION_HEADER>::iterator ishLastSection = std::max_element(m_vIsh.begin(), m_vIsh.end(), std::mem_fun_ref(&PELIB_IMAGE_SECTION_HEADER::biggerFileOffset));
- unsigned int uiRawDataSize = alignOffset(ishLastSection->SizeOfRawData + uiSize, getFileAlignment());
-
- ishLastSection->SizeOfRawData = uiRawDataSize;
- ishLastSection->VirtualSize = ishLastSection->SizeOfRawData;
-
- setSizeOfImage(calcSizeOfImage());
- }
-
- /**
- * Determines the section which contains the file offset.
- * @param dwOffset File offset.
- * @return Section Id of the section which contains the offset.
- **/
- template<int x>
- word PeHeaderT<x>::getSectionWithOffset(VAR4_8 dwOffset) const
- {
- // Offset = 0 must be handled explicitly as there are files
- // with sections that begin at offset 0, that means the section
- // only exists in memory.
-
- if (!dwOffset) return std::numeric_limits<word>::max();
-
- for (word i=0;i<calcNumberOfSections();i++)
- {
- // Explicity exclude sections with raw pointer = 0.
- dword rawptr = getPointerToRawData(i);
- if (rawptr && rawptr <= dwOffset && rawptr + getSizeOfRawData(i) > dwOffset) return i;
- }
-
- return std::numeric_limits<word>::max();
- }
-
- /**
- * Determines the section which contains the Rva.
- * @param dwRva A relative virtual address.
- * @return Section Id of the section which contains the Rva.
- **/
- template<int x>
- word PeHeaderT<x>::getSectionWithRva(VAR4_8 dwRva) const
- {
- // Major note here: It's possible for sections to exist with a Virtual Size of 0.
- // That's why it's necessary to use std::max(Vsize, RawSize) here.
- // An example for such a file is dbeng6.exe (made by Sybase).
- // In this file each and every section has a VSize of 0 but it still runs.
-
- for (word i=0;i<calcNumberOfSections();i++)
- {
- // Weird VC++7 error doesn't allow me to use std::max here.
- dword max = getVirtualSize(i) >= getSizeOfRawData(i) ? getVirtualSize(i) : getSizeOfRawData(i);
- if (getVirtualAddress(i) <= dwRva && getVirtualAddress(i) + max > dwRva) return i;
- }
-
- return -1;
- }
-
- /**
- * Corrects all faulty values of the current PE header. The following values will be corrected: NtSignature,
- * NumberOfSections, SizeOfOptionalHeader, FileAlignment (will be aligned to n*0x200),
- * SectionAlignment (will be aligned to n*0x1000), NumberOfRvaAndSizes, SizeOfHeaders, SizeOfImage,
- * Magic, Characteristics.
- * @param dwOffset Beginning of PeHeader (see #PeLib::MzHeader::getAddressOfPeHeader).
- * \todo 32bit and 64bit versions.
- **/
- template<int x>
- void PeHeaderT<x>::makeValid(dword dwOffset)
- {
- setNtSignature(PELIB_IMAGE_NT_SIGNATURE); // 'PE'
- setMachine(PELIB_IMAGE_FILE_MACHINE_I386);
- setNumberOfSections(calcNumberOfSections());
-
- // Check if 64 bits.
- setSizeOfOptionalHeader(PELIB_IMAGE_OPTIONAL_HEADER<x>::size() + calcNumberOfRvaAndSizes() * 8);
-
- // Check if 64 bits.
- dword dwCharacteristics = PELIB_IMAGE_FILE_EXECUTABLE_IMAGE | PELIB_IMAGE_FILE_32BIT_MACHINE;
- setCharacteristics(dwCharacteristics);
-
- // Check if 64 bits.
- setMagic(PELIB_IMAGE_NT_OPTIONAL_HDR32_MAGIC);
-
- // setImageBase(0x01000000);
-
- // Align file and section alignment values
- unsigned int dwAlignedOffset = alignOffset(getSectionAlignment(), 0x1000);
- setSectionAlignment(dwAlignedOffset ? dwAlignedOffset : 0x1000);
-
- dwAlignedOffset = alignOffset(getFileAlignment(), 0x200);
- setFileAlignment(dwAlignedOffset ? dwAlignedOffset : 0x200);
-
-// setMajorSubsystemVersion(4);
-// setSubsystem(IMAGE_SUBSYSTEM_WINDOWS_GUI);
- setNumberOfRvaAndSizes(calcNumberOfRvaAndSizes());
-
- // Code below depends on code above. Don't change the order.
- dword dwSizeOfHeaders = alignOffset(dwOffset + size(), getFileAlignment());
- setSizeOfHeaders(dwSizeOfHeaders);
-
- dword dwSizeOfImage = alignOffset(dwSizeOfHeaders, getSectionAlignment());
-
- for (int i=0;i<calcNumberOfSections();i++)
- {
- dwSizeOfImage += alignOffset(getVirtualSize(i), getSectionAlignment());
- }
-
- dwSizeOfImage = alignOffset(dwSizeOfImage, getSectionAlignment());
- setSizeOfImage(dwSizeOfImage);
- }
-
- template<int x>
- unsigned int PeHeaderT<x>::offsetToRva(VAR4_8 dwOffset) const
- {
- if (dwOffset < calcStartOfCode()) return dwOffset;
-
- PeLib::word uiSecnr = getSectionWithOffset(dwOffset);
-
- if (uiSecnr == 0xFFFF) return -1;
-
- return getVirtualAddress(uiSecnr) + dwOffset - getPointerToRawData(uiSecnr);
- }
-
- /**
- * Converts a file offset to a virtual address.
- * @param dwOffset File offset.
- * @return Virtual Address.
- **/
- template<int x>
- unsigned int PeHeaderT<x>::offsetToVa(VAR4_8 dwOffset) const
- {
- if (dwOffset < calcStartOfCode()) return getImageBase() + dwOffset;
-
- PeLib::word uiSecnr = getSectionWithOffset(dwOffset);
-
- if (uiSecnr == 0xFFFF) return -1;
-
- return getImageBase() + getVirtualAddress(uiSecnr) + dwOffset - getPointerToRawData(uiSecnr);
- }
-
- template<int x>
- void PeHeaderT<x>::readHeader(InputBuffer& ibBuffer, PELIB_IMAGE_NT_HEADERS<x>& header) const
- {
- ibBuffer >> header.Signature;
-
- ibBuffer >> header.FileHeader.Machine;
- ibBuffer >> header.FileHeader.NumberOfSections;
- ibBuffer >> header.FileHeader.TimeDateStamp;
- ibBuffer >> header.FileHeader.PointerToSymbolTable;
- ibBuffer >> header.FileHeader.NumberOfSymbols;
- ibBuffer >> header.FileHeader.SizeOfOptionalHeader;
- ibBuffer >> header.FileHeader.Characteristics;
- ibBuffer >> header.OptionalHeader.Magic;
-
- ibBuffer >> header.OptionalHeader.MajorLinkerVersion;
- ibBuffer >> header.OptionalHeader.MinorLinkerVersion;
- ibBuffer >> header.OptionalHeader.SizeOfCode;
- ibBuffer >> header.OptionalHeader.SizeOfInitializedData;
- ibBuffer >> header.OptionalHeader.SizeOfUninitializedData;
- ibBuffer >> header.OptionalHeader.AddressOfEntryPoint;
- ibBuffer >> header.OptionalHeader.BaseOfCode;
- readBaseOfData(ibBuffer, header);
- ibBuffer >> header.OptionalHeader.ImageBase;
- ibBuffer >> header.OptionalHeader.SectionAlignment;
- ibBuffer >> header.OptionalHeader.FileAlignment;
- ibBuffer >> header.OptionalHeader.MajorOperatingSystemVersion;
- ibBuffer >> header.OptionalHeader.MinorOperatingSystemVersion;
- ibBuffer >> header.OptionalHeader.MajorImageVersion;
- ibBuffer >> header.OptionalHeader.MinorImageVersion;
- ibBuffer >> header.OptionalHeader.MajorSubsystemVersion;
- ibBuffer >> header.OptionalHeader.MinorSubsystemVersion;
- ibBuffer >> header.OptionalHeader.Win32VersionValue;
- ibBuffer >> header.OptionalHeader.SizeOfImage;
- ibBuffer >> header.OptionalHeader.SizeOfHeaders;
- ibBuffer >> header.OptionalHeader.CheckSum;
- ibBuffer >> header.OptionalHeader.Subsystem;
- ibBuffer >> header.OptionalHeader.DllCharacteristics;
- ibBuffer >> header.OptionalHeader.SizeOfStackReserve;
- ibBuffer >> header.OptionalHeader.SizeOfStackCommit;
- ibBuffer >> header.OptionalHeader.SizeOfHeapReserve;
- ibBuffer >> header.OptionalHeader.SizeOfHeapCommit;
- ibBuffer >> header.OptionalHeader.LoaderFlags;
- ibBuffer >> header.Optiona |