00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022
00023 #include <errno.h>
00024 #include <stdio.h>
00025
00026 #include "MemoryImpl.h"
00027
00028
00029 #include "smbios/message.h"
00030
00031 using namespace std;
00032
00033 namespace memory
00034 {
00035 MemoryFactory::~MemoryFactory() throw()
00036 {}
00037 MemoryFactory::MemoryFactory()
00038 {}
00039
00040 MemoryFactory *MemoryFactory::getFactory()
00041 {
00042
00043
00044
00045 return MemoryFactoryImpl::getFactory(reinterpret_cast<MemoryFactoryImpl *>(0));
00046 }
00047
00048 IMemory *MemoryFactoryImpl::_mem_instance = 0;
00049
00050 MemoryFactoryImpl::~MemoryFactoryImpl() throw()
00051 {
00052 if( _mem_instance )
00053 {
00054 delete _mem_instance;
00055 }
00056 _mem_instance = 0;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 IMemory *MemoryFactoryImpl::getSingleton()
00067 {
00068 if (! _mem_instance)
00069 _mem_instance = makeNew();
00070
00071 return _mem_instance;
00072 }
00073
00074 IMemory *MemoryFactoryImpl::makeNew()
00075 {
00076 if (mode == UnitTestMode)
00077 {
00078 return new MemoryFile( getParameterString("memFile") );
00079 }
00080 else if (mode == AutoDetectMode)
00081 {
00082 return new MemoryOsSpecific( getParameterString("memFile") );
00083 }
00084 else
00085 {
00086 throw smbios::NotImplementedImpl( _("Unknown Memory mode requested.") );
00087 }
00088 }
00089
00090
00091
00092
00093
00094
00095 IMemory::~IMemory ()
00096 {}
00097
00098 IMemory::IMemory ()
00099 {}
00100
00101 MemoryFile::MemoryFile( const string initFilename )
00102 : IMemory(), filename(initFilename), fd(0), rw(false)
00103 {
00104
00105 if( filename == "" )
00106 {
00107 throw AccessErrorImpl( _("File name passed in was null or zero-length.") );
00108 }
00109
00110
00111 fd = fopen( filename.c_str(), "rb" );
00112 if(!fd)
00113 {
00114 AccessErrorImpl accessError;
00115 accessError.setMessageString( _("Unable to open memory. File: %(file)s, OS Error: %(err)s") );
00116 accessError.setParameter( "file", filename );
00117 accessError.setParameter( "err", strerror(errno) );
00118 throw accessError;
00119 }
00120 }
00121
00122 MemoryFile::~MemoryFile()
00123 {
00124 fclose(fd);
00125 }
00126
00127 u8 MemoryFile::getByte( u64 offset ) const
00128 {
00129 u8 value = 0;
00130 fillBuffer( &value, offset, 1 );
00131 return value;
00132 }
00133
00134
00135 void MemoryFile::fillBuffer(u8 *buffer, u64 offset, unsigned int length) const
00136 {
00137
00138 int ret = FSEEK(fd, offset, 0);
00139 if (ret)
00140 {
00141 OutOfBoundsImpl outOfBounds;
00142 outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00143 outOfBounds.setParameter("err", strerror(errno) );
00144 throw outOfBounds;
00145 }
00146 size_t bytesRead = fread( buffer, 1, length, fd );
00147
00148 if ((length != bytesRead))
00149 {
00150 AccessErrorImpl accessError;
00151 accessError.setMessageString(_("Read error trying to read memory. OS Error: %(err)s"));
00152 accessError.setParameter("err", strerror(errno) );
00153 throw accessError;
00154 }
00155 }
00156
00157 void MemoryFile::putByte( u64 offset, u8 byte ) const
00158 {
00159 if(!rw)
00160 {
00161 fclose(fd);
00162 fd = fopen( filename.c_str(), "r+b" );
00163 if(!fd)
00164 {
00165 AccessErrorImpl accessError;
00166 accessError.setMessageString( _("Unable to re-open memory file for writing. File: %(file)s, OS Error: %(err)s") );
00167 accessError.setParameter( "file", filename );
00168 accessError.setParameter( "err", strerror(errno) );
00169 throw accessError;
00170 }
00171 }
00172
00173 int ret = FSEEK(fd, offset, 0);
00174 if( 0 != ret )
00175 {
00176 OutOfBoundsImpl outOfBounds;
00177 outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00178 outOfBounds.setParameter("err", strerror(errno) );
00179 throw outOfBounds;
00180 }
00181 size_t bytesRead = fwrite( &byte, 1, 1, fd );
00182 if( 1 != bytesRead )
00183 {
00184 AccessErrorImpl accessError;
00185 accessError.setMessageString(_("Error trying to write memory. OS Error: %(err)s"));
00186 accessError.setParameter("err", strerror(errno) );
00187 throw accessError;
00188 }
00189 }
00190 }