Bug Summary

File:/home/anal/dolphin-emu/Source/Core/DolphinWX/Src/ISOFile.cpp
Location:line 75, column 44
Description:Forming reference to null pointer

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include <string>
6#include <vector>
7#include <wx/mstream.h>
8
9#include "Common.h"
10#include "CommonPaths.h"
11
12#include "Globals.h"
13#include "FileUtil.h"
14#include "ISOFile.h"
15#include "StringUtil.h"
16#include "Hash.h"
17#include "IniFile.h"
18#include "WxUtils.h"
19
20#include "Filesystem.h"
21#include "BannerLoader.h"
22#include "FileSearch.h"
23#include "CompressedBlob.h"
24#include "ChunkFile.h"
25#include "ConfigManager.h"
26
27static const u32 CACHE_REVISION = 0x115;
28
29#define DVD_BANNER_WIDTH96 96
30#define DVD_BANNER_HEIGHT32 32
31
32GameListItem::GameListItem(const std::string& _rFileName)
33 : m_FileName(_rFileName)
34 , m_emu_state(0)
35 , m_FileSize(0)
36 , m_Revision(0)
37 , m_Valid(false)
38 , m_BlobCompressed(false)
39 , m_ImageWidth(0)
40 , m_ImageHeight(0)
41{
42 if (LoadFromCache())
1
Taking false branch
43 {
44 m_Valid = true;
45 }
46 else
47 {
48 DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(_rFileName);
49
50 if (pVolume != NULL__null)
2
Taking true branch
51 {
52 if (!DiscIO::IsVolumeWadFile(pVolume))
3
Taking false branch
53 m_Platform = DiscIO::IsVolumeWiiDisc(pVolume) ? WII_DISC : GAMECUBE_DISC;
54 else
55 {
56 m_Platform = WII_WAD;
57 }
58
59 m_volume_names = pVolume->GetNames();
60
61 m_Country = pVolume->GetCountry();
62 m_FileSize = pVolume->GetRawSize();
63 m_VolumeSize = pVolume->GetSize();
64
65 m_UniqueID = pVolume->GetUniqueID();
66 m_BlobCompressed = DiscIO::IsCompressedBlob(_rFileName.c_str());
67 m_IsDiscTwo = pVolume->IsDiscTwo();
68 m_Revision = pVolume->GetRevision();
69
70 // check if we can get some info from the banner file too
71 DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
4
'pFileSystem' initialized here
72
73 if (pFileSystem != NULL__null || m_Platform == WII_WAD)
5
Assuming pointer value is null
6
Taking true branch
74 {
75 DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem, pVolume);
7
Forming reference to null pointer
76
77 if (pBannerLoader != NULL__null)
78 {
79 if (pBannerLoader->IsValid())
80 {
81 if (m_Platform != WII_WAD)
82 m_names = pBannerLoader->GetNames();
83 m_company = pBannerLoader->GetCompany();
84 m_descriptions = pBannerLoader->GetDescriptions();
85
86 std::vector<u32> Buffer = pBannerLoader->GetBanner(&m_ImageWidth, &m_ImageHeight);
87 u32* pData = &Buffer[0];
88 // resize vector to image size
89 m_pImage.resize(m_ImageWidth * m_ImageHeight * 3);
90
91 for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++)
92 {
93 m_pImage[i * 3 + 0] = (pData[i] & 0xFF0000) >> 16;
94 m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8;
95 m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0;
96 }
97 }
98 delete pBannerLoader;
99 }
100
101 delete pFileSystem;
102 }
103
104 delete pVolume;
105
106 m_Valid = true;
107
108 // Create a cache file only if we have an image.
109 // Wii isos create their images after you have generated the first savegame
110 if (!m_pImage.empty())
111 SaveToCache();
112 }
113 }
114
115 if (IsValid())
116 {
117 IniFile ini;
118 ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR"GameSettings" DIR_SEP"/" + m_UniqueID + ".ini");
119 ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + m_UniqueID + ".ini", true);
120 ini.Get("EmuState", "EmulationStateId", &m_emu_state);
121 ini.Get("EmuState", "EmulationIssues", &m_issues);
122 }
123
124 if (!m_pImage.empty())
125 {
126 wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
127 double Scale = WxUtils::GetCurrentBitmapLogicalScale();
128 // Note: This uses nearest neighbor, which subjectively looks a lot
129 // better for GC banners than smooths caling.
130 Image.Rescale(DVD_BANNER_WIDTH96 * Scale, DVD_BANNER_HEIGHT32 * Scale);
131#ifdef __APPLE__
132 m_Bitmap = wxBitmap(Image, -1, Scale);
133#else
134 m_Bitmap = wxBitmap(Image, -1);
135#endif
136 }
137 else
138 {
139 // default banner
140 m_Bitmap.LoadFile(StrToWxStr(File::GetThemeDir(SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name)) + "nobanner.png", wxBITMAP_TYPE_PNG);
141 }
142}
143
144GameListItem::~GameListItem()
145{
146}
147
148bool GameListItem::LoadFromCache()
149{
150 return CChunkFileReader::Load<GameListItem>(CreateCacheFilename(), CACHE_REVISION, *this);
151}
152
153void GameListItem::SaveToCache()
154{
155 if (!File::IsDirectory(File::GetUserPath(D_CACHE_IDX)))
156 {
157 File::CreateDir(File::GetUserPath(D_CACHE_IDX));
158 }
159
160 CChunkFileReader::Save<GameListItem>(CreateCacheFilename(), CACHE_REVISION, *this);
161}
162
163void GameListItem::DoState(PointerWrap &p)
164{
165 p.Do(m_volume_names);
166 p.Do(m_company);
167 p.Do(m_names);
168 p.Do(m_descriptions);
169 p.Do(m_UniqueID);
170 p.Do(m_FileSize);
171 p.Do(m_VolumeSize);
172 p.Do(m_Country);
173 p.Do(m_BlobCompressed);
174 p.Do(m_pImage);
175 p.Do(m_ImageWidth);
176 p.Do(m_ImageHeight);
177 p.Do(m_Platform);
178 p.Do(m_IsDiscTwo);
179 p.Do(m_Revision);
180}
181
182std::string GameListItem::CreateCacheFilename()
183{
184 std::string Filename, LegalPathname, extension;
185 SplitPath(m_FileName, &LegalPathname, &Filename, &extension);
186
187 if (Filename.empty()) return Filename; // Disc Drive
188
189 // Filename.extension_HashOfFolderPath_Size.cache
190 // Append hash to prevent ISO name-clashing in different folders.
191 Filename.append(StringFromFormat("%s_%x_%llx.cache",
192 extension.c_str(), HashFletcher((const u8 *)LegalPathname.c_str(), LegalPathname.size()),
193 File::GetSize(m_FileName)));
194
195 std::string fullname(File::GetUserPath(D_CACHE_IDX));
196 fullname += Filename;
197 return fullname;
198}
199
200std::string GameListItem::GetCompany() const
201{
202 if (m_company.empty())
203 return "N/A";
204 else
205 return m_company;
206}
207
208// (-1 = Japanese, 0 = English, etc)?
209std::string GameListItem::GetDescription(int _index) const
210{
211 const u32 index = _index;
212
213 if (index < m_descriptions.size())
214 return m_descriptions[index];
215
216 if (!m_descriptions.empty())
217 return m_descriptions[0];
218
219 return "";
220}
221
222// (-1 = Japanese, 0 = English, etc)?
223std::string GameListItem::GetVolumeName(int _index) const
224{
225 u32 const index = _index;
226
227 if (index < m_volume_names.size() && !m_volume_names[index].empty())
228 return m_volume_names[index];
229
230 if (!m_volume_names.empty())
231 return m_volume_names[0];
232
233 return "";
234}
235
236// (-1 = Japanese, 0 = English, etc)?
237std::string GameListItem::GetBannerName(int _index) const
238{
239 u32 const index = _index;
240
241 if (index < m_names.size() && !m_names[index].empty())
242 return m_names[index];
243
244 if (!m_names.empty())
245 return m_names[0];
246
247 return "";
248}
249
250// (-1 = Japanese, 0 = English, etc)?
251std::string GameListItem::GetName(int _index) const
252{
253 // Prefer name from banner, fallback to name from volume, fallback to filename
254
255 std::string name = GetBannerName(_index);
256
257 if (name.empty())
258 name = GetVolumeName(_index);
259
260 if (name.empty())
261 {
262 // No usable name, return filename (better than nothing)
263 SplitPath(GetFileName(), NULL__null, &name, NULL__null);
264 }
265
266 return name;
267}
268
269const std::string GameListItem::GetWiiFSPath() const
270{
271 DiscIO::IVolume *Iso = DiscIO::CreateVolumeFromFilename(m_FileName);
272 std::string ret;
273
274 if (Iso == NULL__null)
275 return ret;
276
277 if (DiscIO::IsVolumeWiiDisc(Iso) || DiscIO::IsVolumeWadFile(Iso))
278 {
279 char Path[250];
280 u64 Title;
281
282 Iso->GetTitleID((u8*)&Title);
283 Title = Common::swap64(Title);
284
285 sprintf(Path, "%stitle/%08x/%08x/data/",
286 File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(Title>>32), (u32)Title);
287
288 if (!File::Exists(Path))
289 File::CreateFullPath(Path);
290
291 if (Path[0] == '.')
292 ret = WxStrToStr(wxGetCwd()) + std::string(Path).substr(strlen(ROOT_DIR"."));
293 else
294 ret = std::string(Path);
295 }
296 delete Iso;
297
298 return ret;
299}
300