BOOL COptions::ParseOptionsCommand(unsigned char *pData, DWORD dwDataLength, BOOL bFromLocal /*=FALSE*/) { unsigned char *p = pData; int num = *p * 256 + p[1]; p+=2; if (num!=OPTIONS_NUM) return FALSE; int i; for (i = 0; i < num; ++i) { if ((DWORD)(p-pData)>=dwDataLength) return FALSE; int nType = *p++; if (!nType) { if ((DWORD)(p-pData+3) >= dwDataLength) return 2; int len = *p * 256 * 256 + p[1] * 256 + p[2]; p += 3; if ((DWORD)(p - pData + len) > dwDataLength) return FALSE; char *pBuffer = new char[len + 1]; memcpy(pBuffer, p, len); pBuffer[len]=0; if (!m_Options[i].bOnlyLocal || bFromLocal) //Do not change admin interface settings from remote connections SetOption(i+1, ConvFromNetwork(pBuffer), false); delete [] pBuffer; p+=len; } else if (nType == 1) { if ((DWORD)(p-pData+8)>dwDataLength) return FALSE; if (!m_Options[i].bOnlyLocal || bFromLocal) //Do not change admin interface settings from remote connections SetOption(i+1, GET64(p), false); p+=8; } else return FALSE; } SPEEDLIMITSLIST dl; SPEEDLIMITSLIST ul; if ((DWORD)(p-pData+2)>dwDataLength) return FALSE; num = *p++ << 8; num |= *p++; simple_lock lock(m_mutex); for (i=0; i<num; ++i) { CSpeedLimit limit; p = limit.ParseBuffer(p, dwDataLength - (p - pData)); if (!p) { return FALSE; } dl.push_back(limit); } if ((DWORD)(p-pData+2)>dwDataLength) { return FALSE; } num = *p++ << 8; num |= *p++; for (i=0; i<num; i++) { CSpeedLimit limit; p = limit.ParseBuffer(p, dwDataLength - (p - pData)); if (!p) { return FALSE; } ul.push_back(limit); } m_sSpeedLimits[0] = dl; m_sSpeedLimits[1] = ul; SaveOptions(); UpdateInstances(); return TRUE; }
BOOL COptionsDlg::Init(unsigned char *pData, DWORD dwDataLength) { unsigned char *p = pData; unsigned char const* const endMarker = pData + dwDataLength; if ((endMarker - p) < 2) return FALSE; int num = *p * 256 + p[1]; p += 2; if (num != OPTIONS_NUM) return FALSE; for (int i = 0; i < num; ++i) { if (static_cast<DWORD>(p - pData) >= dwDataLength) return FALSE; int nType = *p++; if (!nType) { if (static_cast<DWORD>(p - pData + 3) >= dwDataLength) return 2; int len = *p * 256 * 256 + p[1] * 256 + p[2]; p += 3; if (static_cast<DWORD>(p - pData + len) > dwDataLength) return FALSE; m_OptionsCache[i].nType = 0; char* tmp = new char[len + 1]; memcpy(tmp, p, len); tmp[len] = 0; m_OptionsCache[i].str = ConvFromNetwork(tmp); p += len; delete[] tmp; } else if (nType == 1) { if (static_cast<DWORD>(p - pData + 8) > dwDataLength) return FALSE; m_OptionsCache[i].nType = 1; memcpy(&m_OptionsCache[i].value, p, 8); p += 8; } else return FALSE; } if ((endMarker - p) < 2) return FALSE; num = *p * 256 + p[1]; p += 2; for (int i = 0; i < num; ++i) { CSpeedLimit limit; p = limit.ParseBuffer(p, dwDataLength - (p - pData)); if (!p) return FALSE; m_pOptionsSpeedLimitPage->m_DownloadSpeedLimits.push_back(limit); } if ((endMarker - p) < 2) return FALSE; num = *p * 256 + p[1]; p += 2; for (int i = 0; i < num; ++i) { CSpeedLimit limit; p = limit.ParseBuffer(p, dwDataLength - (p - pData)); if (!p) return FALSE; m_pOptionsSpeedLimitPage->m_UploadSpeedLimits.push_back(limit); } return TRUE; }