3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: fc_windows.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
39 #if (defined(FILECONTAINER_WINDOWS) || defined(TESTSUITE)) && defined(_MSC_VER)
41 #pragma warning(disable:4786)
43 #include "base/filecontainer.h"
52 class FileContainerWindowsImpl : public FileContainer
59 inline bool isLoaded(void) const
63 FileContainerWindowsImpl(void) throw();
64 virtual ~FileContainerWindowsImpl(void) throw();
67 virtual void attachModule(const string & filename) throw(Exception);
68 virtual void loadContents(void * dest, address_t address, size_t size) throw(Exception);
69 virtual address_t getSymbolAddress(const string & symbol) throw(Exception);
70 virtual std::string getArchitecture(void) throw();
72 TESTSUITE_PROTOTYPE(main)
75 FileContainerWindowsImpl instance_of_FileContaienrWindowsImpl;
78 FileContainerWindowsImpl::FileContainerWindowsImpl(void) throw()
79 : process(NULL), image(), base(0)
83 FileContainerWindowsImpl::~FileContainerWindowsImpl(void) throw()
86 ::UnMapAndLoad(&image);
87 ::SymUnloadModule(process, base);
94 void FileContainerWindowsImpl::attachModule(const std::string & _filename) throw(Exception)
96 string filename(_filename);
98 process = ::GetCurrentProcess();
99 if(::SymInitialize( process , NULL, FALSE) == FALSE)
100 ExceptionMessage("[Internal Error] ImageHelper API initialization failure","[内部エラー] 初期化に失敗しました (ImageHlp)").throwException();
102 base = ::SymLoadModule(process, NULL, (PSTR)filename.c_str(), NULL, 0, 0);
104 image.SizeOfImage = sizeof(LOADED_IMAGE);
105 if(::MapAndLoad((PSTR)filename.c_str(), NULL, &image, FALSE, TRUE) == FALSE)
106 ExceptionMessage("[Internel error] Module loading failure [%]","[内部エラー] モジュールの読み込みに失敗しました [%]") << filename << throwException;
110 void FileContainerWindowsImpl::loadContents(void * dest, address_t address, size_t size) throw(Exception)
112 PIMAGE_SECTION_HEADER header;
116 for(i=0;i<image.NumberOfSections;i++) {
117 header = image.Sections+i;
118 if(address >= header->VirtualAddress && address < header->VirtualAddress + header->SizeOfRawData) {
119 address -= header->VirtualAddress - header->PointerToRawData;
120 ::CopyMemory(dest,image.MappedAddress + address,size);
125 if(i == image.NumberOfSections)
126 ExceptionMessage("[Internel error] Memory read with unmapped address","[内部エラー] マップされてないアドレスを使ってメモリリードが行われました").throwException();
130 FileContainer::address_t FileContainerWindowsImpl::getSymbolAddress(const string & _symbol) throw(Exception)
132 FileContainer::address_t result = 0;
133 string symbol(_symbol);
136 if(process == NULL || base == 0)
137 ExceptionMessage("Not initialized","初期化されてません").throwException();
139 sym.SizeOfStruct = sizeof(sym);
140 sym.MaxNameLength = 0;
142 if(::SymGetSymFromName(process, (PSTR)symbol.c_str(), &sym) == TRUE)
143 result = static_cast<FileContainer::address_t>(sym.Address);
146 ExceptionMessage("Unknown symbol [%]","不正なシンボル名 [%]") << symbol << throwException;
148 return static_cast<FileContainer::address_t>(sym.Address);
151 string FileContainerWindowsImpl::getArchitecture(void) throw()
152 { return "Windows (Win32)"; }
156 //---------------------------------------------
159 #include "base/coverage_undefs.h"
161 #pragma warning(disable:4311) //'reinterpret_cast' : ポインタを 'const int *__w64 ' から 'FileContainer::address_t' へ切り詰めます。
163 extern "C" const int FileContainerWindowsImplTestVariable = 0x01234567;
164 extern "C" const int _FileContainerWindowsImplTestVariableWithUnderbar = 0x89abcdef;
166 TESTSUITE(main, FileContainerWindowsImpl)
168 PREDECESSOR("TFileContainer");
170 SingletonBase::ContextChain chain;
171 chain.saveContext<RuntimeObjectTable>();
172 chain.renewInstance();
174 BEGIN_CASE("attachModule","attachModule") {
175 BEGIN_CASE("1","実行しているプログラムが開けるか") {
176 FileContainerWindowsImpl fcwi;
178 try { fcwi.attachModule(TestSuite::getProgName()); } catch(...) { result = false; }
180 TEST_CASE("1", "例外は起きない", result);
183 BEGIN_CASE("2","存在しないファイル名で例外") {
184 FileContainerWindowsImpl fcwi;
186 try { fcwi.attachModule("..."); } catch(...) { result = true; }
188 TEST_CASE("1", "例外が起きる", result);
192 BEGIN_CASE("getSymbolAddress","getSymbolAddress") {
193 FileContainerWindowsImpl fcwi;
195 BEGIN_CASE("1","初期化していない状態で検索する") {
197 try { fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable"); } catch(...) { result = true; }
198 TEST_CASE("1","例外がおきる", result);
201 fcwi.attachModule(TestSuite::getProgName());
203 BEGIN_CASE("2","存在するシンボルを検索する") {
204 FileContainer::address_t addr = 0;
207 try { addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable"); } catch(...) { result = false; }
209 TEST_CASE("1","例外は起きない", result);
210 TEST_CASE("2","アドレスが正しい", addr == reinterpret_cast<FileContainer::address_t>(&FileContainerWindowsImplTestVariable));
213 BEGIN_CASE("3","余計な_を勝手に付加しない") {
214 FileContainer::address_t addr = 0;
217 try { addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariableWithUnderbar"); } catch(...) { result = true; }
219 TEST_CASE("1","例外が起きる", result);
220 TEST_CASE("2","アドレスは0のまま", addr == 0);
223 BEGIN_CASE("4","存在しないシンボルを検索する") {
224 FileContainer::address_t addr = 0;
227 try { addr = fcwi.getSymbolAddress("____unknown____"); } catch(...) { result = true; }
229 TEST_CASE("1","例外がおきる", result);
233 BEGIN_CASE("loadContents","loadContents") {
234 FileContainerWindowsImpl fcwi;
235 fcwi.attachModule(TestSuite::getProgName());
237 BEGIN_CASE("1","存在する変数を読み出す") {
238 FileContainer::address_t addr;
241 addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable");
243 try { fcwi.loadContents(&i, addr, sizeof(i)); } catch(...) { result = false; }
245 TEST_CASE("1","例外は起きない", result);
246 TEST_CASE("2","読み出された内容は正しい", i == FileContainerWindowsImplTestVariable);
249 BEGIN_CASE("2","存在しない変数を読み出す") {
250 FileContainer::address_t addr;
255 try { fcwi.loadContents(&i, addr, sizeof(i)); } catch(Exception &) { result = true; }
257 TEST_CASE("1","例外が起こる", result);
262 chain.restoreContext();
265 #endif /* TESTSUITE */
267 #endif /* FILECONTAINER_WINDOWS || TESTSUITE */