Bug Summary

File:/home/anal/dolphin-emu/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
39// A struct for IOS ioctlv calls
40struct SIOCtlVBuffer
41{
42 SIOCtlVBuffer(u32 _Address) : m_Address(_Address)
43 {
44 // These are the Ioctlv parameters in the IOS communication. The BufferVector
45 // is a memory address offset at where the in and out buffer addresses are
46 // stored.
47 Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
48 NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
49 NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
50 BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
51
52 // The start of the out buffer
53 u32 BufferVectorOffset = BufferVector;
54
55 // Write the address and size for all in messages
56 for (u32 i = 0; i < NumberInBuffer; i++)
57 {
58 SBuffer Buffer;
59 Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
60 BufferVectorOffset += 4;
61 Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
62 BufferVectorOffset += 4;
63 InBuffer.push_back(Buffer);
64 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"
, 65, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
65 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"
, 65, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
;
66 }
67
68 // Write the address and size for all out or in-out messages
69 for (u32 i = 0; i < NumberPayloadBuffer; i++)
70 {
71 SBuffer Buffer;
72 Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
73 BufferVectorOffset += 4;
74 Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
75 BufferVectorOffset += 4;
76 PayloadBuffer.push_back(Buffer);
77 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"
, 78, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
78 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"
, 78, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address
, Buffer.m_Size); } } while (0)
;
79 }
80 }
81
82 const u32 m_Address;
83
84 u32 Parameter;
85 u32 NumberInBuffer;
86 u32 NumberPayloadBuffer;
87 u32 BufferVector;
88
89 struct SBuffer { u32 m_Address, m_Size; };
90 std::vector<SBuffer> InBuffer;
91 std::vector<SBuffer> PayloadBuffer;
92};
93
94class IWII_IPC_HLE_Device
95{
96public:
97
98 IWII_IPC_HLE_Device(u32 _DeviceID, const std::string& _rName, bool _Hardware = true) :
99 m_Name(_rName),
100 m_DeviceID(_DeviceID),
101 m_Hardware(_Hardware),
102 m_Active(false)
103 {
104 }
105
106 virtual ~IWII_IPC_HLE_Device()
107 {
108 }
109
110 virtual void DoState(PointerWrap& p)
111 {
112 DoStateShared(p);
113 p.Do(m_Active);
114 }
115
116 void DoStateShared(PointerWrap& p);
117
118 const std::string& GetDeviceName() const { return m_Name; }
119 u32 GetDeviceID() const { return m_DeviceID; }
120
121 virtual bool Open(u32 _CommandAddress, u32 _Mode)
122 {
123 (void)_Mode;
124 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"
, 124, "%s does not support Open()", m_Name.c_str()); } } while
(0)
;
125 Memory::Write_U32(FS_ENOENT(u32)-6, _CommandAddress + 4);
126 m_Active = true;
127 return true;
128 }
129
130 virtual bool Close(u32 _CommandAddress, bool _bForce = false)
131 {
132 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"
, 132, "%s does not support Close()", m_Name.c_str()); } } while
(0)
;
133 if (!_bForce)
134 Memory::Write_U32(FS_EINVAL(u32)-4, _CommandAddress + 4);
135 m_Active = false;
136 return true;
137 }
138
139#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"
, 139, "%s does not support "#cmd"()", m_Name.c_str()); } } while
(0)
; return true;
140 virtual bool Seek (u32) { UNIMPLEMENTED_CMD(Seek) }
141 virtual bool Read (u32) { UNIMPLEMENTED_CMD(Read) }
142 virtual bool Write (u32) { UNIMPLEMENTED_CMD(Write) }
143 virtual bool IOCtl (u32) { UNIMPLEMENTED_CMD(IOCtl) }
144 virtual bool IOCtlV (u32) { UNIMPLEMENTED_CMD(IOCtlV) }
145#undef UNIMPLEMENTED_CMD
146
147 virtual int GetCmdDelay(u32) { return 0; }
148
149 virtual u32 Update() { return 0; }
150
151 virtual bool IsHardware() { return m_Hardware; }
152 virtual bool IsOpened() { return m_Active; }
153public:
154 std::string m_Name;
155protected:
156
157 // STATE_TO_SAVE
158 u32 m_DeviceID;
159 bool m_Hardware;
160 bool m_Active;
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