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 #include <cstring>
00026
00027 #include "MemoryImpl.h"
00028
00029
00030 #include "smbios/message.h"
00031
00032 using namespace std;
00033
00034 namespace memory
00035 {
00036 MemoryFactory::~MemoryFactory() throw()
00037 {}
00038 MemoryFactory::MemoryFactory()
00039 {}
00040
00041 MemoryFactory *MemoryFactory::getFactory()
00042 {
00043
00044
00045
00046 return MemoryFactoryImpl::getFactory(reinterpret_cast<MemoryFactoryImpl *>(0));
00047 }
00048
00049 IMemory *MemoryFactoryImpl::_mem_instance = 0;
00050
00051 MemoryFactoryImpl::~MemoryFactoryImpl() throw()
00052 {
00053 if( _mem_instance )
00054 {
00055 delete _mem_instance;
00056 }
00057 _mem_instance = 0;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067 IMemory *MemoryFactoryImpl::getSingleton()
00068 {
00069 if (! _mem_instance)
00070 _mem_instance = makeNew();
00071
00072 return _mem_instance;
00073 }
00074
00075 IMemory *MemoryFactoryImpl::makeNew()
00076 {
00077 if (mode == UnitTestMode)
00078 {
00079 return new MemoryFile( getParameterString("memFile") );
00080 }
00081 else if (mode == AutoDetectMode)
00082 {
00083 return new MemoryOsSpecific( getParameterString("memFile") );
00084 }
00085 else
00086 {
00087 throw smbios::NotImplementedImpl( _("Unknown Memory mode requested.") );
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00096 IMemory::~IMemory ()
00097 {}
00098
00099 IMemory::IMemory ()
00100 {}
00101
00102 MemoryFile::MemoryFile( const string initFilename )
00103 : IMemory(), filename(initFilename), fd(0), rw(false), reopenHint(1)
00104 {
00105
00106 if( filename == "" )
00107 {
00108 throw AccessErrorImpl( _("File name passed in was null or zero-length.") );
00109 }
00110
00111
00112 fd = fopen( filename.c_str(), "rb" );
00113 if (!fd)
00114 {
00115 AccessErrorImpl accessError;
00116 accessError.setMessageString( _("Unable to open memory. File: %(file)s, OS Error: %(err)s") );
00117 accessError.setParameter( "file", filename );
00118 accessError.setParameter( "err", strerror(errno) );
00119 throw accessError;
00120 }
00121
00122 if (reopenHint>0)
00123 {
00124 fclose(fd);
00125 fd=0;
00126 }
00127 }
00128
00129 MemoryFile::~MemoryFile()
00130 {
00131 if (fd)
00132 {
00133 fclose(fd);
00134 fd = 0;
00135 }
00136 }
00137
00138 u8 MemoryFile::getByte( u64 offset ) const
00139 {
00140 u8 value = 0;
00141 fillBuffer( &value, offset, 1 );
00142 return value;
00143 }
00144
00145
00146 void MemoryFile::fillBuffer(u8 *buffer, u64 offset, unsigned int length) const
00147 {
00148 if (!fd)
00149 {
00150
00151 fd = fopen( filename.c_str(), "rb" );
00152 if (!fd)
00153 {
00154 AccessErrorImpl accessError;
00155 accessError.setMessageString( _("Unable to open memory. File: %(file)s, OS Error: %(err)s") );
00156 accessError.setParameter( "file", filename );
00157 accessError.setParameter( "err", strerror(errno) );
00158 throw accessError;
00159 }
00160 }
00161
00162 int ret = FSEEK(fd, offset, 0);
00163 if (ret)
00164 {
00165 OutOfBoundsImpl outOfBounds;
00166 outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00167 outOfBounds.setParameter("err", strerror(errno) );
00168 fclose(fd);
00169 fd = 0;
00170 throw outOfBounds;
00171 }
00172 size_t bytesRead = fread( buffer, 1, length, fd );
00173
00174 if (reopenHint>0)
00175 {
00176 fclose(fd);
00177 fd=0;
00178 }
00179
00180
00181 if ((length != bytesRead))
00182 {
00183 AccessErrorImpl accessError;
00184 accessError.setMessageString(_("Read error trying to read memory. OS Error: %(err)s"));
00185 accessError.setParameter("err", strerror(errno) );
00186 if(fd)
00187 {
00188 fclose(fd);
00189 fd = 0;
00190 }
00191 throw accessError;
00192 }
00193 }
00194
00195 void MemoryFile::putByte( u64 offset, u8 byte ) const
00196 {
00197 if(!rw || !fd)
00198 {
00199 if(fd)
00200 {
00201 fclose(fd);
00202 fd = 0;
00203 }
00204
00205 fd = fopen( filename.c_str(), "r+b" );
00206 if(!fd)
00207 {
00208 AccessErrorImpl accessError;
00209 accessError.setMessageString( _("Unable to re-open memory file for writing. File: %(file)s, OS Error: %(err)s") );
00210 accessError.setParameter( "file", filename );
00211 accessError.setParameter( "err", strerror(errno) );
00212 throw accessError;
00213 }
00214 }
00215
00216 int ret = FSEEK(fd, offset, 0);
00217 if( 0 != ret )
00218 {
00219 OutOfBoundsImpl outOfBounds;
00220 outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00221 outOfBounds.setParameter("err", strerror(errno) );
00222 fclose(fd);
00223 fd = 0;
00224 throw outOfBounds;
00225 }
00226 size_t bytesRead = fwrite( &byte, 1, 1, fd );
00227 if (reopenHint > 0)
00228 {
00229 fclose(fd);
00230 fd = 0;
00231 }
00232 if( 1 != bytesRead )
00233 {
00234 AccessErrorImpl accessError;
00235 accessError.setMessageString(_("Error trying to write memory. OS Error: %(err)s"));
00236 accessError.setParameter("err", strerror(errno) );
00237 if(fd)
00238 {
00239 fclose(fd);
00240 fd = 0;
00241 }
00242 throw accessError;
00243 }
00244 }
00245 }