Bug Summary

File:Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h
Location:line 205, column 8
Description:Value stored to 'OutBuffer' during its initialization is never read

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#ifndef _WII_IPC_HLE_DEVICE_H_
6#define _WII_IPC_HLE_DEVICE_H_
7
8#include <string>
9#include <queue>
10#include "../HW/Memmap.h"
11
12#include "ChunkFile.h"
13
14#define FS_SUCCESS(u32)0 (u32)0 // Success
15#define FS_EACCES(u32)-1 (u32)-1 // Permission denied
16#define FS_EEXIST(u32)-2 (u32)-2 // File exists
17#define FS_EINVAL(u32)-4 (u32)-4 // Invalid argument Invalid FD
18#define FS_ENOENT(u32)-6 (u32)-6 // File not found
19#define FS_EBUSY(u32)-8 (u32)-8 // Resource busy
20#define FS_EIO(u32)-12 (u32)-12 // Returned on ECC error
21#define FS_ENOMEM(u32)-22 (u32)-22 // Alloc failed during request
22#define FS_EFATAL(u32)-101 (u32)-101 // Fatal error
23#define FS_EACCESS(u32)-102 (u32)-102 // Permission denied
24#define FS_ECORRUPT(u32)-103 (u32)-103 // returned for "corrupted" NAND
25#define FS_EEXIST2(u32)-105 (u32)-105 // File exists
26#define FS_ENOENT2(u32)-106 (u32)-106 // File not found
27#define FS_ENFILE(u32)-107 (u32)-107 // Too many fds open
28#define FS_EFBIG(u32)-108 (u32)-108 // Max block count reached?
29#define FS_EFDEXHAUSTED(u32)-109 (u32)-109 // Too many fds open
30#define FS_ENAMELEN(u32)-110 (u32)-110 // Pathname is too long
31#define FS_EFDOPEN(u32)-111 (u32)-111 // FD is already open
32#define FS_EIO2(u32)-114 (u32)-114 // Returned on ECC error
33#define FS_ENOTEMPTY(u32)-115 (u32)-115 // Directory not empty
34#define FS_EDIRDEPTH(u32)-116 (u32)-116 // Max directory depth exceeded
35#define FS_EBUSY2(u32)-118 (u32)-118 // Resource busy
36//#define FS_EFATAL (u32)-119 // Fatal error not used by IOS as fatal ERROR
37#define FS_EESEXHAUSTED(u32)-1016 (u32)-1016 // Max of 2 ES handles at a time
38
39class IWII_IPC_HLE_Device
40{
41public:
42
43 IWII_IPC_HLE_Device(u32 _DeviceID, const std::string& _rName, bool _Hardware = true) :
44 m_Name(_rName),
45 m_DeviceID(_DeviceID),
46 m_Hardware(_Hardware),
47 m_Active(false)
48 {
49 }
50
51 virtual ~IWII_IPC_HLE_Device()
52 {
53 }
54
55 virtual void DoState(PointerWrap& p)
56 {
57 DoStateShared(p);
58 p.Do(m_Active);
59 }
60
61 void DoStateShared(PointerWrap& p);
62
63 const std::string& GetDeviceName() const { return m_Name; }
64 u32 GetDeviceID() const { return m_DeviceID; }
65
66 virtual bool Open(u32 _CommandAddress, u32 _Mode)
67 {
68 (void)_Mode;
69 WARN_LOG(WII_IPC_HLE, "%s does not support Open()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 69, "%s does not support Open()", m_Name.c_str()); } } while
(0)
;
70 Memory::Write_U32(FS_ENOENT(u32)-6, _CommandAddress + 4);
71 m_Active = true;
72 return true;
73 }
74
75 virtual bool Close(u32 _CommandAddress, bool _bForce = false)
76 {
77 WARN_LOG(WII_IPC_HLE, "%s does not support Close()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 77, "%s does not support Close()", m_Name.c_str()); } } while
(0)
;
78 if (!_bForce)
79 Memory::Write_U32(FS_EINVAL(u32)-4, _CommandAddress + 4);
80 m_Active = false;
81 return true;
82 }
83
84#define UNIMPLEMENTED_CMD(cmd) WARN_LOG(WII_IPC_HLE, "%s does not support "#cmd"()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 84, "%s does not support "#cmd"()", m_Name.c_str()); } } while
(0)
; return true;
85 virtual bool Seek (u32) { UNIMPLEMENTED_CMD(Seek) }
86 virtual bool Read (u32) { UNIMPLEMENTED_CMD(Read) }
87 virtual bool Write (u32) { UNIMPLEMENTED_CMD(Write) }
88 virtual bool IOCtl (u32) { UNIMPLEMENTED_CMD(IOCtl) }
89 virtual bool IOCtlV (u32) { UNIMPLEMENTED_CMD(IOCtlV) }
90#undef UNIMPLEMENTED_CMD
91
92 virtual int GetCmdDelay(u32) { return 0; }
93
94 virtual u32 Update() { return 0; }
95
96 virtual bool IsHardware() { return m_Hardware; }
97 virtual bool IsOpened() { return m_Active; }
98
99protected:
100
101 // STATE_TO_SAVE
102 std::string m_Name;
103 u32 m_DeviceID;
104 bool m_Hardware;
105 bool m_Active;
106
107 // A struct for IOS ioctlv calls
108 struct SIOCtlVBuffer
109 {
110 SIOCtlVBuffer(u32 _Address) : m_Address(_Address)
111 {
112 // These are the Ioctlv parameters in the IOS communication. The BufferVector
113 // is a memory address offset at where the in and out buffer addresses are
114 // stored.
115 Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
116 NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
117 NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
118 BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
119
120 // The start of the out buffer
121 u32 BufferVectorOffset = BufferVector;
122
123 // Write the address and size for all in messages
124 for (u32 i = 0; i < NumberInBuffer; i++)
125 {
126 SBuffer Buffer;
127 Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
128 BufferVectorOffset += 4;
129 Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
130 BufferVectorOffset += 4;
131 InBuffer.push_back(Buffer);
132 DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x",do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 133, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
133 i, Buffer.m_Address, Buffer.m_Size)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 133, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
;
134 }
135
136 // Write the address and size for all out or in-out messages
137 for (u32 i = 0; i < NumberPayloadBuffer; i++)
138 {
139 SBuffer Buffer;
140 Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
141 BufferVectorOffset += 4;
142 Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
143 BufferVectorOffset += 4;
144 PayloadBuffer.push_back(Buffer);
145 DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x",do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 146, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
146 i, Buffer.m_Address, Buffer.m_Size)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 146, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
;
147 }
148 }
149
150 const u32 m_Address;
151
152 u32 Parameter;
153 u32 NumberInBuffer;
154 u32 NumberPayloadBuffer;
155 u32 BufferVector;
156
157 struct SBuffer { u32 m_Address, m_Size; };
158 std::vector<SBuffer> InBuffer;
159 std::vector<SBuffer> PayloadBuffer;
160 };
161
162 // Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers
163 // of 4 byte commands.
164 void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8,
165 LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE,
166 LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG)
167 {
168 GENERIC_LOG(LogType, Verbosity, "CommandDump of %s",{ if (Verbosity <= 3) GenericLog(Verbosity, LogType, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 169, "CommandDump of %s", GetDeviceName().c_str()); }
169 GetDeviceName().c_str()){ if (Verbosity <= 3) GenericLog(Verbosity, LogType, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 169, "CommandDump of %s", GetDeviceName().c_str()); }
;
170 for (u32 i = 0; i < _NumberOfCommands; i++)
171 {
172 GENERIC_LOG(LogType, Verbosity, " Command%02i: 0x%08x", i,{ if (Verbosity <= 3) GenericLog(Verbosity, LogType, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 173, " Command%02i: 0x%08x", i, Memory::Read_U32(_CommandAddress
+ i*4)); }
173 Memory::Read_U32(_CommandAddress + i*4)){ if (Verbosity <= 3) GenericLog(Verbosity, LogType, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 173, " Command%02i: 0x%08x", i, Memory::Read_U32(_CommandAddress
+ i*4)); }
;
174 }
175 }
176
177 void DumpAsync(u32 BufferVector, u32 NumberInBuffer, u32 NumberOutBuffer,
178 LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE,
179 LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG)
180 {
181 GENERIC_LOG(LogType, Verbosity, "======= DumpAsync ======"){ if (Verbosity <= 3) GenericLog(Verbosity, LogType, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 181, "======= DumpAsync ======"); }
;
182
183 u32 BufferOffset = BufferVector;
184 for (u32 i = 0; i < NumberInBuffer; i++)
185 {
186 u32 InBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
187 u32 InBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
188
189 GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:",{ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 190, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i
); }
190 GetDeviceName().c_str(), i){ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 190, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i
); }
;
191
192 std::string Temp;
193 for (u32 j = 0; j < InBufferSize; j++)
194 {
195 char Buffer[128];
196 sprintf(Buffer, "%02x ", Memory::Read_U8(InBuffer+j));
197 Temp.append(Buffer);
198 }
199
200 GENERIC_LOG(LogType, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str()){ if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 200, " Buffer: %s", Temp.c_str()); }
;
201 }
202
203 for (u32 i = 0; i < NumberOutBuffer; i++)
204 {
205 u32 OutBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
Value stored to 'OutBuffer' during its initialization is never read
206 u32 OutBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
207
208 GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:",{ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 209, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(),
i); }
209 GetDeviceName().c_str(), i){ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 209, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(),
i); }
;
210 GENERIC_LOG(LogType, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):",{ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 211, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize
); }
211 OutBuffer, OutBufferSize){ if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO, LogType
, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 211, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize
); }
;
212
213 #if defined(MAX_LOGLEVEL3) && MAX_LOGLEVEL3 >= INFO_LEVEL4
214 DumpCommands(OutBuffer, OutBufferSize, LogType, Verbosity);
215 #endif
216 }
217 }
218};
219
220class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device
221{
222public:
223 CWII_IPC_HLE_Device_stub(u32 DeviceID, const std::string& Name)
224 : IWII_IPC_HLE_Device(DeviceID, Name)
225 {
226 }
227
228 bool Open(u32 CommandAddress, u32 Mode)
229 {
230 (void)Mode;
231 WARN_LOG(WII_IPC_HLE, "%s faking Open()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 231, "%s faking Open()", m_Name.c_str()); } } while (0)
;
232 Memory::Write_U32(GetDeviceID(), CommandAddress + 4);
233 m_Active = true;
234 return true;
235 }
236 bool Close(u32 CommandAddress, bool bForce = false)
237 {
238 WARN_LOG(WII_IPC_HLE, "%s faking Close()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 238, "%s faking Close()", m_Name.c_str()); } } while (0)
;
239 if (!bForce)
240 Memory::Write_U32(FS_SUCCESS(u32)0, CommandAddress + 4);
241 m_Active = false;
242 return true;
243 }
244
245 bool IOCtl(u32 CommandAddress)
246 {
247 WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 247, "%s faking IOCtl()", m_Name.c_str()); } } while (0)
;
248 Memory::Write_U32(FS_SUCCESS(u32)0, CommandAddress + 4);
249 return true;
250 }
251 bool IOCtlV(u32 CommandAddress)
252 {
253 WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_Name.c_str())do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING
, LogTypes::WII_IPC_HLE, "/home/anal/dolphin-emu/Source/Core/Core/Src/Boot/../IPC_HLE/WII_IPC_HLE_Device.h"
, 253, "%s faking IOCtlV()", m_Name.c_str()); } } while (0)
;
254 Memory::Write_U32(FS_SUCCESS(u32)0, CommandAddress + 4);
255 return true;
256 }
257};
258
259#endif