diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 58c878d0bb..60ffc3fe94 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -291,18 +291,18 @@ void DMA_MemoryToLC(const u32 _CacheAddr, const u32 _MemAddr, const u32 _iNumBlo } } -std::string GetString(u32 em_address) +std::string GetString(u32 em_address, size_t size) { - std::string str; - char c; - - while ((c = Read_U8(em_address)) != '\0') + const char* ptr = reinterpret_cast(GetPointer(em_address)); + if (size == 0) // Null terminated string. { - str += c; - em_address++; + return std::string(ptr); + } + else // Fixed size string, potentially null terminated or null padded. + { + size_t length = strnlen(ptr, size); + return std::string(ptr, length); } - - return str; } // GetPointer must always return an address in the bottom 32 bits of address space, so that 64-bit @@ -358,7 +358,6 @@ u8 *GetPointer(const u32 _Address) return nullptr; } - bool IsRAMAddress(const u32 addr, bool allow_locked_cache, bool allow_fake_vmem) { switch ((addr >> 24) & 0xFC) diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index bf28c16ff2..b90eab3cd1 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -118,7 +118,7 @@ void Write_U64_Swap(const u64 _Data, const u32 _Address); // Useful helper functions, used by ARM JIT void Write_F64(const double _Data, const u32 _Address); -std::string GetString(u32 em_address); +std::string GetString(u32 em_address, size_t size = 0); u8* GetPointer(const u32 _Address); void DMA_LCToMemory(const u32 _iMemAddr, const u32 _iCacheAddr, const u32 _iNumBlocks); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 52c7b84eca..423a1a1c38 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -17,7 +17,7 @@ static Common::replace_v replacements; // This is used by several of the FileIO and /dev/fs functions -std::string HLE_IPC_BuildFilename(std::string path_wii, int _size) +std::string HLE_IPC_BuildFilename(std::string path_wii) { std::string path_full = File::GetUserPath(D_WIIROOT_IDX); @@ -103,7 +103,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) "Read and Write" }; - m_filepath = HLE_IPC_BuildFilename(m_Name, 64); + m_filepath = HLE_IPC_BuildFilename(m_Name); // The file must exist before we can open it // It should be created by ISFS_CreateFile, not here @@ -333,5 +333,5 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) p.Do(m_Mode); p.Do(m_SeekPos); - m_filepath = HLE_IPC_BuildFilename(m_Name, 64); + m_filepath = HLE_IPC_BuildFilename(m_Name); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index da68e189f5..f7a90fc027 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -7,7 +7,7 @@ #include "Common/FileUtil.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" -std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size); +std::string HLE_IPC_BuildFilename(std::string _pFilename); void HLE_IPC_CreateVirtualFATFilesystem(); class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index 21502a4383..1962abaf43 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -85,8 +85,8 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) case IOCTLV_READ_DIR: { // the wii uses this function to define the type (dir or file) - std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer( - CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size)); + std::string DirName(HLE_IPC_BuildFilename(Memory::GetString( + CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size))); INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", DirName.c_str()); @@ -173,8 +173,8 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) // this command sucks because it asks of the number of used // fsBlocks and inodes // It should be correct, but don't count on it... - const char *relativepath = (const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); - std::string path(HLE_IPC_BuildFilename(relativepath, CommandBuffer.InBuffer[0].m_Size)); + std::string relativepath = Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); + std::string path(HLE_IPC_BuildFilename(relativepath)); u32 fsBlocks = 0; u32 iNodes = 0; @@ -184,8 +184,8 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) // LPFaint99: After I found that setting the number of inodes to the number of children + 1 for the directory itself // I decided to compare with sneek which has the following 2 special cases which are // Copyright (C) 2009-2011 crediar http://code.google.com/p/sneek/ - if ((memcmp(relativepath, "/title/00010001", 16 ) == 0 ) || - (memcmp(relativepath, "/title/00010005", 16) == 0 )) + if ((relativepath.compare(0, 16, "/title/00010001") == 0 ) || + (relativepath.compare(0, 16, "/title/00010005") == 0 )) { fsBlocks = 23; // size is size/0x4000 iNodes = 42; // empty folders return a FileCount of 1 @@ -286,7 +286,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; - std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64; + std::string DirName(HLE_IPC_BuildFilename(Memory::GetString(Addr, 64))); Addr += 64; Addr += 9; // owner attribs, permission u8 Attribs = Memory::Read_U8(Addr); @@ -306,7 +306,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; - std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64); Addr += 64; + std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn, 64)); Addr += 64; u8 OwnerPerm = Memory::Read_U8(Addr); Addr += 1; u8 GroupPerm = Memory::Read_U8(Addr); Addr += 1; u8 OtherPerm = Memory::Read_U8(Addr); Addr += 1; @@ -332,7 +332,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 OwnerID = 0; u16 GroupID = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08 (0x3038) for MH3 etc - std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64); + std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn, 64)); u8 OwnerPerm = 0x3; // read/write u8 GroupPerm = 0x3; // read/write u8 OtherPerm = 0x3; // read/write @@ -377,7 +377,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); int Offset = 0; - std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64); + std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; if (File::Delete(Filename)) { @@ -401,10 +401,10 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); int Offset = 0; - std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64); + std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; - std::string FilenameRename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64); + std::string FilenameRename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; // try to make the basis directory @@ -438,7 +438,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 Addr = _BufferIn; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; - std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64; + std::string Filename(HLE_IPC_BuildFilename(Memory::GetString(Addr, 64))); Addr += 64; u8 OwnerPerm = Memory::Read_U8(Addr); Addr++; u8 GroupPerm = Memory::Read_U8(Addr); Addr++; u8 OtherPerm = Memory::Read_U8(Addr); Addr++; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 1a1cb0b2ef..df3840f608 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -919,21 +919,23 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_INETATON: { - struct hostent* remoteHost = gethostbyname((char*)Memory::GetPointer(BufferIn)); + std::string hostname = Memory::GetString(BufferIn); + struct hostent* remoteHost = gethostbyname(hostname.c_str()); Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), BufferOut); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETATON = %d " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X",remoteHost->h_addr_list[0] == nullptr ? -1 : 0, - (char*)Memory::GetPointer(BufferIn), BufferIn, BufferInSize, BufferOut, BufferOutSize, Common::swap32(*(u32*)remoteHost->h_addr_list[0])); + hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize, Common::swap32(*(u32*)remoteHost->h_addr_list[0])); ReturnValue = remoteHost->h_addr_list[0] == nullptr ? 0 : 1; break; } case IOCTL_SO_INETPTON: { + std::string address = Memory::GetString(BufferIn); INFO_LOG(WII_IPC_NET, "IOCTL_SO_INETPTON " - "(Translating: %s)", Memory::GetPointer(BufferIn)); - ReturnValue = inet_pton((char*)Memory::GetPointer(BufferIn), Memory::GetPointer(BufferOut+4)); + "(Translating: %s)", address.c_str()); + ReturnValue = inet_pton(address.c_str(), Memory::GetPointer(BufferOut+4)); break; } @@ -1033,11 +1035,12 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) case IOCTL_SO_GETHOSTBYNAME: { - hostent* remoteHost = gethostbyname((char*)Memory::GetPointer(BufferIn)); + std::string hostname = Memory::GetString(BufferIn); + hostent* remoteHost = gethostbyname(hostname.c_str()); INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTBYNAME " "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - (char*)Memory::GetPointer(BufferIn), BufferIn, BufferInSize, BufferOut, BufferOutSize); + hostname.c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); if (remoteHost) { @@ -1332,13 +1335,23 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) hints.ai_next = nullptr; } - char* pNodeName = nullptr; + // getaddrinfo allows a null pointer for the nodeName or serviceName strings + // So we have to do a bit of juggling here. + std::string nodeNameStr; + const char* pNodeName = nullptr; if (BufferInSize > 0) - pNodeName = (char*)Memory::GetPointer(_BufferIn); + { + nodeNameStr = Memory::GetString(_BufferIn, BufferInSize); + pNodeName = nodeNameStr.c_str(); + } - char* pServiceName = nullptr; + std::string serviceNameStr; + const char* pServiceName = nullptr; if (BufferInSize2 > 0) - pServiceName = (char*)Memory::GetPointer(_BufferIn2); + { + serviceNameStr = Memory::GetString(_BufferIn2, BufferInSize2); + pServiceName = serviceNameStr.c_str(); + } int ret = getaddrinfo(pNodeName, pServiceName, BufferInSize3 ? &hints : nullptr, &result); u32 addr = _BufferOut; @@ -1389,7 +1402,7 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress) INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO " "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", _BufferIn, BufferInSize, _BufferOut, BufferOutSize); - INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetPointer(_BufferIn)); + INFO_LOG(WII_IPC_NET, "IOCTLV_SO_GETADDRINFO: %s", Memory::GetString(_BufferIn).c_str()); ReturnValue = ret; break; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp index bd02d7ba21..4f404ed45e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp @@ -135,7 +135,7 @@ bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) case IOCTLV_NET_SSL_NEW: { int verifyOption = Memory::Read_U32(BufferOut); - const char * hostname = (const char*) Memory::GetPointer(BufferOut2); + std::string hostname = Memory::GetString(BufferOut2, BufferOutSize2); int freeSSL = this->getSSLFreeID(); if (freeSSL) @@ -176,7 +176,7 @@ bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) ssl_set_authmode(&ssl->ctx, SSL_VERIFY_NONE); ssl_set_renegotiation(&ssl->ctx, SSL_RENEGOTIATION_ENABLED); - memcpy(ssl->hostname, hostname, std::min((int)BufferOutSize2, NET_SSL_MAX_HOSTNAME_LEN)); + memcpy(ssl->hostname, hostname.c_str(), std::min((int)BufferOutSize2, NET_SSL_MAX_HOSTNAME_LEN)); ssl->hostname[NET_SSL_MAX_HOSTNAME_LEN-1] = '\0'; ssl_set_hostname(&ssl->ctx, ssl->hostname); @@ -193,7 +193,7 @@ _SSL_NEW_ERROR: "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", - verifyOption, hostname, + verifyOption, hostname.c_str(), _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); @@ -436,7 +436,7 @@ _SSL_NEW_ERROR: _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); - INFO_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(BufferOut2)); + INFO_LOG(WII_IPC_SSL, "%s", Memory::GetString(BufferOut2).c_str()); break; } case IOCTLV_NET_SSL_READ: diff --git a/Source/Core/Core/IPC_HLE/WII_Socket.cpp b/Source/Core/Core/IPC_HLE/WII_Socket.cpp index b5a130c2c6..f7f91f3cd9 100644 --- a/Source/Core/Core/IPC_HLE/WII_Socket.cpp +++ b/Source/Core/Core/IPC_HLE/WII_Socket.cpp @@ -423,7 +423,9 @@ void WiiSocket::Update(bool read, bool write, bool except) u32 flags = Memory::Read_U32(BufferIn2 + 0x04); u32 has_destaddr = Memory::Read_U32(BufferIn2 + 0x08); - char * data = (char*)Memory::GetPointer(BufferIn); + + // Not a string, windows requires a const char* for sendto + const char* data = (const char*)Memory::GetPointer(BufferIn); // Act as non blocking when SO_MSG_NONBLOCK is specified forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK); @@ -457,7 +459,8 @@ void WiiSocket::Update(bool read, bool write, bool except) case IOCTLV_SO_RECVFROM: { u32 flags = Memory::Read_U32(BufferIn + 0x04); - char * data = (char *)Memory::GetPointer(BufferOut); + // Not a string, windows requires a char* for recvfrom + char* data = (char*)Memory::GetPointer(BufferOut); int data_len = BufferOutSize; sockaddr_in local_name;