changed IOCTL_SO_GETHOSTID to remove malloc()/free() calls

account for GetIpForwardTable() returning ERROR_MORE_DATA
This commit is contained in:
Toad King 2014-05-16 19:13:52 -04:00
parent ce64885a66
commit e7e6021414
1 changed files with 33 additions and 28 deletions

View File

@ -854,55 +854,60 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress)
INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTID " INFO_LOG(WII_IPC_NET, "IOCTL_SO_GETHOSTID "
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)", "(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
BufferIn, BufferInSize, BufferOut, BufferOutSize); BufferIn, BufferInSize, BufferOut, BufferOutSize);
// default placeholder, in case of failure
ReturnValue = 192 << 24 | 168 << 16 | 1 << 8 | 150;
#ifdef _WIN32 #ifdef _WIN32
DWORD forwardTableSize, ipTableSize; DWORD forwardTableSize, ipTableSize, result;
PMIB_IPFORWARDTABLE forwardTable = (PMIB_IPFORWARDTABLE)malloc(sizeof(MIB_IPFORWARDTABLE)); DWORD ifIndex = -1;
PMIB_IPADDRTABLE ipTable = (PMIB_IPADDRTABLE)malloc(sizeof(MIB_IPADDRTABLE)); std::unique_ptr<MIB_IPFORWARDTABLE> forwardTable;
std::unique_ptr<MIB_IPADDRTABLE> ipTable;
forwardTableSize = sizeof(MIB_IPFORWARDTABLE); forwardTableSize = 0;
if (GetIpForwardTable(forwardTable, &forwardTableSize, 0) == ERROR_INSUFFICIENT_BUFFER) if (GetIpForwardTable(nullptr, &forwardTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
{ {
free(forwardTable); forwardTable = std::unique_ptr<MIB_IPFORWARDTABLE>((PMIB_IPFORWARDTABLE)operator new(forwardTableSize));
forwardTable = (PMIB_IPFORWARDTABLE)malloc(forwardTableSize);
} }
ipTableSize = sizeof(MIB_IPADDRTABLE); ipTableSize = 0;
if (GetIpAddrTable(ipTable, &ipTableSize, 0) == ERROR_INSUFFICIENT_BUFFER) if (GetIpAddrTable(nullptr, &ipTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
{ {
free(ipTable); ipTable = std::unique_ptr<MIB_IPADDRTABLE>((PMIB_IPADDRTABLE)operator new(ipTableSize));
ipTable = (PMIB_IPADDRTABLE)malloc(ipTableSize);
} }
// find the interface IP used for the default route and use that // find the interface IP used for the default route and use that
if (!GetIpForwardTable(forwardTable, &forwardTableSize, 0) && !GetIpAddrTable(ipTable, &ipTableSize, 0)) result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE);
while (result == NO_ERROR || result == ERROR_MORE_DATA) // can return ERROR_MORE_DATA on XP even after the first call
{ {
for (DWORD i = 0; i < forwardTable->dwNumEntries; i++) for (DWORD i = 0; i < forwardTable->dwNumEntries; i++)
{ {
MIB_IPFORWARDROW forwardRow = forwardTable->table[i]; if (forwardTable->table[i].dwForwardDest == 0)
if (forwardRow.dwForwardDest == 0)
{ {
for (DWORD j = 0; j < ipTable->dwNumEntries; j++) ifIndex = forwardTable->table[i].dwForwardIfIndex;
{
MIB_IPADDRROW ipRow = ipTable->table[j];
if (ipRow.dwIndex == forwardRow.dwForwardIfIndex)
{
ReturnValue = Common::swap32(ipRow.dwAddr);
break; break;
} }
} }
if (result == NO_ERROR || ifIndex != -1)
break;
result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE);
}
if (ifIndex != -1 && GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR)
{
for (DWORD i = 0; i < ipTable->dwNumEntries; i++)
{
if (ipTable->table[i].dwIndex == ifIndex)
{
ReturnValue = Common::swap32(ipTable->table[i].dwAddr);
break; break;
} }
} }
} }
free(forwardTable);
free(ipTable);
#endif #endif
// default placeholder, in case of failure
if (ReturnValue == 0)
ReturnValue = 192 << 24 | 168 << 16 | 1 << 8 | 150;
break; break;
} }