| 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 |
| 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 |
| 40 | struct 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 | |
| 94 | class IWII_IPC_HLE_Device |
| 95 | { |
| 96 | public: |
| 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; } |
| 153 | public: |
| 154 | std::string m_Name; |
| 155 | protected: |
| 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 | |
| 220 | class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device |
| 221 | { |
| 222 | public: |
| 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 |