bool ShaderProgramLoader::load(type& res, const std::string& name, const context_type* context) { UberShader::IdType id = context->ubershader_pool.create(); UberShader& ubershader = context->ubershader_pool.get(id); size_t defs_pos = name.find_first_of('&'); const std::string& defs = defs_pos == std::string::npos ? std::string() : name.substr(defs_pos + 1, name.size() - defs_pos); const std::vector<std::string>& definitions = utils::split(defs, ","); const std::string& actual_filename = defs_pos == std::string::npos ? name : name.substr(0, defs_pos); std::string filename_with_extension = actual_filename + detail::shader_extension; std::ifstream f(filename_with_extension.c_str()); if (!f.is_open()) { WARN_LOG("Can't open file:" << filename_with_extension); return false; } const std::vector<std::string>& file_content = utils::read_lines(f); f.close(); std::vector<UberShader::Info> infos; detail::parse_defs(infos, file_content); size_t total = 1; if (!infos.empty()) { const UberShader::Info& last = infos.back(); total = last.offset * (last.high - last.low + 1); } bool result = false; for (size_t i = 0; i < total; ++i) { ShaderProgram::IdType shader_id = context->shader_pool.create(); ShaderProgram& shader_program = context->shader_pool.get(shader_id); std::vector<std::string> data; data.reserve(1024); for (size_t j = 0; j < definitions.size(); ++j) data.push_back(std::string("#define ") + definitions[j]); std::string debug_defs; for (size_t j = 0; j < infos.size(); ++j) { size_t value = infos[j].low + (i / infos[j].offset) % (infos[j].high - infos[j].low + 1); std::string def = "#define " + infos[j].name + " " + types_cast<std::string>(value); debug_defs += def; debug_defs += " "; data.push_back(def); } data.insert(data.end(), file_content.begin(), file_content.end()); ShaderInitializationParams params; detail::LoadContext load_context; load_context.filename = filename_with_extension; load_context.level = 0; load_context.tag_found = false; params.csdata = detail::load_shader_impl(params, data, detail::compute_shader_tag, load_context); if (params.csdata.empty()) { load_context.tag_found = false; params.vsdata = detail::load_shader_impl(params, data, detail::vertex_shader_tag, load_context); load_context.tag_found = false; params.fsdata = detail::load_shader_impl(params, data, detail::fragment_shader_tag, load_context); load_context.tag_found = false; params.gsdata = detail::load_shader_impl(params, data, detail::geometry_shader_tag, load_context); } // TODO: parse GLSL errors to find the correct line with error const std::vector<std::string>& vs_tmp = utils::split(params.vsdata, "\n", true); const std::vector<std::string>& fs_tmp = utils::split(params.fsdata, "\n", true); const std::vector<std::string>& cs_tmp = utils::split(params.csdata, "\n", true); const std::vector<std::string>& gs_tmp = utils::split(params.gsdata, "\n", true); UNUSED(vs_tmp); UNUSED(fs_tmp); UNUSED(cs_tmp); UNUSED(gs_tmp); detail::update_shader_data(params, context); result = shader_program.init(params); if (!result) { ASSERT(0, "Shader compilation failed: " << name << "\n" << debug_defs); continue; } ubershader.add(i, shader_id); } if (!result) return false; ubershader.set_infos(infos); res.shader_program_handle = ubershader.id(); return true; }
int ThreadManForKernel_ceadeb47(u32 usec) { WARN_LOG(SCEKERNEL,"ThreadManForKernel_ceadeb47:Not support this patcher"); return sceKernelDelayThread(usec); }
int PSPSaveDialog::Init(int paramAddr) { // Ignore if already running if (GetStatus() != SCE_UTILITY_STATUS_NONE) { ERROR_LOG_REPORT(SCEUTILITY, "A save request is already running, not starting a new one"); return SCE_ERROR_UTILITY_INVALID_STATUS; } requestAddr = paramAddr; int size = Memory::Read_U32(requestAddr); memset(&request, 0, sizeof(request)); // Only copy the right size to support different save request format if (size != SAVEDATA_DIALOG_SIZE_V1 && size != SAVEDATA_DIALOG_SIZE_V2 && size != SAVEDATA_DIALOG_SIZE_V3) { ERROR_LOG_REPORT(SCEUTILITY, "sceUtilitySavedataInitStart: invalid size %d", size); return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE; } Memory::Memcpy(&request, requestAddr, size); Memory::Memcpy(&originalRequest, requestAddr, size); int retval = param.SetPspParam(&request); const u32 mode = (u32)param.GetPspParam()->mode; const char *modeName = mode < ARRAY_SIZE(utilitySavedataTypeNames) ? utilitySavedataTypeNames[mode] : "UNKNOWN"; INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) - %s (%d)", paramAddr, modeName, mode); INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) : Game key (hex): %s", paramAddr, param.GetKey(param.GetPspParam()).c_str()); yesnoChoice = 1; switch ((SceUtilitySavedataFocus)(u32)param.GetPspParam()->focus) { case SCE_UTILITY_SAVEDATA_FOCUS_NAME: currentSelectedSave = param.GetSaveNameIndex(param.GetPspParam()); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST: currentSelectedSave = param.GetFirstListSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST: currentSelectedSave = param.GetLastListSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LATEST: currentSelectedSave = param.GetLatestSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_OLDEST: currentSelectedSave = param.GetOldestSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA: currentSelectedSave = param.GetFirstDataSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA: currentSelectedSave = param.GetLastDataSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY: currentSelectedSave = param.GetFirstEmptySave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY: currentSelectedSave = param.GetLastEmptySave(); break; default: WARN_LOG(SCEUTILITY, "Unknown save list focus option: %d", param.GetPspParam()->focus); currentSelectedSave = 0; break; } switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if (param.GetFileInfo(0).size != 0) display = DS_LOAD_CONFIRM; else display = DS_LOAD_NODATA; break; case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_NONE; // Is this necessary? // currentSelectedSave = param.GetSelectedSave(); break; case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_LOAD_NODATA; else display = DS_LOAD_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_SAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if (param.GetFileInfo(0).size != 0) { yesnoChoice = 0; display = DS_SAVE_CONFIRM_OVERWRITE; } else display = DS_SAVE_CONFIRM; break; case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_NONE; // Is this necessary? // currentSelectedSave = param.GetSelectedSave(); break; case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_SAVE_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; else display = DS_DELETE_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_SIZES: case SCE_UTILITY_SAVEDATA_TYPE_LIST: case SCE_UTILITY_SAVEDATA_TYPE_FILES: case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE: case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: display = DS_NONE; break; case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space) display = DS_DELETE_LIST_CHOICE; break; default: { ERROR_LOG_REPORT(SCEUTILITY, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)(u32)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); param.GetPspParam()->common.result = 0; ChangeStatusInit(SAVEDATA_INIT_DELAY_US); display = DS_NONE; return 0; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block. } break; } if (retval < 0) { ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US); } else { ChangeStatusInit(SAVEDATA_INIT_DELAY_US); } UpdateButtons(); StartFade(true); /*INFO_LOG(SCEUTILITY,"Dump Param :"); INFO_LOG(SCEUTILITY,"size : %d",param.GetPspParam()->size); INFO_LOG(SCEUTILITY,"language : %d",param.GetPspParam()->language); INFO_LOG(SCEUTILITY,"buttonSwap : %d",param.GetPspParam()->buttonSwap); INFO_LOG(SCEUTILITY,"result : %d",param.GetPspParam()->common.result); INFO_LOG(SCEUTILITY,"mode : %d",param.GetPspParam()->mode); INFO_LOG(SCEUTILITY,"bind : %d",param.GetPspParam()->bind); INFO_LOG(SCEUTILITY,"overwriteMode : %d",param.GetPspParam()->overwriteMode); INFO_LOG(SCEUTILITY,"gameName : %s",param.GetGameName(param.GetPspParam()).c_str()); INFO_LOG(SCEUTILITY,"saveName : %s",param.GetPspParam()->saveName); INFO_LOG(SCEUTILITY,"saveNameList : %08x",*((unsigned int*)¶m.GetPspParam()->saveNameList)); INFO_LOG(SCEUTILITY,"fileName : %s",param.GetPspParam()->fileName); INFO_LOG(SCEUTILITY,"dataBuf : %08x",*((unsigned int*)¶m.GetPspParam()->dataBuf)); INFO_LOG(SCEUTILITY,"dataBufSize : %u",param.GetPspParam()->dataBufSize); INFO_LOG(SCEUTILITY,"dataSize : %u",param.GetPspParam()->dataSize); INFO_LOG(SCEUTILITY,"sfo title : %s",param.GetPspParam()->sfoParam.title); INFO_LOG(SCEUTILITY,"sfo savedataTitle : %s",param.GetPspParam()->sfoParam.savedataTitle); INFO_LOG(SCEUTILITY,"sfo detail : %s",param.GetPspParam()->sfoParam.detail); INFO_LOG(SCEUTILITY,"icon0 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon0FileData.buf)); INFO_LOG(SCEUTILITY,"icon0 size : %u",param.GetPspParam()->icon0FileData.bufSize); INFO_LOG(SCEUTILITY,"icon1 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon1FileData.buf)); INFO_LOG(SCEUTILITY,"icon1 size : %u",param.GetPspParam()->icon1FileData.bufSize); INFO_LOG(SCEUTILITY,"pic1 data : %08x",*((unsigned int*)¶m.GetPspParam()->pic1FileData.buf)); INFO_LOG(SCEUTILITY,"pic1 size : %u",param.GetPspParam()->pic1FileData.bufSize); INFO_LOG(SCEUTILITY,"snd0 data : %08x",*((unsigned int*)¶m.GetPspParam()->snd0FileData.buf)); INFO_LOG(SCEUTILITY,"snd0 size : %u",param.GetPspParam()->snd0FileData.bufSize);*/ return retval; }
int Interpreter::SingleStepInner(void) { static UGeckoInstruction instCode; u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches if (function != 0) { int type = HLE::GetFunctionTypeByIndex(function); if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) { int flags = HLE::GetFunctionFlagsByIndex(function); if (HLE::IsEnabled(flags)) { HLEFunction(function); if (type == HLE::HLE_HOOK_START) { // Run the original. function = 0; } } else { function = 0; } } } if (function == 0) { #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); instCode.hex = Memory::Read_Opcode(PC); // Uncomment to trace the interpreter //if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; //else // startTrace = 0; if (startTrace) { Trace(instCode); } if (instCode.hex != 0) { UReg_MSR& msr = (UReg_MSR&)MSR; if (msr.FP) //If FPU is enabled, just execute { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { // check if we have to generate a FPU unavailable exception if (!PPCTables::UsesFPU(instCode)) { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { PowerPC::CheckExceptions(); m_EndBlock = true; } } else { Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); PowerPC::CheckExceptions(); m_EndBlock = true; } } } else { // Memory exception on instruction fetch PowerPC::CheckExceptions(); m_EndBlock = true; } } last_pc = PC; PC = NPC; #if defined(_DEBUG) || defined(DEBUGFAST) if (PowerPC::ppcState.gpr[1] == 0) { WARN_LOG(POWERPC, "%i Corrupt stack", PowerPC::ppcState.DebugCount); } PowerPC::ppcState.DebugCount++; #endif patches(); GekkoOPInfo *opinfo = GetOpInfo(instCode); return opinfo->numCycles; }
int ThreadManForKernel_446d8de6(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) { WARN_LOG(SCEKERNEL,"ThreadManForKernel_446d8de6:Not support this patcher"); return sceKernelCreateThread(threadName, entry, prio, stacksize, attr, optionAddr); }
IPCCommandResult NetIPTop::IOCtl(const IOCtlRequest& request) { if (Core::g_want_determinism) { return GetDefaultReply(IPC_EACCES); } s32 return_value = 0; switch (request.request) { case IOCTL_SO_STARTUP: { request.Log(GetDeviceName(), LogTypes::IOS_WC24); break; } case IOCTL_SO_SOCKET: { u32 af = Memory::Read_U32(request.buffer_in); u32 type = Memory::Read_U32(request.buffer_in + 4); u32 prot = Memory::Read_U32(request.buffer_in + 8); WiiSockMan& sm = WiiSockMan::GetInstance(); return_value = sm.NewSocket(af, type, prot); INFO_LOG(IOS_NET, "IOCTL_SO_SOCKET " "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)", return_value, af, type, prot, request.buffer_in, request.buffer_in_size, request.buffer_out, request.buffer_out_size); break; } case IOCTL_SO_ICMPSOCKET: { u32 pf = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); return_value = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP); INFO_LOG(IOS_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, return_value); break; } case IOCTL_SO_CLOSE: case IOCTL_SO_ICMPCLOSE: { u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); return_value = sm.DeleteSocket(fd); INFO_LOG(IOS_NET, "%s(%x) %x", request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd, return_value); break; } case IOCTL_SO_ACCEPT: case IOCTL_SO_BIND: case IOCTL_SO_CONNECT: case IOCTL_SO_FCNTL: { u32 fd = Memory::Read_U32(request.buffer_in); WiiSockMan& sm = WiiSockMan::GetInstance(); sm.DoSock(fd, request, static_cast<NET_IOCTL>(request.request)); return GetNoReply(); } ///////////////////////////////////////////////////////////// // TODO: Tidy all below // ///////////////////////////////////////////////////////////// case IOCTL_SO_SHUTDOWN: { request.Log(GetDeviceName(), LogTypes::IOS_WC24); u32 fd = Memory::Read_U32(request.buffer_in); u32 how = Memory::Read_U32(request.buffer_in + 4); int ret = shutdown(fd, how); return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false); break; } case IOCTL_SO_LISTEN: { u32 fd = Memory::Read_U32(request.buffer_in); u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04); u32 ret = listen(fd, BACKLOG); return_value = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false); request.Log(GetDeviceName(), LogTypes::IOS_WC24); break; } case IOCTL_SO_GETSOCKOPT: { u32 fd = Memory::Read_U32(request.buffer_out); u32 level = Memory::Read_U32(request.buffer_out + 4); u32 optname = Memory::Read_U32(request.buffer_out + 8); request.Log(GetDeviceName(), LogTypes::IOS_WC24); // Do the level/optname translation int nat_level = -1, nat_optname = -1; for (auto& map : opt_level_mapping) if (level == map[1]) nat_level = map[0]; for (auto& map : opt_name_mapping) if (optname == map[1]) nat_optname = map[0]; u8 optval[20]; u32 optlen = 4; int ret = getsockopt(fd, nat_level, nat_optname, (char*)&optval, (socklen_t*)&optlen); return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); Memory::Write_U32(optlen, request.buffer_out + 0xC); Memory::CopyToEmu(request.buffer_out + 0x10, optval, optlen); if (optname == SO_ERROR) { s32 last_error = WiiSockMan::GetInstance().GetLastNetError(); Memory::Write_U32(sizeof(s32), request.buffer_out + 0xC); Memory::Write_U32(last_error, request.buffer_out + 0x10); } break; } case IOCTL_SO_SETSOCKOPT: { u32 fd = Memory::Read_U32(request.buffer_in); u32 level = Memory::Read_U32(request.buffer_in + 4); u32 optname = Memory::Read_U32(request.buffer_in + 8); u32 optlen = Memory::Read_U32(request.buffer_in + 0xc); u8 optval[20]; optlen = std::min(optlen, (u32)sizeof(optval)); Memory::CopyFromEmu(optval, request.buffer_in + 0x10, optlen); INFO_LOG(IOS_NET, "IOCTL_SO_SETSOCKOPT(%08x, %08x, %08x, %08x) " "BufferIn: (%08x, %i), BufferOut: (%08x, %i)" "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx", fd, level, optname, optlen, request.buffer_in, request.buffer_in_size, request.buffer_out, request.buffer_out_size, optval[0], optval[1], optval[2], optval[3], optval[4], optval[5], optval[6], optval[7], optval[8], optval[9], optval[10], optval[11], optval[12], optval[13], optval[14], optval[15], optval[16], optval[17], optval[18], optval[19]); // TODO: bug booto about this, 0x2005 most likely timeout related, default value on Wii is , // 0x2001 is most likely tcpnodelay if (level == 6 && (optname == 0x2005 || optname == 0x2001)) { return_value = 0; break; } // Do the level/optname translation int nat_level = -1, nat_optname = -1; for (auto& map : opt_level_mapping) if (level == map[1]) nat_level = map[0]; for (auto& map : opt_name_mapping) if (optname == map[1]) nat_optname = map[0]; if (nat_level == -1 || nat_optname == -1) { INFO_LOG(IOS_NET, "SO_SETSOCKOPT: unknown level %d or optname %d", level, optname); // Default to the given level/optname. They match on Windows... nat_level = level; nat_optname = optname; } int ret = setsockopt(fd, nat_level, nat_optname, (char*)optval, optlen); return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false); break; } case IOCTL_SO_GETSOCKNAME: { u32 fd = Memory::Read_U32(request.buffer_in); request.Log(GetDeviceName(), LogTypes::IOS_WC24); sockaddr sa; socklen_t sa_len; sa_len = sizeof(sa); int ret = getsockname(fd, &sa, &sa_len); if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating"); if (request.buffer_out_size > 0) Memory::Write_U8(request.buffer_out_size, request.buffer_out); if (request.buffer_out_size > 1) Memory::Write_U8(sa.sa_family & 0xFF, request.buffer_out + 1); if (request.buffer_out_size > 2) Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, std::min<size_t>(sizeof(sa.sa_data), request.buffer_out_size - 2)); return_value = ret; break; } case IOCTL_SO_GETPEERNAME: { u32 fd = Memory::Read_U32(request.buffer_in); sockaddr sa; socklen_t sa_len; sa_len = sizeof(sa); int ret = getpeername(fd, &sa, &sa_len); if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating"); if (request.buffer_out_size > 0) Memory::Write_U8(request.buffer_out_size, request.buffer_out); if (request.buffer_out_size > 1) Memory::Write_U8(AF_INET, request.buffer_out + 1); if (request.buffer_out_size > 2) Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data, std::min<size_t>(sizeof(sa.sa_data), request.buffer_out_size - 2)); INFO_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME(%x)", fd); return_value = ret; break; } case IOCTL_SO_GETHOSTID: { request.Log(GetDeviceName(), LogTypes::IOS_WC24); #ifdef _WIN32 DWORD forwardTableSize, ipTableSize, result; DWORD ifIndex = -1; std::unique_ptr<MIB_IPFORWARDTABLE> forwardTable; std::unique_ptr<MIB_IPADDRTABLE> ipTable; forwardTableSize = 0; if (GetIpForwardTable(nullptr, &forwardTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { forwardTable = std::unique_ptr<MIB_IPFORWARDTABLE>((PMIB_IPFORWARDTABLE) operator new(forwardTableSize)); } ipTableSize = 0; if (GetIpAddrTable(nullptr, &ipTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { ipTable = std::unique_ptr<MIB_IPADDRTABLE>((PMIB_IPADDRTABLE) operator new(ipTableSize)); } // find the interface IP used for the default route and use that 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) { if (forwardTable->table[i].dwForwardDest == 0) { ifIndex = forwardTable->table[i].dwForwardIfIndex; 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) { return_value = Common::swap32(ipTable->table[i].dwAddr); break; } } } #endif // default placeholder, in case of failure if (return_value == 0) return_value = 192 << 24 | 168 << 16 | 1 << 8 | 150; break; } case IOCTL_SO_INETATON: { std::string hostname = Memory::GetString(request.buffer_in); struct hostent* remoteHost = gethostbyname(hostname.c_str()); if (remoteHost == nullptr || remoteHost->h_addr_list == nullptr || remoteHost->h_addr_list[0] == nullptr) { INFO_LOG(IOS_NET, "IOCTL_SO_INETATON = -1 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: None", hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, request.buffer_out_size); return_value = 0; } else { Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), request.buffer_out); INFO_LOG(IOS_NET, "IOCTL_SO_INETATON = 0 " "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X", hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, request.buffer_out_size, Common::swap32(*(u32*)remoteHost->h_addr_list[0])); return_value = 1; } break; } case IOCTL_SO_INETPTON: { std::string address = Memory::GetString(request.buffer_in); INFO_LOG(IOS_NET, "IOCTL_SO_INETPTON " "(Translating: %s)", address.c_str()); return_value = inet_pton(address.c_str(), Memory::GetPointer(request.buffer_out + 4)); break; } case IOCTL_SO_INETNTOP: { // u32 af = Memory::Read_U32(BufferIn); // u32 validAddress = Memory::Read_U32(request.buffer_in + 4); // u32 src = Memory::Read_U32(request.buffer_in + 8); char ip_s[16]; sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(request.buffer_in + 8), Memory::Read_U8(request.buffer_in + 8 + 1), Memory::Read_U8(request.buffer_in + 8 + 2), Memory::Read_U8(request.buffer_in + 8 + 3)); INFO_LOG(IOS_NET, "IOCTL_SO_INETNTOP %s", ip_s); Memory::CopyToEmu(request.buffer_out, (u8*)ip_s, strlen(ip_s)); break; } case IOCTL_SO_POLL: { // Map Wii/native poll events types struct { int native; int wii; } mapping[] = { {POLLRDNORM, 0x0001}, {POLLRDBAND, 0x0002}, {POLLPRI, 0x0004}, {POLLWRNORM, 0x0008}, {POLLWRBAND, 0x0010}, {POLLERR, 0x0020}, {POLLHUP, 0x0040}, {POLLNVAL, 0x0080}, }; u32 unknown = Memory::Read_U32(request.buffer_in); u32 timeout = Memory::Read_U32(request.buffer_in + 4); int nfds = request.buffer_out_size / 0xc; if (nfds == 0) ERROR_LOG(IOS_NET, "Hidden POLL"); std::vector<pollfd_t> ufds(nfds); for (int i = 0; i < nfds; ++i) { ufds[i].fd = Memory::Read_U32(request.buffer_out + 0xc * i); // fd int events = Memory::Read_U32(request.buffer_out + 0xc * i + 4); // events ufds[i].revents = Memory::Read_U32(request.buffer_out + 0xc * i + 8); // revents // Translate Wii to native events int unhandled_events = events; ufds[i].events = 0; for (auto& map : mapping) { if (events & map.wii) ufds[i].events |= map.native; unhandled_events &= ~map.wii; } DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL(%d) " "Sock: %08x, Unknown: %08x, Events: %08x, " "NativeEvents: %08x", i, ufds[i].fd, unknown, events, ufds[i].events); // Do not pass return-only events to the native poll ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL | UNSUPPORTED_WSAPOLL); if (unhandled_events) ERROR_LOG(IOS_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events); } int ret = poll(ufds.data(), nfds, timeout); ret = WiiSockMan::GetNetErrorCode(ret, "SO_POLL", false); for (int i = 0; i < nfds; ++i) { // Translate native to Wii events int revents = 0; for (auto& map : mapping) { if (ufds[i].revents & map.native) revents |= map.wii; } // No need to change fd or events as they are input only. // Memory::Write_U32(ufds[i].fd, request.buffer_out + 0xc*i); //fd // Memory::Write_U32(events, request.buffer_out + 0xc*i + 4); //events Memory::Write_U32(revents, request.buffer_out + 0xc * i + 8); // revents DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL socket %d wevents %08X events %08X revents %08X", i, revents, ufds[i].events, ufds[i].revents); } return_value = ret; break; } case IOCTL_SO_GETHOSTBYNAME: { if (request.buffer_out_size != 0x460) { ERROR_LOG(IOS_NET, "Bad buffer size for IOCTL_SO_GETHOSTBYNAME"); return_value = -1; break; } std::string hostname = Memory::GetString(request.buffer_in); hostent* remoteHost = gethostbyname(hostname.c_str()); INFO_LOG(IOS_NET, "IOCTL_SO_GETHOSTBYNAME " "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)", hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out, request.buffer_out_size); if (remoteHost) { for (int i = 0; remoteHost->h_aliases[i]; ++i) { DEBUG_LOG(IOS_NET, "alias%i:%s", i, remoteHost->h_aliases[i]); } for (int i = 0; remoteHost->h_addr_list[i]; ++i) { u32 ip = Common::swap32(*(u32*)(remoteHost->h_addr_list[i])); std::string ip_s = StringFromFormat("%i.%i.%i.%i", ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); DEBUG_LOG(IOS_NET, "addr%i:%s", i, ip_s.c_str()); } // Host name; located immediately after struct static const u32 GETHOSTBYNAME_STRUCT_SIZE = 0x10; static const u32 GETHOSTBYNAME_IP_LIST_OFFSET = 0x110; // Limit host name length to avoid buffer overflow. u32 name_length = (u32)strlen(remoteHost->h_name) + 1; if (name_length > (GETHOSTBYNAME_IP_LIST_OFFSET - GETHOSTBYNAME_STRUCT_SIZE)) { ERROR_LOG(IOS_NET, "Hostname too long in IOCTL_SO_GETHOSTBYNAME"); return_value = -1; break; } Memory::CopyToEmu(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name, name_length); Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, request.buffer_out); // IP address list; located at offset 0x110. u32 num_ip_addr = 0; while (remoteHost->h_addr_list[num_ip_addr]) num_ip_addr++; // Limit number of IP addresses to avoid buffer overflow. // (0x460 - 0x340) / sizeof(pointer) == 72 static const u32 GETHOSTBYNAME_MAX_ADDRESSES = 71; num_ip_addr = std::min(num_ip_addr, GETHOSTBYNAME_MAX_ADDRESSES); for (u32 i = 0; i < num_ip_addr; ++i) { u32 addr = request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4; Memory::Write_U32_Swap(*(u32*)(remoteHost->h_addr_list[i]), addr); } // List of pointers to IP addresses; located at offset 0x340. // This must be exact: PPC code to convert the struct hardcodes // this offset. static const u32 GETHOSTBYNAME_IP_PTR_LIST_OFFSET = 0x340; Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET, request.buffer_out + 12); for (u32 i = 0; i < num_ip_addr; ++i) { u32 addr = request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4; Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr); } Memory::Write_U32(0, request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4); // Aliases - empty. (Hardware doesn't return anything.) Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4, request.buffer_out + 4); // Returned struct must be ipv4. _assert_msg_(IOS_NET, remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32), "returned host info is not IPv4"); Memory::Write_U16(AF_INET, request.buffer_out + 8); Memory::Write_U16(sizeof(u32), request.buffer_out + 10); return_value = 0; } else { return_value = -1; } break; } case IOCTL_SO_ICMPCANCEL: ERROR_LOG(IOS_NET, "IOCTL_SO_ICMPCANCEL"); default: request.DumpUnknown(GetDeviceName(), LogTypes::IOS_NET); }
// The front SD slot IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) { u32 Cmd = Memory::Read_U32(_CommandAddress + 0xC); u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); // As a safety precaution we fill the out buffer with zeros to avoid // returning nonsense values Memory::Memset(BufferOut, 0, BufferOutSize); u32 ReturnValue = 0; switch (Cmd) { case IOCTL_WRITEHCR: { u32 reg = Memory::Read_U32(BufferIn); u32 val = Memory::Read_U32(BufferIn + 16); INFO_LOG(WII_IPC_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val); if (reg >= 0x200) { WARN_LOG(WII_IPC_SD, "IOCTL_WRITEHCR out of range"); break; } if ((reg == HCR_CLOCKCONTROL) && (val & 1)) { // Clock is set to oscillate, enable bit 1 to say it's stable m_Registers[reg] = val | 2; } else if ((reg == HCR_SOFTWARERESET) && val) { // When a reset is specified, the register gets cleared m_Registers[reg] = 0; } else { // Default to just storing the new value m_Registers[reg] = val; } } break; case IOCTL_READHCR: { u32 reg = Memory::Read_U32(BufferIn); if (reg >= 0x200) { WARN_LOG(WII_IPC_SD, "IOCTL_READHCR out of range"); break; } u32 val = m_Registers[reg]; INFO_LOG(WII_IPC_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val); // Just reading the register Memory::Write_U32(val, BufferOut); } break; case IOCTL_RESETCARD: INFO_LOG(WII_IPC_SD, "IOCTL_RESETCARD"); if (m_Card) m_Status |= CARD_INITIALIZED; // Returns 16bit RCA and 16bit 0s (meaning success) Memory::Write_U32(0x9f620000, BufferOut); break; case IOCTL_SETCLK: { INFO_LOG(WII_IPC_SD, "IOCTL_SETCLK"); // libogc only sets it to 1 and makes sure the return isn't negative... // one half of the sdclk divisor: a power of two or zero. u32 clock = Memory::Read_U32(BufferIn); if (clock != 1) INFO_LOG(WII_IPC_SD, "Setting to %i, interesting", clock); } break; case IOCTL_SENDCMD: INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(BufferIn), _CommandAddress); ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize); break; case IOCTL_GETSTATUS: if (SConfig::GetInstance().m_WiiSDCard) m_Status |= CARD_INSERTED; else m_Status = CARD_NOT_EXIST; INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s", (m_Status & CARD_INSERTED) ? "inserted" : "not present", (m_Status & CARD_INITIALIZED) ? " and initialized" : ""); Memory::Write_U32(m_Status, BufferOut); break; case IOCTL_GETOCR: INFO_LOG(WII_IPC_SD, "IOCTL_GETOCR"); Memory::Write_U32(0x80ff8000, BufferOut); break; default: ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", Cmd); break; } // INFO_LOG(WII_IPC_SD, "InBuffer"); // DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD); // INFO_LOG(WII_IPC_SD, "OutBuffer"); // DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD); if (ReturnValue == RET_EVENT_REGISTER) { // async m_event.addr = _CommandAddress; Memory::Write_U32(0, _CommandAddress + 0x4); // Check if the condition is already true EventNotify(); return GetNoReply(); } else if (ReturnValue == RET_EVENT_UNREGISTER) { // release returns 0 // unknown sd int // technically we do it out of order, oh well EnqueueReply(m_event.addr, EVENT_INVALID); m_event.addr = 0; m_event.type = EVENT_NONE; Memory::Write_U32(0, _CommandAddress + 0x4); return GetDefaultReply(); } else { Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); return GetDefaultReply(); } }
void CWII_IPC_HLE_Device_usb_oh0_57e_308::SetRegister(const u32 cmd_ptr) { WARN_LOG(OSHLE, "cmd -> %s", ArrayToString(Memory::GetPointer(cmd_ptr), 10, 16).c_str()); const u8 reg = Memory::Read_U8(cmd_ptr + 1) & ~1; const u16 arg1 = Memory::Read_U16(cmd_ptr + 2); const u16 arg2 = Memory::Read_U16(cmd_ptr + 4); //u16 arg3 = Memory::Read_U16(cmd_ptr + 6); //u16 count = Memory::Read_U16(cmd_ptr + 8); _dbg_assert_(OSHLE, Memory::Read_U8(cmd_ptr) == 0x9a); _dbg_assert_(OSHLE, (Memory::Read_U8(cmd_ptr + 1) & 1) == 0); switch (reg) { case SAMPLER_STATE: sampler.sample_on = !!arg1; break; case SAMPLER_FREQ: switch (arg1) { case FREQ_8KHZ: sampler.freq = 8000; break; case FREQ_11KHZ: sampler.freq = 11025; break; case FREQ_RESERVED: case FREQ_16KHZ: default: sampler.freq = 16000; break; } break; case SAMPLER_GAIN: switch (arg1 & ~0x300) { case GAIN_00dB: sampler.gain = 0; break; case GAIN_15dB: sampler.gain = 15; break; case GAIN_30dB: sampler.gain = 30; break; case GAIN_36dB: default: sampler.gain = 36; break; } break; case EC_STATE: sampler.ec_reset = !!arg1; break; case SP_STATE: switch (arg1) { case SP_ENABLE: sampler.sp_on = arg2 == 0; break; case SP_SIN: break; case SP_SOUT: break; case SP_RIN: break; } break; case SAMPLER_MUTE: sampler.mute = !!arg1; break; } }
void CWII_IPC_HLE_Device_usb_oh0_57e_308::GetRegister(const u32 cmd_ptr) const { const u8 reg = Memory::Read_U8(cmd_ptr + 1) & ~1; const u32 arg1 = cmd_ptr + 2; const u32 arg2 = cmd_ptr + 4; _dbg_assert_(OSHLE, Memory::Read_U8(cmd_ptr) == 0x9a); _dbg_assert_(OSHLE, (Memory::Read_U8(cmd_ptr + 1) & 1) == 1); switch (reg) { case SAMPLER_STATE: Memory::Write_U16(sampler.sample_on ? 1 : 0, arg1); break; case SAMPLER_FREQ: switch (sampler.freq) { case 8000: Memory::Write_U16(FREQ_8KHZ, arg1); break; case 11025: Memory::Write_U16(FREQ_11KHZ, arg1); break; case 16000: default: Memory::Write_U16(FREQ_16KHZ, arg1); break; } break; case SAMPLER_GAIN: switch (sampler.gain) { case 0: Memory::Write_U16(0x300 | GAIN_00dB, arg1); break; case 15: Memory::Write_U16(0x300 | GAIN_15dB, arg1); break; case 30: Memory::Write_U16(0x300 | GAIN_30dB, arg1); break; case 36: default: Memory::Write_U16(0x300 | GAIN_36dB, arg1); break; } break; case EC_STATE: Memory::Write_U16(sampler.ec_reset ? 1 : 0, arg1); break; case SP_STATE: switch (Memory::Read_U16(arg1)) { case SP_ENABLE: Memory::Write_U16(sampler.sp_on ? 0 : 1, arg2); break; case SP_SIN: break; case SP_SOUT: Memory::Write_U16(0x39B0, arg2); // 6dB TODO actually calc? break; case SP_RIN: break; } break; case SAMPLER_MUTE: Memory::Write_U16(sampler.mute ? 1 : 0, arg1); break; } WARN_LOG(OSHLE, "cmd <- %s", ArrayToString(Memory::GetPointer(cmd_ptr), 10, 16).c_str()); }
IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 CommandAddress) { IPCCommandResult SendReply = GetNoReply(); u32 Command = Memory::Read_U32(CommandAddress + 0x0c); u32 BufferIn = Memory::Read_U32(CommandAddress + 0x10); u32 BufferInSize = Memory::Read_U32(CommandAddress + 0x14); u32 BufferOut = Memory::Read_U32(CommandAddress + 0x18); u32 BufferOutSize = Memory::Read_U32(CommandAddress + 0x1c); WARN_LOG(OSHLE, "%s - IOCtl:%x", GetDeviceName().c_str(), Command); WARN_LOG(OSHLE, "%x:%x %x:%x", BufferIn, BufferInSize, BufferOut, BufferOutSize); switch (Command) { case USBV5_IOCTL_GETVERSION: Memory::Write_U32(0x50001, BufferOut); SendReply = GetDefaultReply(); break; case USBV5_IOCTL_GETDEVICECHANGE: { // fd Memory::Write_U32(0xcd000030, BufferOut); // vid, pid Memory::Write_U32(0x046d0a03, BufferOut + 4); // token //Memory::Write_U32(0, BufferOut + 8); // sent on change static bool firstcall = true; if (firstcall) SendReply = GetDefaultReply(), firstcall = false; // num devices Memory::Write_U32(1, CommandAddress + 4); return SendReply; } break; case USBV5_IOCTL_ATTACHFINISH: SendReply = GetDefaultReply(); break; case USBV5_IOCTL_SUSPEND_RESUME: WARN_LOG(OSHLE, "device:%i resumed:%i", Memory::Read_U32(BufferIn), Memory::Read_U32(BufferIn + 4)); SendReply = GetDefaultReply(); break; case USBV5_IOCTL_GETDEVPARAMS: { s32 device = Memory::Read_U32(BufferIn); u32 unk = Memory::Read_U32(BufferIn + 4); WARN_LOG(OSHLE, "USBV5_IOCTL_GETDEVPARAMS device:%i unk:%i", device, unk); Memory::Write_U32(0, BufferOut); SendReply = GetDefaultReply(); } break; default: //WARN_LOG(OSHLE, "%x:%x %x:%x", BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } Memory::Write_U32(0, CommandAddress + 4); return SendReply; }
IPCCommandResult CWII_IPC_HLE_Device_usb_oh0_57e_308::IOCtlV(u32 CommandAddress) { IPCCommandResult SendReply = GetNoReply(); SIOCtlVBuffer CommandBuffer(CommandAddress); switch (CommandBuffer.Parameter) { case USBV0_IOCTL_CTRLMSG: { USBSetupPacket setup_packet; setup_packet.bmRequestType = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); setup_packet.bRequest = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address); setup_packet.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address); setup_packet.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address); setup_packet.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address); const u32 payload_addr = CommandBuffer.PayloadBuffer[0].m_Address; static bool initialized = false; #define DIR_TO_DEV 0 #define DIR_TO_HOST 1 #define TYPE_STANDARD 0 #define TYPE_VENDOR 2 #define RECP_DEV 0 #define RECP_INT 1 #define RECP_ENDP 2 #define USBHDR(dir, type, recipient, request) \ ((((dir << 7) | (type << 5) | recipient) << 8) | request) switch (((u16)setup_packet.bmRequestType << 8) | setup_packet.bRequest) { case USBHDR(DIR_TO_DEV, TYPE_STANDARD, RECP_INT, 11): _dbg_assert_(OSHLE, setup_packet.wValue == 1); break; case USBHDR(DIR_TO_HOST, TYPE_STANDARD, RECP_INT, 10): Memory::Write_U8(1, payload_addr); break; case USBHDR(DIR_TO_HOST, TYPE_VENDOR, RECP_INT, 6): if (!initialized) Memory::Write_U8(0, payload_addr), initialized = true; else Memory::Write_U8(1, payload_addr); break; case USBHDR(DIR_TO_DEV, TYPE_VENDOR, RECP_INT, 1): SetRegister(payload_addr); break; case USBHDR(DIR_TO_HOST, TYPE_VENDOR, RECP_INT, 2): GetRegister(payload_addr); break; case USBHDR(DIR_TO_DEV, TYPE_VENDOR, RECP_INT, 0): initialized = false; break; default: WARN_LOG(OSHLE, "UNK %02x %02x %04x %04x", setup_packet.bmRequestType, setup_packet.bRequest, setup_packet.wValue, setup_packet.wLength); break; } // command finished, send a reply to command WII_IPC_HLE_Interface::EnqueueReply(CommandBuffer.m_Address); } break; case USBV0_IOCTL_BLKMSG: { u8 Command = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address); switch (Command) { // used for sending firmware case DATA_OUT: { u16 len = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address); WARN_LOG(OSHLE, "SEND DATA %x %x %x", len, CommandBuffer.PayloadBuffer[0].m_Address, CommandBuffer.PayloadBuffer[0].m_Size); SendReply = GetDefaultReply(); } break; default: WARN_LOG(OSHLE, "UNK BLKMSG %i", Command); break; } } break; case USBV0_IOCTL_ISOMSG: { // endp 81 = mic -> console // endp 03 = console -> mic u8 endpoint = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address); u16 length = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address); u8 num_packets = Memory::Read_U8(CommandBuffer.InBuffer[2].m_Address); u16 *packet_sizes = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address); u8 *packets = Memory::GetPointer(CommandBuffer.PayloadBuffer[1].m_Address); /* for (int i = 0; i < num_packets; i++) { u16 packet_len = Common::swap16(packet_sizes[i]); WARN_LOG(OSHLE, "packet %i [%i] to endpoint %02x", i, packet_len, endpoint); WARN_LOG(OSHLE, "%s", ArrayToString(packets, packet_len, 16).c_str()); packets += packet_len; } */ if (endpoint == AUDIO_IN) for (u16 *sample = (u16*)packets; sample != (u16*)(packets + length); sample++) *sample = 0x8000; // TODO actual responses should obey some kinda timey thing SendReply = GetDefaultReply(); } break; default: WARN_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str()); WARN_LOG(OSHLE, " Parameter: 0x%x", CommandBuffer.Parameter); WARN_LOG(OSHLE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); WARN_LOG(OSHLE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); WARN_LOG(OSHLE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); //DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer, LogTypes::OSHLE, LogTypes::LWARNING); break; } Memory::Write_U32(0, CommandAddress + 4); return SendReply; }
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written) { switch (stack) { case MSBT_STACK_UNKNOWN: { // Try to auto-detect the stack type stack = MSBT_STACK_BLUESOLEIL; if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written)) return 1; stack = MSBT_STACK_MS; if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written)) return 1; stack = MSBT_STACK_UNKNOWN; break; } case MSBT_STACK_MS: { auto result = pHidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, (ULONG)(len - 1)); //FlushFileBuffers(dev_handle); if (!result) { auto err = GetLastError(); if (err == 121) { // Semaphore timeout NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); } else if (err != 0x1F) // Some third-party adapters (DolphinBar) use this // error code to signal the absence of a Wiimote // linked to the HID device. { WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); } } if (written) *written = (result ? (DWORD)len : 0); return result; } case MSBT_STACK_BLUESOLEIL: { u8 big_buf[MAX_PAYLOAD]; if (len < MAX_PAYLOAD) { std::copy(buf, buf + len, big_buf); std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); buf = big_buf; } ResetEvent(hid_overlap_write.hEvent); DWORD bytes = 0; if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) { // If the number of written bytes is requested, block until we can provide // this information to the called. if (written) { auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT); if (WAIT_TIMEOUT == wait_result) { WARN_LOG(WIIMOTE, "_IOWrite: A timeout occurred on writing to Wiimote."); CancelIo(dev_handle); *written = 0; } else if (WAIT_FAILED == wait_result) { WARN_LOG(WIIMOTE, "_IOWrite: A wait error occurred on writing to Wiimote."); CancelIo(dev_handle); *written = 0; } else if (!GetOverlappedResult(dev_handle, &hid_overlap_write, written, TRUE)) *written = 0; } return 1; } else { auto const err = GetLastError(); if (ERROR_IO_PENDING == err) { CancelIo(dev_handle); } return 0; } } } return 0; }
int xio_validate_rdma_op(struct xio_vmsg *vmsg, struct xio_sge *rsg_list, size_t rsize, int op_size) { struct xio_iovec_ex *liov; uint64_t raddr; uint32_t rlen; uint64_t laddr; uint32_t llen; uint32_t tot_len = 0; size_t lsize; int l, r; if (rsize < 1) { ERROR_LOG("rsize:%zu\n", rsize); return -1; } if (vmsg->data_iovlen > XIO_MAX_IOV || vmsg->data_iovlen == 0) { WARN_LOG("IOV size %zu\n", vmsg->data_iovlen); return -EINVAL; } lsize = vmsg->data_iovlen; liov = vmsg->data_iov; r = 0; rlen = rsg_list[r].length; raddr = rsg_list[r].addr; l = 0; laddr = uint64_from_ptr(liov[l].iov_base); llen = liov[l].iov_len; while (1) { if (rlen < llen) { r++; tot_len += rlen; if (r == rsize) break; llen -= rlen; laddr += rlen; raddr = rsg_list[r].addr; rlen = rsg_list[r].length; } else if (llen < rlen) { /* check page alignment when source buff spans more * then one destination buffer */ l++; tot_len += llen; if (l == lsize) break; rlen -= llen; raddr += llen; laddr = uint64_from_ptr(liov[l].iov_base); llen = liov[l].iov_len; } else { l++; r++; tot_len += llen; if ((l == lsize) || (r == rsize)) break; laddr = uint64_from_ptr(liov[l].iov_base); llen = liov[l].iov_len; raddr = rsg_list[r].addr; rlen = rsg_list[r].length; } } /* not enough buffers to complete */ if (tot_len < op_size) { ERROR_LOG("iovec exausted\n"); return -1; } return 0; }
bool VideoBackend::Initialize(void* window_handle) { if (!LoadVulkanLibrary()) { PanicAlert("Failed to load Vulkan library."); return false; } // HACK: Use InitBackendInfo to initially populate backend features. // This is because things like stereo get disabled when the config is validated, // which happens before our device is created (settings control instance behavior), // and we don't want that to happen if the device actually supports it. InitBackendInfo(); InitializeShared(); // Check for presence of the debug layer before trying to enable it bool enable_validation_layer = g_Config.bEnableValidationLayer; if (enable_validation_layer && !VulkanContext::CheckValidationLayerAvailablility()) { WARN_LOG(VIDEO, "Validation layer requested but not available, disabling."); enable_validation_layer = false; } // Create Vulkan instance, needed before we can create a surface. bool enable_surface = (window_handle != nullptr); VkInstance instance = VulkanContext::CreateVulkanInstance(enable_surface, enable_validation_layer); if (instance == VK_NULL_HANDLE) { PanicAlert("Failed to create Vulkan instance."); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Load instance function pointers if (!LoadVulkanInstanceFunctions(instance)) { PanicAlert("Failed to load Vulkan instance functions."); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create Vulkan surface VkSurfaceKHR surface = VK_NULL_HANDLE; if (enable_surface) { surface = SwapChain::CreateVulkanSurface(instance, window_handle); if (surface == VK_NULL_HANDLE) { PanicAlert("Failed to create Vulkan surface."); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } } // Fill the adapter list, and check if the user has selected an invalid device // For some reason nvidia's driver crashes randomly if you call vkEnumeratePhysicalDevices // after creating a device.. VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(instance); size_t selected_adapter_index = static_cast<size_t>(g_Config.iAdapter); if (gpu_list.empty()) { PanicAlert("No Vulkan physical devices available."); if (surface != VK_NULL_HANDLE) vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } else if (selected_adapter_index >= gpu_list.size()) { WARN_LOG(VIDEO, "Vulkan adapter index out of range, selecting first adapter."); selected_adapter_index = 0; } // Pass ownership over to VulkanContext, and let it take care of everything. g_vulkan_context = VulkanContext::Create(instance, gpu_list[selected_adapter_index], surface, &g_Config, enable_validation_layer); if (!g_vulkan_context) { PanicAlert("Failed to create Vulkan device"); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create swap chain. This has to be done early so that the target size is correct for auto-scale. std::unique_ptr<SwapChain> swap_chain; if (surface != VK_NULL_HANDLE) { swap_chain = SwapChain::Create(window_handle, surface, g_Config.IsVSync()); if (!swap_chain) { PanicAlert("Failed to create Vulkan swap chain."); return false; } } // Create command buffers. We do this separately because the other classes depend on it. g_command_buffer_mgr = std::make_unique<CommandBufferManager>(g_Config.bBackendMultithreading); if (!g_command_buffer_mgr->Initialize()) { PanicAlert("Failed to create Vulkan command buffers"); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create main wrapper instances. g_object_cache = std::make_unique<ObjectCache>(); g_framebuffer_manager = std::make_unique<FramebufferManager>(); g_renderer = std::make_unique<Renderer>(std::move(swap_chain)); // Invoke init methods on main wrapper classes. // These have to be done before the others because the destructors // for the remaining classes may call methods on these. if (!g_object_cache->Initialize() || !FramebufferManager::GetInstance()->Initialize() || !StateTracker::CreateInstance() || !Renderer::GetInstance()->Initialize()) { PanicAlert("Failed to initialize Vulkan classes."); g_renderer.reset(); StateTracker::DestroyInstance(); g_framebuffer_manager.reset(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create remaining wrapper instances. g_vertex_manager = std::make_unique<VertexManager>(); g_texture_cache = std::make_unique<TextureCache>(); g_perf_query = std::make_unique<PerfQuery>(); if (!VertexManager::GetInstance()->Initialize() || !TextureCache::GetInstance()->Initialize() || !PerfQuery::GetInstance()->Initialize()) { PanicAlert("Failed to initialize Vulkan classes."); g_perf_query.reset(); g_texture_cache.reset(); g_vertex_manager.reset(); g_renderer.reset(); StateTracker::DestroyInstance(); g_framebuffer_manager.reset(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } return true; }
void TraversalClient::HandleServerPacket(TraversalPacket* packet) { u8 ok = 1; switch (packet->type) { case TraversalPacketAck: if (!packet->ack.ok) { OnFailure(ServerForgotAboutUs); break; } for (auto it = m_OutgoingTraversalPackets.begin(); it != m_OutgoingTraversalPackets.end(); ++it) { if (it->packet.requestId == packet->requestId) { m_OutgoingTraversalPackets.erase(it); break; } } break; case TraversalPacketHelloFromServer: if (m_State != Connecting) break; if (!packet->helloFromServer.ok) { OnFailure(VersionTooOld); break; } m_HostId = packet->helloFromServer.yourHostId; m_State = Connected; if (m_Client) m_Client->OnTraversalStateChanged(); break; case TraversalPacketPleaseSendPacket: { // security is overrated. ENetAddress addr = MakeENetAddress(&packet->pleaseSendPacket.address); if (addr.port != 0) { char message[] = "Hello from Dolphin Netplay..."; ENetBuffer buf; buf.data = message; buf.dataLength = sizeof(message) - 1; enet_socket_send(m_NetHost->socket, &addr, &buf, 1); } else { // invalid IPV6 ok = 0; } break; } case TraversalPacketConnectReady: case TraversalPacketConnectFailed: { if (!m_PendingConnect || packet->connectReady.requestId != m_ConnectRequestId) break; m_PendingConnect = false; if (!m_Client) break; if (packet->type == TraversalPacketConnectReady) m_Client->OnConnectReady(MakeENetAddress(&packet->connectReady.address)); else m_Client->OnConnectFailed(packet->connectFailed.reason); break; } default: WARN_LOG(NETPLAY, "Received unknown packet with type %d", packet->type); break; } if (packet->type != TraversalPacketAck) { TraversalPacket ack = {}; ack.type = TraversalPacketAck; ack.requestId = packet->requestId; ack.ack.ok = ok; ENetBuffer buf; buf.data = &ack; buf.dataLength = sizeof(ack); if (enet_socket_send(m_NetHost->socket, &m_ServerAddress, &buf, 1) == -1) OnFailure(SocketSendError); } }
IPCCommandResult CWII_IPC_HLE_Device_usb_oh0_46d_a03::IOCtlV(u32 CommandAddress) { IPCCommandResult SendReply = GetNoReply(); SIOCtlVBuffer CommandBuffer(CommandAddress); switch (CommandBuffer.Parameter) { case USBV0_IOCTL_CTRLMSG: { USBSetupPacket setup_packet; setup_packet.bmRequestType = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); setup_packet.bRequest = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address); setup_packet.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address); setup_packet.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address); setup_packet.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address); const u32 payload_addr = CommandBuffer.PayloadBuffer[0].m_Address; #define DIR_TO_DEV 0 #define DIR_TO_HOST 1 #define TYPE_STANDARD 0 #define TYPE_CLASS 1 #define TYPE_VENDOR 2 #define RECP_DEV 0 #define RECP_INT 1 #define RECP_ENDP 2 #define USBHDR(dir, type, recipient, request) \ ((((dir << 7) | (type << 5) | recipient) << 8) | request) switch (((u16)setup_packet.bmRequestType << 8) | setup_packet.bRequest) { case USBHDR(DIR_TO_HOST, TYPE_STANDARD, RECP_DEV, 6): // GET_DESCRIPTOR switch (setup_packet.wValue >> 8) { // CONFIGURATION case 2: { const usb_configurationdesc config = { 9, 2, 121, 2, 1, 3, 0x80, 30 }; if (setup_packet.wLength == 9) { memcpy(Memory::GetPointer(payload_addr), &config, setup_packet.wLength); } else { #define LE24(x) (x & 0xff), ((x >> 8) & 0xff), (x >> 16) #pragma pack(push, 1) struct { usb_configurationdesc config; usb_interfacedesc int0; struct audiocontrol_hdr { u8 bLength; u8 bDescriptorType; u8 bDescriptorSubtype; }; struct { audiocontrol_hdr hdr; u16 bcdADC; u16 wTotalLength; u8 bInCollection; u8 baInterfaceNr; } audiocontrol_header; struct { audiocontrol_hdr hdr; u8 bTerminalID; u16 wTerminalType; u8 bAssocTerminal; u8 bNrChannels; u16 wChannelConfig; u8 iChannelNames; u8 iTerminal; } audiocontrol_input_terminal; struct { audiocontrol_hdr hdr; u8 bUnitID; u8 bSourceID; u8 bControlSize; u8 bmaControls0; u8 bmaControls1; u8 iFeature; } audiocontrol_feature_unit; struct { audiocontrol_hdr hdr; u8 bTerminalID; u16 wTerminalType; u8 bAssocTerminal; u8 bSourceID; u8 iTerminal; } audiocontrol_output_terminal; usb_interfacedesc int1; usb_interfacedesc int2; struct { audiocontrol_hdr hdr; u8 bTerminalLink; u8 bDelay; u16 wFormatTag; } audiocontrol_as_general; struct { audiocontrol_hdr hdr; u8 bFormatType; u8 bNrChannels; u8 bSubframeSize; u8 bBitResolution; u8 bSamFreqType; u8 tSamFreq[3 * 5]; } audiocontrol_format_type; usb_endpointdesc endp; struct { audiocontrol_hdr hdr; u8 bmAttributes; u8 bLockDelayUnits; u16 wLockDelay; } audiocontrol_ep_general; } const fullconfig = { config, { 9, 4, 0, 0, 0, 1, 1, 0, 0 }, { 9, 36, 1, 0x100, 39, 1, 1 }, { 12, 36, 2, 13, 0x201, 0, 1, 0, 0, 0 }, { 9, 36, 6, 2, 13, 1, 3, 0 }, { 9, 36, 3, 10, 0x101, 0, 2, 0 }, { 9, 4, 1, 0, 0, 1, 2, 0, 0 }, { 9, 4, 1, 1, 1, 1, 2, 0, 0 }, { 7, 36, 1, 10, 0, 1 }, { 23, 36, 2, 1, 1, 2, 16, 5, LE24(8000), LE24(11025), LE24(22050), LE24(44100), LE24(48000) }, { 9, 5, 0x84, 13, 0x60, 1, 0, 0 }, { 7, 37, 1, 1, 2, 1 } }; #pragma pack(pop) #undef LE24 memcpy(Memory::GetPointer(payload_addr), &fullconfig, setup_packet.wLength); } Memory::Write_U32(sizeof(USBSetupPacket) + setup_packet.wLength, CommandAddress + 4); return GetDefaultReply(); } break; default: goto outerdefault; } break; case USBHDR(DIR_TO_HOST, TYPE_CLASS, RECP_INT, 0x82): case USBHDR(DIR_TO_HOST, TYPE_CLASS, RECP_INT, 0x83): if (setup_packet.bRequest & 1) Memory::Write_U16(0x7fff, payload_addr); else Memory::Write_U16(0x8000, payload_addr); break; case USBHDR(DIR_TO_DEV, TYPE_CLASS, RECP_ENDP, 1): { u32 freq = *(u32*)Memory::GetPointer(payload_addr) & 0xffffff; WARN_LOG(OSHLE, "set freq: %x", freq); } break; case USBHDR(DIR_TO_DEV, TYPE_STANDARD, RECP_INT, 11): break; outerdefault: default: WARN_LOG(OSHLE, "UNK %02x %02x %04x %04x", setup_packet.bmRequestType, setup_packet.bRequest, setup_packet.wValue, setup_packet.wLength); break; } // command finished, send a reply to command WII_IPC_HLE_Interface::EnqueueReply(CommandBuffer.m_Address); } break; case USBV0_IOCTL_ISOMSG: { // endp 81 = mic -> console // endp 03 = console -> mic u8 endpoint = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address); u16 length = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address); u8 num_packets = Memory::Read_U8(CommandBuffer.InBuffer[2].m_Address); u16 *packet_sizes = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address); u8 *packets = Memory::GetPointer(CommandBuffer.PayloadBuffer[1].m_Address); u16 packet_len = Common::swap16(packet_sizes[0]); WARN_LOG(OSHLE, "%i to endpoint %02x", packet_len, endpoint); /* for (int i = 0; i < num_packets; i++) { u16 packet_len = Common::swap16(packet_sizes[i]); WARN_LOG(OSHLE, "packet %i [%i] to endpoint %02x", i, packet_len, endpoint); WARN_LOG(OSHLE, "%s", ArrayToString(packets, packet_len, 16).c_str()); packets += packet_len; } */ if (endpoint == AUDIO_IN) for (u16 *sample = (u16*)packets; sample != (u16*)(packets + length); sample++) *sample = 0; // TODO actual responses should obey some kinda timey thing SendReply = GetDefaultReply(); } break; default: WARN_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str()); WARN_LOG(OSHLE, " Parameter: 0x%x", CommandBuffer.Parameter); WARN_LOG(OSHLE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); WARN_LOG(OSHLE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); WARN_LOG(OSHLE, " BufferVector: 0x%08x", CommandBuffer.BufferVector); //DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer, LogTypes::OSHLE, LogTypes::LWARNING); break; } Memory::Write_U32(0, CommandAddress + 4); return SendReply; }
void ExecuteCommand(u32 _Address) { IPCCommandResult result = IPC_NO_REPLY; IPCCommandType Command = static_cast<IPCCommandType>(Memory::Read_U32(_Address)); s32 DeviceID = Memory::Read_U32(_Address + 8); IWII_IPC_HLE_Device* pDevice = (DeviceID >= 0 && DeviceID < IPC_MAX_FDS) ? g_FdMap[DeviceID] : nullptr; INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) %p", _Address, Command, DeviceID, pDevice); switch (Command) { case IPC_CMD_OPEN: { u32 Mode = Memory::Read_U32(_Address + 0x10); DeviceID = getFreeDeviceId(); std::string DeviceName = Memory::GetString(Memory::Read_U32(_Address + 0xC)); WARN_LOG(WII_IPC_HLE, "Trying to open %s as %d", DeviceName.c_str(), DeviceID); if (DeviceID >= 0) { if (DeviceName.find("/dev/es") == 0) { u32 j; for (j=0; j<ES_MAX_COUNT; j++) { if (!es_inuse[j]) { es_inuse[j] = true; g_FdMap[DeviceID] = es_handles[j]; result = es_handles[j]->Open(_Address, Mode); Memory::Write_U32(DeviceID, _Address+4); break; } } if (j == ES_MAX_COUNT) { Memory::Write_U32(FS_EESEXHAUSTED, _Address + 4); result = IPC_DEFAULT_REPLY; } } else if (DeviceName.find("/dev/") == 0) { pDevice = GetDeviceByName(DeviceName); if (pDevice) { g_FdMap[DeviceID] = pDevice; result = pDevice->Open(_Address, Mode); INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)", pDevice->GetDeviceName().c_str(), DeviceID, Mode); Memory::Write_U32(DeviceID, _Address+4); } else { WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str()); Memory::Write_U32(FS_ENOENT, _Address+4); result = IPC_DEFAULT_REPLY; } } else { pDevice = CreateFileIO(DeviceID, DeviceName); result = pDevice->Open(_Address, Mode); INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)", pDevice->GetDeviceName().c_str(), DeviceID, Mode); if (Memory::Read_U32(_Address + 4) == (u32)DeviceID) { g_FdMap[DeviceID] = pDevice; } else { delete pDevice; pDevice = nullptr; } } } else { Memory::Write_U32(FS_EFDEXHAUSTED, _Address + 4); result = IPC_DEFAULT_REPLY; } break; } case IPC_CMD_CLOSE: { if (pDevice) { result = pDevice->Close(_Address); for (u32 j=0; j<ES_MAX_COUNT; j++) { if (es_handles[j] == g_FdMap[DeviceID]) { es_inuse[j] = false; } } g_FdMap[DeviceID] = nullptr; // Don't delete hardware if (!pDevice->IsHardware()) { delete pDevice; pDevice = nullptr; } } else { Memory::Write_U32(FS_EINVAL, _Address + 4); result = IPC_DEFAULT_REPLY; } break; } case IPC_CMD_READ: { if (pDevice) { result = pDevice->Read(_Address); } else { Memory::Write_U32(FS_EINVAL, _Address + 4); result = IPC_DEFAULT_REPLY; } break; } case IPC_CMD_WRITE: { if (pDevice) { result = pDevice->Write(_Address); } else { Memory::Write_U32(FS_EINVAL, _Address + 4); result = IPC_DEFAULT_REPLY; } break; } case IPC_CMD_SEEK: { if (pDevice) { result = pDevice->Seek(_Address); } else { Memory::Write_U32(FS_EINVAL, _Address + 4); result = IPC_DEFAULT_REPLY; } break; } case IPC_CMD_IOCTL: { if (pDevice) { result = pDevice->IOCtl(_Address); } break; } case IPC_CMD_IOCTLV: { if (pDevice) { result = pDevice->IOCtlV(_Address); } break; } default: { _dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address); break; } } // Ensure replies happen in order const s64 ticks_until_last_reply = last_reply_time - CoreTiming::GetTicks(); if (ticks_until_last_reply > 0) result.reply_delay_ticks += ticks_until_last_reply; last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; if (result.send_reply) { // The original hardware overwrites the command type with the async reply type. Memory::Write_U32(IPC_REP_ASYNC, _Address); // IOS also seems to write back the command that was responded to in the FD field. Memory::Write_U32(Command, _Address + 8); // Generate a reply to the IPC command EnqueueReply(_Address, (int)result.reply_delay_ticks); } }
u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) { // LBN unittest /* u32 a, b; if (parseLBN("/sce_lbn0x307aa_size0xefffe000", &a, &b)) { ERROR_LOG(FILESYS, "lbn: %08x %08x", a, b); } else { ERROR_LOG(FILESYS, "faillbn: %08x %08x", a, b); }*/ OpenFileEntry entry; entry.isRawSector = false; entry.isBlockSectorMode = false; if (filename.compare(0,8,"/sce_lbn") == 0) { u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF; parseLBN(filename, §orStart, &readSize); if (sectorStart >= blockDevice->GetNumBlocks()) { WARN_LOG(FILESYS, "Unable to open raw sector: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks()); return 0; } DEBUG_LOG(FILESYS, "Got a raw sector open: %s, sector %08x, size %08x", filename.c_str(), sectorStart, readSize); u32 newHandle = hAlloc->GetNewHandle(); entry.seekPos = 0; entry.file = 0; entry.isRawSector = true; entry.sectorStart = sectorStart; entry.openSize = readSize; // when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device. // the param in sceIoLseek and sceIoRead is lba mode. we must mark it. if(strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0) entry.isBlockSectorMode = true; entries[newHandle] = entry; return newHandle; } if (access & FILEACCESS_WRITE) { ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str()); return 0; } // May return entireISO for "umd0:" entry.file = GetFromPath(filename); if (!entry.file){ return 0; } if (entry.file==&entireISO) entry.isBlockSectorMode = true; entry.seekPos = 0; u32 newHandle = hAlloc->GetNewHandle(); entries[newHandle] = entry; return newHandle; }
bool SConfig::AutoSetup(EBootBS2 _BootBS2) { std::string set_region_dir(EUR_DIR); switch (_BootBS2) { case BOOT_DEFAULT: { bool bootDrive = cdio_is_cdrom(m_strFilename); // Check if the file exist, we may have gotten it from a --elf command line // that gave an incorrect file name if (!bootDrive && !File::Exists(m_strFilename)) { PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str()); return false; } std::string Extension; SplitPath(m_strFilename, nullptr, nullptr, &Extension); if (!strcasecmp(Extension.c_str(), ".gcm") || !strcasecmp(Extension.c_str(), ".iso") || !strcasecmp(Extension.c_str(), ".wbfs") || !strcasecmp(Extension.c_str(), ".ciso") || !strcasecmp(Extension.c_str(), ".gcz") || bootDrive) { m_BootType = BOOT_ISO; std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); if (pVolume == nullptr) { if (bootDrive) PanicAlertT("Could not read \"%s\". " "There is no disc in the drive, or it is not a GC/Wii backup. " "Please note that original GameCube and Wii discs cannot be read " "by most PC DVD drives.", m_strFilename.c_str()); else PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", m_strFilename.c_str()); return false; } m_strName = pVolume->GetInternalName(); m_strUniqueID = pVolume->GetUniqueID(); m_revision = pVolume->GetRevision(); // Check if we have a Wii disc bWii = pVolume.get()->GetVolumeType() == DiscIO::IVolume::WII_DISC; const char* retrieved_region_dir = GetRegionOfCountry(pVolume->GetCountry()); if (!retrieved_region_dir) { if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)." "\nContinue with PAL region?")) return false; retrieved_region_dir = EUR_DIR; } set_region_dir = retrieved_region_dir; bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; } else if (!strcasecmp(Extension.c_str(), ".elf")) { bWii = CBoot::IsElfWii(m_strFilename); // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL. // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, without forcing all GC homebrew to 50Hz. // In the future, it probably makes sense to add a Region setting for homebrew somewhere in the emulator config. bNTSC = bWii ? false : true; set_region_dir = bNTSC ? USA_DIR : EUR_DIR; m_BootType = BOOT_ELF; } else if (!strcasecmp(Extension.c_str(), ".dol")) { CDolLoader dolfile(m_strFilename); bWii = dolfile.IsWii(); // TODO: See the ELF code above. bNTSC = bWii ? false : true; set_region_dir = bNTSC ? USA_DIR : EUR_DIR; m_BootType = BOOT_DOL; } else if (!strcasecmp(Extension.c_str(), ".dff")) { bWii = true; set_region_dir = USA_DIR; bNTSC = true; m_BootType = BOOT_DFF; std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true)); if (ddfFile) { bWii = ddfFile->GetIsWii(); } } else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid()) { std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename); if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr) { //WAD is valid yet cannot be booted. Install instead. u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename); if (installed) SuccessAlertT("The WAD has been installed successfully"); return false; //do not boot } const char* retrieved_region_dir = GetRegionOfCountry(ContentLoader.GetCountry()); set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR; bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; bWii = true; m_BootType = BOOT_WII_NAND; if (pVolume) { m_strName = pVolume->GetInternalName(); m_strUniqueID = pVolume->GetUniqueID(); } else { // null pVolume means that we are loading from nand folder (Most Likely Wii Menu) // if this is the second boot we would be using the Name and id of the last title m_strName.clear(); m_strUniqueID.clear(); } // Use the TitleIDhex for name and/or unique ID if launching from nand folder // or if it is not ascii characters (specifically sysmenu could potentially apply to other things) std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID()); if (m_strName.empty()) { m_strName = titleidstr; } if (m_strUniqueID.empty()) { m_strUniqueID = titleidstr; } } else { PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str()); return false; } } break; case BOOT_BS2_USA: set_region_dir = USA_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_JAP: set_region_dir = JAP_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_EUR: set_region_dir = EUR_DIR; m_strFilename.clear(); bNTSC = false; break; } // Setup paths CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, set_region_dir, true); CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, set_region_dir, false); m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); if (!bWii) { if (!bHLE_BS2) { m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) { WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str()); bHLE_BS2 = true; } } } else if (bWii && !bHLE_BS2) { WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode."); bHLE_BS2 = true; } return true; }
IVolume::ECountry CountrySwitch(u8 CountryCode) { switch (CountryCode) { // Region free - fall through to European defaults for now case 'A': // PAL case 'D': // German return IVolume::COUNTRY_GERMANY; break; case 'X': // Used by a couple PAL games case 'Y': // German, french case 'L': // Japanese import to PAL regions case 'M': // Japanese import to PAL regions case 'S': // Spanish-speaking regions case 'P': case 'U': // Australia return IVolume::COUNTRY_EUROPE; break; case 'F': return IVolume::COUNTRY_FRANCE; break; case 'I': return IVolume::COUNTRY_ITALY; break; case 'R': return IVolume::COUNTRY_RUSSIA; break; // NTSC case 'E': case 'N': // Japanese import to USA and other NTSC regions case 'Z': // Prince Of Persia - The Forgotten Sands (WII) return IVolume::COUNTRY_USA; break; case 'J': return IVolume::COUNTRY_JAPAN; break; case 'K': case 'T': // Korea with English language case 'Q': // Korea with Japanese language return IVolume::COUNTRY_KOREA; break; case 'O': return IVolume::COUNTRY_SDK; break; case 'W': return IVolume::COUNTRY_TAIWAN; break; default: if (CountryCode > 'A') // Silently ignore IOS wads WARN_LOG(DISCIO, "Unknown Country Code! %c", CountryCode); return IVolume::COUNTRY_UNKNOWN; break; } }
int scePsmfPlayerGetAudioOutSize(u32 psmfPlayer) { WARN_LOG(HLE, "scePsmfPlayerGetAudioOutSize(%08x)", psmfPlayer); return audioSamplesBytes; }
void CEXIMemoryCard::TransferByte(u8& byte) { DEBUG_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: > %02x", byte); if (m_uPosition == 0) { command = byte; // first byte is command byte = 0xFF; // would be tristate, but we don't care. switch (command) // This seems silly, do we really need it? { case cmdNintendoID: case cmdReadArray: case cmdArrayToBuffer: case cmdSetInterrupt: case cmdWriteBuffer: case cmdReadStatus: case cmdReadID: case cmdReadErrorBuffer: case cmdWakeUp: case cmdSleep: case cmdClearStatus: case cmdSectorErase: case cmdPageProgram: case cmdExtraByteProgram: case cmdChipErase: DEBUG_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: command %02x at position 0. seems normal.", command); break; default: WARN_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: command %02x at position 0", command); break; } if (command == cmdClearStatus) { status &= ~MC_STATUS_PROGRAMEERROR; status &= ~MC_STATUS_ERASEERROR; status |= MC_STATUS_READY; m_bInterruptSet = 0; byte = 0xFF; m_uPosition = 0; } } else { switch (command) { case cmdNintendoID: // // Nintendo card: // 00 | 80 00 00 00 10 00 00 00 // "bigben" card: // 00 | ff 00 00 05 10 00 00 00 00 00 00 00 00 00 00 // we do it the Nintendo way. if (m_uPosition == 1) byte = 0x80; // dummy cycle else byte = (u8)(memorycard->GetCardId() >> (24 - (((m_uPosition - 2) & 3) * 8))); break; case cmdReadArray: switch (m_uPosition) { case 1: // AD1 address = byte << 17; byte = 0xFF; break; case 2: // AD2 address |= byte << 9; break; case 3: // AD3 address |= (byte & 3) << 7; break; case 4: // BA address |= (byte & 0x7F); break; } if (m_uPosition > 1) // not specified for 1..8, anyway { memorycard->Read(address & (memory_card_size - 1), 1, &byte); // after 9 bytes, we start incrementing the address, // but only the sector offset - the pointer wraps around if (m_uPosition >= 9) address = (address & ~0x1FF) | ((address + 1) & 0x1FF); } break; case cmdReadStatus: // (unspecified for byte 1) byte = status; break; case cmdReadID: if (m_uPosition == 1) // (unspecified) byte = (u8)(card_id >> 8); else byte = (u8)((m_uPosition & 1) ? (card_id) : (card_id >> 8)); break; case cmdSectorErase: switch (m_uPosition) { case 1: // AD1 address = byte << 17; break; case 2: // AD2 address |= byte << 9; break; } byte = 0xFF; break; case cmdSetInterrupt: if (m_uPosition == 1) { interruptSwitch = byte; } byte = 0xFF; break; case cmdChipErase: byte = 0xFF; break; case cmdPageProgram: switch (m_uPosition) { case 1: // AD1 address = byte << 17; break; case 2: // AD2 address |= byte << 9; break; case 3: // AD3 address |= (byte & 3) << 7; break; case 4: // BA address |= (byte & 0x7F); break; } if (m_uPosition >= 5) programming_buffer[((m_uPosition - 5) & 0x7F)] = byte; // wrap around after 128 bytes byte = 0xFF; break; default: WARN_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: unknown command byte %02x\n", byte); byte = 0xFF; } }
// called from ---UPnP--- thread // discovers the IGD static bool InitUPnP() { static bool s_inited = false; static bool s_error = false; // Don't init if already inited if (s_inited) return true; // Don't init if it failed before if (s_error) return false; s_urls = {}; s_data = {}; // Find all UPnP devices int upnperror = 0; std::unique_ptr<UPNPDev, decltype(&freeUPNPDevlist)> devlist(nullptr, freeUPNPDevlist); #if MINIUPNPC_API_VERSION >= 14 devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror)); #else devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, &upnperror)); #endif if (!devlist) { WARN_LOG(NETPLAY, "An error occurred trying to discover UPnP devices."); s_error = true; return false; } // Look for the IGD for (UPNPDev* dev = devlist.get(); dev; dev = dev->pNext) { if (!std::strstr(dev->st, "InternetGatewayDevice")) continue; int desc_xml_size = 0; std::unique_ptr<char, decltype(&std::free)> desc_xml(nullptr, std::free); int statusCode = 200; #if MINIUPNPC_API_VERSION >= 16 desc_xml.reset( static_cast<char*>(miniwget_getaddr(dev->descURL, &desc_xml_size, s_our_ip.data(), static_cast<int>(s_our_ip.size()), 0, &statusCode))); #else desc_xml.reset(static_cast<char*>(miniwget_getaddr( dev->descURL, &desc_xml_size, s_our_ip.data(), static_cast<int>(s_our_ip.size()), 0))); #endif if (desc_xml && statusCode == 200) { parserootdesc(desc_xml.get(), desc_xml_size, &s_data); GetUPNPUrls(&s_urls, &s_data, dev->descURL, 0); NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL); break; } else { WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL); } } s_inited = true; return true; }
bool PointGeometryShader::SetShader(u32 components, float pointSize, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable) { if (!m_ready) return false; // Make sure geometry shader for "components" is available ComboMap::iterator shaderIt = m_shaders.find(components); if (shaderIt == m_shaders.end()) { // Generate new shader. Warning: not thread-safe. static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); GenerateVSOutputStructForGS(code, API_D3D); code.Write("\n%s", POINT_GS_COMMON); std::stringstream numTexCoordsStream; numTexCoordsStream << xfregs.numTexGen.numTexGens; INFO_LOG(VIDEO, "Compiling point geometry shader for components 0x%.08X (num texcoords %d)", components, xfregs.numTexGen.numTexGens); const std::string& numTexCoordsStr = numTexCoordsStream.str(); D3D_SHADER_MACRO macros[] = { { "NUM_TEXCOORDS", numTexCoordsStr.c_str() }, { nullptr, nullptr } }; ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), unsigned int(strlen(code.GetBuffer())), macros); if (!newShader) { WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components); // Add dummy shader to prevent trying to compile again m_shaders[components] = nullptr; return false; } shaderIt = m_shaders.insert(std::make_pair(components, newShader)).first; } if (shaderIt != m_shaders.end()) { if (shaderIt->second) { D3D11_MAPPED_SUBRESOURCE map; HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { PointGSParams* params = (PointGSParams*)map.pData; params->PointSize = pointSize; params->TexOffset = texOffset; params->VpWidth = vpWidth; params->VpHeight = vpHeight; for (int i = 0; i < 8; ++i) params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f; D3D::context->Unmap(m_paramsBuffer, 0); } else ERROR_LOG(VIDEO, "Failed to map point gs params buffer"); DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f", pointSize, texOffset, vpWidth, vpHeight); D3D::context->GSSetShader(shaderIt->second, nullptr, 0); D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); return true; } else return false; } else return false; }
int ThreadManForKernel_f475845d(SceUID threadToStartID, int argSize, u32 argBlockPtr) { WARN_LOG(SCEKERNEL,"ThreadManForKernel_f475845d:Not support this patcher"); return sceKernelStartThread(threadToStartID,argSize,argBlockPtr); }
void UCConfMgr::AddConfMember(void) { TUP_RESULT tRet = TUP_FAIL; if(!m_strCalleeNum.empty()) { STConfParam item={0}; item.memStatus = CONF_MEM_INVITING; if(m_bIsUCAccount) { item.memType = UC_ACCOUNT; strcpy_s(item.ucAcc,STRING_LENGTH,m_strCalleeAccount.c_str()); //添加讨论组UC成员 UCGroupMgr::Instance().AddUCMemberInGroup(m_strGroupID,m_strCalleeAccount); UCGroupMgr::Instance().AddLocalUCMember(m_strGroupID,m_strCalleeAccount,m_strCalleeNum); } else { item.memType = UC_IPPHONE; strcpy_s(item.ucAcc,STRING_LENGTH,m_strCalleeNum.c_str()); //增加讨论群组电话用户 UCGroupMgr::Instance().AddPhoneMemberInGroup(m_strGroupID,m_strCalleeNum); UCGroupMgr::Instance().AddLocalPhoneMember(m_strGroupID,m_strCalleeNum); } NotifyConfUI(item); tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,m_strCalleeNum.c_str(),m_strCalleeNum.size()+1); if(tRet != TUP_SUCCESS) { WARN_LOG("tup_call_serverconf_add_attendee add %s failed",m_strCalleeNum.c_str()); item.memStatus = CONF_MEM_DEL; NotifyConfUI(item); } } //要先加UC用户群组再加电话用户,否则被叫端收不到话机用户的增加消息 UCMemList::iterator ucit = m_confUCMemList.begin(); UCMemList::iterator ucitEnd = m_confUCMemList.end(); for(;ucit != ucitEnd;ucit++) { std::string strBindNO = (*ucit).second; if(strBindNO != m_strCalleeNum)//避免重复邀请 { std::string strAccount = (*ucit).first; STConfParam item; item.memStatus = CONF_MEM_INVITING; item.memType = UC_ACCOUNT; strcpy_s(item.ucAcc,STRING_LENGTH,strAccount.c_str()); NotifyConfUI(item); //添加讨论组UC成员 UCGroupMgr::Instance().AddUCMemberInGroup(m_strGroupID,strAccount); UCGroupMgr::Instance().AddLocalUCMember(m_strGroupID,strAccount,strBindNO); tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,strBindNO.c_str(),strBindNO.size()+1); if(tRet != TUP_SUCCESS) { WARN_LOG("tup_call_serverconf_add_attendee add %s:%s failed,reason %d",strAccount.c_str(),strBindNO.c_str(),tRet); item.memStatus = CONF_MEM_DEL; NotifyConfUI(item); } } } std::string strGroup; PhoneMemList::iterator it = m_confPhoneMemList.begin(); PhoneMemList::iterator itEnd = m_confPhoneMemList.end(); for(;it != itEnd;it++) { std::string strPhoneNum = *it; if(strPhoneNum != m_strCalleeNum)//避免重复邀请 { STConfParam item; item.memStatus = CONF_MEM_INVITING; item.memType = UC_IPPHONE; strcpy_s(item.ucAcc,STRING_LENGTH,strPhoneNum.c_str()); NotifyConfUI(item); //增加讨论群组电话用户 UCGroupMgr::Instance().AddPhoneMemberInGroup(m_strGroupID,strPhoneNum); UCGroupMgr::Instance().AddLocalPhoneMember(m_strGroupID,strPhoneNum); tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,strPhoneNum.c_str(),strPhoneNum.size()+1); if(tRet != TUP_SUCCESS) { WARN_LOG("tup_call_serverconf_add_attendee add %s failed",strPhoneNum.c_str()); item.memStatus = CONF_MEM_DEL; NotifyConfUI(item); } } } //主席也要放到成员列表里面 m_strChairManAccount = UCRegMgr::Instance().GetSelfAccount(); m_strChairManBindNo = UCRegMgr::Instance().GetBindNO(); m_confUCMemList[m_strChairManAccount] = m_strChairManBindNo; //清除信息 m_strCalleeNum.clear(); m_strCalleeAccount.clear(); m_bIsUCAccount = false; }
int LoadExecForKernel_4AC57943(SceUID cbId) { WARN_LOG(SCEKERNEL,"LoadExecForKernel_4AC57943:Not support this patcher"); return sceKernelRegisterExitCallback(cbId);//not sure right }
SceUID sceKernelCreateTls(const char *name, u32 partition, u32 attr, u32 blockSize, u32 count, u32 optionsPtr) { if (!name) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid name", SCE_KERNEL_ERROR_NO_MEMORY); return SCE_KERNEL_ERROR_NO_MEMORY; } if ((attr & ~PSP_TLS_ATTR_KNOWN) >= 0x100) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, attr); return SCE_KERNEL_ERROR_ILLEGAL_ATTR; } if (partition < 1 || partition > 9 || partition == 7) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition); return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; } // We only support user right now. if (partition != 2 && partition != 6) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_PERM, partition); return SCE_KERNEL_ERROR_ILLEGAL_PERM; } // There's probably a simpler way to get this same basic formula... // This is based on results from a PSP. bool illegalMemSize = blockSize == 0 || count == 0; if (!illegalMemSize && (u64) blockSize > ((0x100000000ULL / (u64) count) - 4ULL)) illegalMemSize = true; if (!illegalMemSize && (u64) count >= 0x100000000ULL / (((u64) blockSize + 3ULL) & ~3ULL)) illegalMemSize = true; if (illegalMemSize) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid blockSize/count", SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE); return SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE; } int index = -1; for (int i = 0; i < TLS_NUM_INDEXES; ++i) if (tlsUsedIndexes[i] == false) { index = i; break; } if (index == -1) { WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): ran out of indexes for TLS objects", PSP_ERROR_TOO_MANY_TLS); return PSP_ERROR_TOO_MANY_TLS; } u32 totalSize = blockSize * count; u32 blockPtr = userMemory.Alloc(totalSize, (attr & PSP_TLS_ATTR_HIGHMEM) != 0, name); userMemory.ListBlocks(); if (blockPtr == (u32) -1) { ERROR_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x): failed to allocate memory", SCE_KERNEL_ERROR_NO_MEMORY, name, partition, attr, blockSize, count, optionsPtr); return SCE_KERNEL_ERROR_NO_MEMORY; } TLS *tls = new TLS(); SceUID id = kernelObjects.Create(tls); tls->ntls.size = sizeof(tls->ntls); strncpy(tls->ntls.name, name, KERNELOBJECT_MAX_NAME_LENGTH); tls->ntls.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0; tls->ntls.attr = attr; tls->ntls.index = index; tlsUsedIndexes[index] = true; tls->ntls.blockSize = blockSize; tls->ntls.totalBlocks = count; tls->ntls.freeBlocks = count; tls->ntls.numWaitThreads = 0; tls->address = blockPtr; tls->usage.resize(count, 0); WARN_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x)", id, name, partition, attr, blockSize, count, optionsPtr); // TODO: just alignment? if (optionsPtr != 0) WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported options parameter: %08x", name, optionsPtr); if ((attr & PSP_TLS_ATTR_PRIORITY) != 0) WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported attr parameter: %08x", name, attr); return id; }
static int sceCccIsValidUCS2(u32 c) { WARN_LOG(HLE, "UNIMPL sceCccIsValidUCS2(%08x)", c); return c != 0; }
u32 sceAudioOutput2Release() { WARN_LOG(HLE,"sceAudioOutput2Release()"); chans[0].reserved = false; return 0; }