mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	http/soc: Various implementations and fixes (#6828)
This commit is contained in:
		
							parent
							
								
									baf3ea4beb
								
							
						
					
					
						commit
						970f2284d8
					
				
					 17 changed files with 322 additions and 202 deletions
				
			
		|  | @ -247,6 +247,8 @@ add_library(citra_core STATIC | ||||||
|     hle/service/cam/cam_s.h |     hle/service/cam/cam_s.h | ||||||
|     hle/service/cam/cam_u.cpp |     hle/service/cam/cam_u.cpp | ||||||
|     hle/service/cam/cam_u.h |     hle/service/cam/cam_u.h | ||||||
|  |     hle/service/cam/y2r_u.cpp | ||||||
|  |     hle/service/cam/y2r_u.h | ||||||
|     hle/service/cecd/cecd.cpp |     hle/service/cecd/cecd.cpp | ||||||
|     hle/service/cecd/cecd.h |     hle/service/cecd/cecd.h | ||||||
|     hle/service/cecd/cecd_ndm.cpp |     hle/service/cecd/cecd_ndm.cpp | ||||||
|  | @ -279,8 +281,8 @@ add_library(citra_core STATIC | ||||||
|     hle/service/dlp/dlp_srvr.h |     hle/service/dlp/dlp_srvr.h | ||||||
|     hle/service/dsp/dsp_dsp.cpp |     hle/service/dsp/dsp_dsp.cpp | ||||||
|     hle/service/dsp/dsp_dsp.h |     hle/service/dsp/dsp_dsp.h | ||||||
|     hle/service/err_f.cpp |     hle/service/err/err_f.cpp | ||||||
|     hle/service/err_f.h |     hle/service/err/err_f.h | ||||||
|     hle/service/frd/frd.cpp |     hle/service/frd/frd.cpp | ||||||
|     hle/service/frd/frd.h |     hle/service/frd/frd.h | ||||||
|     hle/service/frd/frd_a.cpp |     hle/service/frd/frd_a.cpp | ||||||
|  | @ -307,8 +309,8 @@ add_library(citra_core STATIC | ||||||
|     hle/service/hid/hid_spvr.h |     hle/service/hid/hid_spvr.h | ||||||
|     hle/service/hid/hid_user.cpp |     hle/service/hid/hid_user.cpp | ||||||
|     hle/service/hid/hid_user.h |     hle/service/hid/hid_user.h | ||||||
|     hle/service/http_c.cpp |     hle/service/http/http_c.cpp | ||||||
|     hle/service/http_c.h |     hle/service/http/http_c.h | ||||||
|     hle/service/ir/extra_hid.cpp |     hle/service/ir/extra_hid.cpp | ||||||
|     hle/service/ir/extra_hid.h |     hle/service/ir/extra_hid.h | ||||||
|     hle/service/ir/ir.cpp |     hle/service/ir/ir.cpp | ||||||
|  | @ -323,8 +325,8 @@ add_library(citra_core STATIC | ||||||
|     hle/service/ldr_ro/cro_helper.h |     hle/service/ldr_ro/cro_helper.h | ||||||
|     hle/service/ldr_ro/ldr_ro.cpp |     hle/service/ldr_ro/ldr_ro.cpp | ||||||
|     hle/service/ldr_ro/ldr_ro.h |     hle/service/ldr_ro/ldr_ro.h | ||||||
|     hle/service/mic_u.cpp |     hle/service/mic/mic_u.cpp | ||||||
|     hle/service/mic_u.h |     hle/service/mic/mic_u.h | ||||||
|     hle/service/mvd/mvd.cpp |     hle/service/mvd/mvd.cpp | ||||||
|     hle/service/mvd/mvd.h |     hle/service/mvd/mvd.h | ||||||
|     hle/service/mvd/mvd_std.cpp |     hle/service/mvd/mvd_std.cpp | ||||||
|  | @ -421,12 +423,10 @@ add_library(citra_core STATIC | ||||||
|     hle/service/sm/sm.h |     hle/service/sm/sm.h | ||||||
|     hle/service/sm/srv.cpp |     hle/service/sm/srv.cpp | ||||||
|     hle/service/sm/srv.h |     hle/service/sm/srv.h | ||||||
|     hle/service/soc_u.cpp |     hle/service/soc/soc_u.cpp | ||||||
|     hle/service/soc_u.h |     hle/service/soc/soc_u.h | ||||||
|     hle/service/ssl_c.cpp |     hle/service/ssl/ssl_c.cpp | ||||||
|     hle/service/ssl_c.h |     hle/service/ssl/ssl_c.h | ||||||
|     hle/service/y2r_u.cpp |  | ||||||
|     hle/service/y2r_u.h |  | ||||||
|     hw/aes/arithmetic128.cpp |     hw/aes/arithmetic128.cpp | ||||||
|     hw/aes/arithmetic128.h |     hw/aes/arithmetic128.h | ||||||
|     hw/aes/ccm.cpp |     hw/aes/ccm.cpp | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/hle/service/gsp/gsp.h" | #include "core/hle/service/gsp/gsp.h" | ||||||
| #include "core/hle/service/ir/ir_rst.h" | #include "core/hle/service/ir/ir_rst.h" | ||||||
| #include "core/hle/service/mic_u.h" | #include "core/hle/service/mic/mic_u.h" | ||||||
| #include "core/hle/service/plgldr/plgldr.h" | #include "core/hle/service/plgldr/plgldr.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| #include "core/hle/service/sm/sm.h" | #include "core/hle/service/sm/sm.h" | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| #include "core/hle/service/ac/ac.h" | #include "core/hle/service/ac/ac.h" | ||||||
| #include "core/hle/service/ac/ac_i.h" | #include "core/hle/service/ac/ac_i.h" | ||||||
| #include "core/hle/service/ac/ac_u.h" | #include "core/hle/service/ac/ac_u.h" | ||||||
| #include "core/hle/service/soc_u.h" | #include "core/hle/service/soc/soc_u.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
| namespace Service::AC { | namespace Service::AC { | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/service/y2r_u.h" | #include "core/hle/service/cam/y2r_u.h" | ||||||
| #include "core/hw/y2r.h" | #include "core/hw/y2r.h" | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::Y2R::Y2R_U) | SERVICE_CONSTRUCT_IMPL(Service::Y2R::Y2R_U) | ||||||
|  | @ -14,7 +14,7 @@ | ||||||
| #include "core/hle/ipc.h" | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/err_f.h" | #include "core/hle/service/err/err_f.h" | ||||||
| #undef exception_info // We use 'exception_info' as a plain identifier, but MSVC defines this in one
 | #undef exception_info // We use 'exception_info' as a plain identifier, but MSVC defines this in one
 | ||||||
|                       // of its many headers.
 |                       // of its many headers.
 | ||||||
| 
 | 
 | ||||||
|  | @ -15,7 +15,7 @@ | ||||||
| #include "core/hle/kernel/ipc.h" | #include "core/hle/kernel/ipc.h" | ||||||
| #include "core/hle/romfs.h" | #include "core/hle/romfs.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/hle/service/http_c.h" | #include "core/hle/service/http/http_c.h" | ||||||
| #include "core/hw/aes/key.h" | #include "core/hw/aes/key.h" | ||||||
| 
 | 
 | ||||||
| SERIALIZE_EXPORT_IMPL(Service::HTTP::HTTP_C) | SERIALIZE_EXPORT_IMPL(Service::HTTP::HTTP_C) | ||||||
|  | @ -55,11 +55,31 @@ const ResultCode ERROR_WRONG_CERT_HANDLE = // 0xD8A0A0C9 | ||||||
| const ResultCode ERROR_CERT_ALREADY_SET = // 0xD8A0A03D
 | const ResultCode ERROR_CERT_ALREADY_SET = // 0xD8A0A03D
 | ||||||
|     ResultCode(61, ErrorModule::HTTP, ErrorSummary::InvalidState, ErrorLevel::Permanent); |     ResultCode(61, ErrorModule::HTTP, ErrorSummary::InvalidState, ErrorLevel::Permanent); | ||||||
| 
 | 
 | ||||||
|  | static std::pair<std::string, std::string> SplitUrl(const std::string& url) { | ||||||
|  |     const std::string prefix = "://"; | ||||||
|  |     const auto scheme_end = url.find(prefix); | ||||||
|  |     const auto prefix_end = scheme_end == std::string::npos ? 0 : scheme_end + prefix.length(); | ||||||
|  | 
 | ||||||
|  |     const auto path_index = url.find("/", prefix_end); | ||||||
|  |     std::string host; | ||||||
|  |     std::string path; | ||||||
|  |     if (path_index == std::string::npos) { | ||||||
|  |         // If no path is specified after the host, set it to "/"
 | ||||||
|  |         host = url; | ||||||
|  |         path = "/"; | ||||||
|  |     } else { | ||||||
|  |         host = url.substr(0, path_index); | ||||||
|  |         path = url.substr(path_index); | ||||||
|  |     } | ||||||
|  |     return std::make_pair(host, path); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Context::MakeRequest() { | void Context::MakeRequest() { | ||||||
|     ASSERT(state == RequestState::NotStarted); |     ASSERT(state == RequestState::NotStarted); | ||||||
| 
 | 
 | ||||||
| #ifdef ENABLE_WEB_SERVICE | #ifdef ENABLE_WEB_SERVICE | ||||||
|     std::unique_ptr<httplib::Client> client = std::make_unique<httplib::Client>(url.c_str()); |     const auto& [host, path] = SplitUrl(url); | ||||||
|  |     const auto client = std::make_unique<httplib::Client>(host); | ||||||
|     SSL_CTX* ctx = client->ssl_context(); |     SSL_CTX* ctx = client->ssl_context(); | ||||||
|     if (ctx) { |     if (ctx) { | ||||||
|         if (auto client_cert = ssl_config.client_cert_ctx.lock()) { |         if (auto client_cert = ssl_config.client_cert_ctx.lock()) { | ||||||
|  | @ -87,7 +107,7 @@ void Context::MakeRequest() { | ||||||
|     httplib::Request request; |     httplib::Request request; | ||||||
|     httplib::Error error; |     httplib::Error error; | ||||||
|     request.method = request_method_strings.at(method); |     request.method = request_method_strings.at(method); | ||||||
|     request.path = url; |     request.path = path; | ||||||
|     // TODO(B3N30): Add post data body
 |     // TODO(B3N30): Add post data body
 | ||||||
|     request.progress = [this](u64 current, u64 total) -> bool { |     request.progress = [this](u64 current, u64 total) -> bool { | ||||||
|         // TODO(B3N30): Is there a state that shows response header are available
 |         // TODO(B3N30): Is there a state that shows response header are available
 | ||||||
|  | @ -101,7 +121,7 @@ void Context::MakeRequest() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!client->send(request, response, error)) { |     if (!client->send(request, response, error)) { | ||||||
|         LOG_ERROR(Service_HTTP, "Request failed: {}", error); |         LOG_ERROR(Service_HTTP, "Request failed: {}: {}", error, httplib::to_string(error)); | ||||||
|         state = RequestState::TimedOut; |         state = RequestState::TimedOut; | ||||||
|     } else { |     } else { | ||||||
|         LOG_DEBUG(Service_HTTP, "Request successful"); |         LOG_DEBUG(Service_HTTP, "Request successful"); | ||||||
|  | @ -185,33 +205,7 @@ void HTTP_C::BeginRequest(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called, context_id={}", context_handle); |     LOG_WARNING(Service_HTTP, "(STUBBED) called, context_id={}", context_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|     ASSERT(session_data); |  | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to make a request on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // This command can only be called with a bound context
 |  | ||||||
|     if (!session_data->current_http_context) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to make a request without a bound context"); |  | ||||||
| 
 |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, |  | ||||||
|                            ErrorSummary::Internal, ErrorLevel::Permanent)); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (session_data->current_http_context != context_handle) { |  | ||||||
|         LOG_ERROR( |  | ||||||
|             Service_HTTP, |  | ||||||
|             "Tried to make a request on a mismatched session input context={} session context={}", |  | ||||||
|             context_handle, *session_data->current_http_context); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -238,33 +232,7 @@ void HTTP_C::BeginRequestAsync(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called, context_id={}", context_handle); |     LOG_WARNING(Service_HTTP, "(STUBBED) called, context_id={}", context_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|     ASSERT(session_data); |  | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to make a request on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // This command can only be called with a bound context
 |  | ||||||
|     if (!session_data->current_http_context) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to make a request without a bound context"); |  | ||||||
| 
 |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, |  | ||||||
|                            ErrorSummary::Internal, ErrorLevel::Permanent)); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (session_data->current_http_context != context_handle) { |  | ||||||
|         LOG_ERROR( |  | ||||||
|             Service_HTTP, |  | ||||||
|             "Tried to make a request on a mismatched session input context={} session context={}", |  | ||||||
|             context_handle, *session_data->current_http_context); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -285,6 +253,44 @@ void HTTP_C::BeginRequestAsync(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void HTTP_C::ReceiveData(Kernel::HLERequestContext& ctx) { | ||||||
|  |     ReceiveDataImpl(ctx, false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HTTP_C::ReceiveDataTimeout(Kernel::HLERequestContext& ctx) { | ||||||
|  |     ReceiveDataImpl(ctx, true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HTTP_C::ReceiveDataImpl(Kernel::HLERequestContext& ctx, bool timeout) { | ||||||
|  |     IPC::RequestParser rp(ctx); | ||||||
|  |     const Context::Handle context_handle = rp.Pop<u32>(); | ||||||
|  |     [[maybe_unused]] const u32 buffer_size = rp.Pop<u32>(); | ||||||
|  |     u64 timeout_nanos = 0; | ||||||
|  |     if (timeout) { | ||||||
|  |         timeout_nanos = rp.Pop<u64>(); | ||||||
|  |         LOG_WARNING(Service_HTTP, "(STUBBED) called, timeout={}", timeout_nanos); | ||||||
|  |     } else { | ||||||
|  |         LOG_WARNING(Service_HTTP, "(STUBBED) called"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto itr = contexts.find(context_handle); | ||||||
|  |     ASSERT(itr != contexts.end()); | ||||||
|  | 
 | ||||||
|  |     if (timeout) { | ||||||
|  |         itr->second.request_future.wait_for(std::chrono::nanoseconds(timeout_nanos)); | ||||||
|  |         // TODO (flTobi): Return error on timeout
 | ||||||
|  |     } else { | ||||||
|  |         itr->second.request_future.wait(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     const u32 url_size = rp.Pop<u32>(); |     const u32 url_size = rp.Pop<u32>(); | ||||||
|  | @ -297,14 +303,8 @@ void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_DEBUG(Service_HTTP, "called, url_size={}, url={}, method={}", url_size, url, method); |     LOG_DEBUG(Service_HTTP, "called, url_size={}, url={}, method={}", url_size, url, method); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     auto* session_data = EnsureSessionInitialized(ctx, rp); | ||||||
|     ASSERT(session_data); |     if (!session_data) { | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to create a context on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         rb.PushMappedBuffer(buffer); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -365,13 +365,8 @@ void HTTP_C::CloseContext(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called, handle={}", context_handle); |     LOG_WARNING(Service_HTTP, "(STUBBED) called, handle={}", context_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     auto* session_data = EnsureSessionInitialized(ctx, rp); | ||||||
|     ASSERT(session_data); |     if (!session_data) { | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to close a context on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -416,36 +411,7 @@ void HTTP_C::AddRequestHeader(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, |     LOG_DEBUG(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, | ||||||
|               context_handle); |               context_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|     ASSERT(session_data); |  | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to add a request header on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // This command can only be called with a bound context
 |  | ||||||
|     if (!session_data->current_http_context) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Command called without a bound context"); |  | ||||||
| 
 |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, |  | ||||||
|                            ErrorSummary::Internal, ErrorLevel::Permanent)); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (session_data->current_http_context != context_handle) { |  | ||||||
|         LOG_ERROR(Service_HTTP, |  | ||||||
|                   "Tried to add a request header on a mismatched session input context={} session " |  | ||||||
|                   "context={}", |  | ||||||
|                   context_handle, *session_data->current_http_context); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -492,36 +458,7 @@ void HTTP_C::AddPostDataAscii(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, |     LOG_DEBUG(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, | ||||||
|               context_handle); |               context_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|     ASSERT(session_data); |  | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to add post data on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // This command can only be called with a bound context
 |  | ||||||
|     if (!session_data->current_http_context) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Command called without a bound context"); |  | ||||||
| 
 |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, |  | ||||||
|                            ErrorSummary::Internal, ErrorLevel::Permanent)); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (session_data->current_http_context != context_handle) { |  | ||||||
|         LOG_ERROR(Service_HTTP, |  | ||||||
|                   "Tried to add post data on a mismatched session input context={} session " |  | ||||||
|                   "context={}", |  | ||||||
|                   context_handle, *session_data->current_http_context); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         rb.PushMappedBuffer(value_buffer); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -549,6 +486,46 @@ void HTTP_C::AddPostDataAscii(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.PushMappedBuffer(value_buffer); |     rb.PushMappedBuffer(value_buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void HTTP_C::GetResponseStatusCode(Kernel::HLERequestContext& ctx) { | ||||||
|  |     GetResponseStatusCodeImpl(ctx, false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HTTP_C::GetResponseStatusCodeTimeout(Kernel::HLERequestContext& ctx) { | ||||||
|  |     GetResponseStatusCodeImpl(ctx, true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HTTP_C::GetResponseStatusCodeImpl(Kernel::HLERequestContext& ctx, bool timeout) { | ||||||
|  |     IPC::RequestParser rp(ctx); | ||||||
|  |     const Context::Handle context_handle = rp.Pop<u32>(); | ||||||
|  |     u64 timeout_nanos = 0; | ||||||
|  |     if (timeout) { | ||||||
|  |         timeout_nanos = rp.Pop<u64>(); | ||||||
|  |         LOG_INFO(Service_HTTP, "called, timeout={}", timeout_nanos); | ||||||
|  |     } else { | ||||||
|  |         LOG_INFO(Service_HTTP, "called"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto itr = contexts.find(context_handle); | ||||||
|  |     ASSERT(itr != contexts.end()); | ||||||
|  | 
 | ||||||
|  |     if (timeout) { | ||||||
|  |         itr->second.request_future.wait_for(std::chrono::nanoseconds(timeout)); | ||||||
|  |         // TODO (flTobi): Return error on timeout
 | ||||||
|  |     } else { | ||||||
|  |         itr->second.request_future.wait(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const u32 response_code = itr->second.response.status; | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.Push(response_code); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void HTTP_C::SetClientCertContext(Kernel::HLERequestContext& ctx) { | void HTTP_C::SetClientCertContext(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     const u32 context_handle = rp.Pop<u32>(); |     const u32 context_handle = rp.Pop<u32>(); | ||||||
|  | @ -557,32 +534,7 @@ void HTTP_C::SetClientCertContext(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_HTTP, "called with context_handle={} client_cert_handle={}", context_handle, |     LOG_DEBUG(Service_HTTP, "called with context_handle={} client_cert_handle={}", context_handle, | ||||||
|               client_cert_handle); |               client_cert_handle); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     if (!PerformStateChecks(ctx, rp, context_handle)) { | ||||||
|     ASSERT(session_data); |  | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to set client cert on an uninitialized session"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // This command can only be called with a bound context
 |  | ||||||
|     if (!session_data->current_http_context) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Tried to set client cert without a bound context"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, |  | ||||||
|                            ErrorSummary::Internal, ErrorLevel::Permanent)); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (session_data->current_http_context != context_handle) { |  | ||||||
|         LOG_ERROR(Service_HTTP, |  | ||||||
|                   "Tried to add set client cert on a mismatched session input context={} session " |  | ||||||
|                   "context={}", |  | ||||||
|                   context_handle, *session_data->current_http_context); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -683,13 +635,8 @@ void HTTP_C::OpenDefaultClientCertContext(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_DEBUG(Service_HTTP, "called, cert_id={} cert_handle={}", cert_id, client_certs_counter); |     LOG_DEBUG(Service_HTTP, "called, cert_id={} cert_handle={}", cert_id, client_certs_counter); | ||||||
| 
 | 
 | ||||||
|     auto* session_data = GetSessionData(ctx.Session()); |     auto* session_data = EnsureSessionInitialized(ctx, rp); | ||||||
|     ASSERT(session_data); |     if (!session_data) { | ||||||
| 
 |  | ||||||
|     if (!session_data->initialized) { |  | ||||||
|         LOG_ERROR(Service_HTTP, "Command called without Initialize"); |  | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |  | ||||||
|         rb.Push(ERROR_STATE_ERROR); |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -792,6 +739,85 @@ void HTTP_C::Finalize(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called"); |     LOG_WARNING(Service_HTTP, "(STUBBED) called"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void HTTP_C::GetDownloadSizeState(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx); | ||||||
|  |     const Context::Handle context_handle = rp.Pop<u32>(); | ||||||
|  | 
 | ||||||
|  |     LOG_INFO(Service_HTTP, "called"); | ||||||
|  | 
 | ||||||
|  |     const auto* session_data = EnsureSessionInitialized(ctx, rp); | ||||||
|  |     if (!session_data) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto itr = contexts.find(context_handle); | ||||||
|  |     ASSERT(itr != contexts.end()); | ||||||
|  | 
 | ||||||
|  |     // On the real console, the current downloaded progress and the total size of the content gets
 | ||||||
|  |     // returned. Since we do not support chunked downloads on the host, always return the content
 | ||||||
|  |     // length if the download is complete and 0 otherwise.
 | ||||||
|  |     u32 content_length = 0; | ||||||
|  |     const bool is_complete = itr->second.request_future.wait_for(std::chrono::milliseconds(0)) == | ||||||
|  |                              std::future_status::ready; | ||||||
|  |     if (is_complete) { | ||||||
|  |         const auto& headers = itr->second.response.headers; | ||||||
|  |         const auto& it = headers.find("Content-Length"); | ||||||
|  |         if (it != headers.end()) { | ||||||
|  |             content_length = std::stoi(it->second); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.Push(content_length); | ||||||
|  |     rb.Push(content_length); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SessionData* HTTP_C::EnsureSessionInitialized(Kernel::HLERequestContext& ctx, | ||||||
|  |                                               IPC::RequestParser rp) { | ||||||
|  |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|  |     ASSERT(session_data); | ||||||
|  | 
 | ||||||
|  |     if (!session_data->initialized) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to make a request on an uninitialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         return nullptr; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return session_data; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool HTTP_C::PerformStateChecks(Kernel::HLERequestContext& ctx, IPC::RequestParser rp, | ||||||
|  |                                 Context::Handle context_handle) { | ||||||
|  |     const auto* session_data = EnsureSessionInitialized(ctx, rp); | ||||||
|  |     if (!session_data) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // This command can only be called with a bound context
 | ||||||
|  |     if (!session_data->current_http_context) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to make a request without a bound context"); | ||||||
|  | 
 | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, | ||||||
|  |                            ErrorSummary::Internal, ErrorLevel::Permanent)); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (session_data->current_http_context != context_handle) { | ||||||
|  |         LOG_ERROR( | ||||||
|  |             Service_HTTP, | ||||||
|  |             "Tried to make a request on a mismatched session input context={} session context={}", | ||||||
|  |             context_handle, *session_data->current_http_context); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void HTTP_C::DecryptClCertA() { | void HTTP_C::DecryptClCertA() { | ||||||
|     static constexpr u32 iv_length = 16; |     static constexpr u32 iv_length = 16; | ||||||
| 
 | 
 | ||||||
|  | @ -875,13 +901,13 @@ HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | ||||||
|         {0x0003, &HTTP_C::CloseContext, "CloseContext"}, |         {0x0003, &HTTP_C::CloseContext, "CloseContext"}, | ||||||
|         {0x0004, nullptr, "CancelConnection"}, |         {0x0004, nullptr, "CancelConnection"}, | ||||||
|         {0x0005, nullptr, "GetRequestState"}, |         {0x0005, nullptr, "GetRequestState"}, | ||||||
|         {0x0006, nullptr, "GetDownloadSizeState"}, |         {0x0006, &HTTP_C::GetDownloadSizeState, "GetDownloadSizeState"}, | ||||||
|         {0x0007, nullptr, "GetRequestError"}, |         {0x0007, nullptr, "GetRequestError"}, | ||||||
|         {0x0008, &HTTP_C::InitializeConnectionSession, "InitializeConnectionSession"}, |         {0x0008, &HTTP_C::InitializeConnectionSession, "InitializeConnectionSession"}, | ||||||
|         {0x0009, &HTTP_C::BeginRequest, "BeginRequest"}, |         {0x0009, &HTTP_C::BeginRequest, "BeginRequest"}, | ||||||
|         {0x000A, &HTTP_C::BeginRequestAsync, "BeginRequestAsync"}, |         {0x000A, &HTTP_C::BeginRequestAsync, "BeginRequestAsync"}, | ||||||
|         {0x000B, nullptr, "ReceiveData"}, |         {0x000B, &HTTP_C::ReceiveData, "ReceiveData"}, | ||||||
|         {0x000C, nullptr, "ReceiveDataTimeout"}, |         {0x000C, &HTTP_C::ReceiveDataTimeout, "ReceiveDataTimeout"}, | ||||||
|         {0x000D, nullptr, "SetProxy"}, |         {0x000D, nullptr, "SetProxy"}, | ||||||
|         {0x000E, nullptr, "SetProxyDefault"}, |         {0x000E, nullptr, "SetProxyDefault"}, | ||||||
|         {0x000F, nullptr, "SetBasicAuthorization"}, |         {0x000F, nullptr, "SetBasicAuthorization"}, | ||||||
|  | @ -903,8 +929,8 @@ HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | ||||||
|         {0x001F, nullptr, "GetResponseHeaderTimeout"}, |         {0x001F, nullptr, "GetResponseHeaderTimeout"}, | ||||||
|         {0x0020, nullptr, "GetResponseData"}, |         {0x0020, nullptr, "GetResponseData"}, | ||||||
|         {0x0021, nullptr, "GetResponseDataTimeout"}, |         {0x0021, nullptr, "GetResponseDataTimeout"}, | ||||||
|         {0x0022, nullptr, "GetResponseStatusCode"}, |         {0x0022, &HTTP_C::GetResponseStatusCode, "GetResponseStatusCode"}, | ||||||
|         {0x0023, nullptr, "GetResponseStatusCodeTimeout"}, |         {0x0023, &HTTP_C::GetResponseStatusCodeTimeout, "GetResponseStatusCodeTimeout"}, | ||||||
|         {0x0024, nullptr, "AddTrustedRootCA"}, |         {0x0024, nullptr, "AddTrustedRootCA"}, | ||||||
|         {0x0025, nullptr, "AddDefaultCert"}, |         {0x0025, nullptr, "AddDefaultCert"}, | ||||||
|         {0x0026, nullptr, "SelectRootCertChain"}, |         {0x0026, nullptr, "SelectRootCertChain"}, | ||||||
|  | @ -30,6 +30,10 @@ namespace Core { | ||||||
| class System; | class System; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace IPC { | ||||||
|  | class RequestParser; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace Service::HTTP { | namespace Service::HTTP { | ||||||
| 
 | 
 | ||||||
| enum class RequestMethod : u8 { | enum class RequestMethod : u8 { | ||||||
|  | @ -288,6 +292,17 @@ private: | ||||||
|      */ |      */ | ||||||
|     void CloseContext(Kernel::HLERequestContext& ctx); |     void CloseContext(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::GetDownloadSizeState service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : Context handle | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      *      2 : Total content data downloaded so far | ||||||
|  |      *      3 : Total content size from the "Content-Length" response header | ||||||
|  |      */ | ||||||
|  |     void GetDownloadSizeState(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * HTTP_C::InitializeConnectionSession service function |      * HTTP_C::InitializeConnectionSession service function | ||||||
|      *  Inputs: |      *  Inputs: | ||||||
|  | @ -317,6 +332,37 @@ private: | ||||||
|      */ |      */ | ||||||
|     void BeginRequestAsync(Kernel::HLERequestContext& ctx); |     void BeginRequestAsync(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::ReceiveData service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : Context handle | ||||||
|  |      *      2 : Buffer size | ||||||
|  |      *      3 : (OutSize<<4) | 12 | ||||||
|  |      *      4 : Output data pointer | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      */ | ||||||
|  |     void ReceiveData(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::ReceiveDataTimeout service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : Context handle | ||||||
|  |      *      2 : Buffer size | ||||||
|  |      *    3-4 : u64 nanoseconds delay | ||||||
|  |      *      5 : (OutSize<<4) | 12 | ||||||
|  |      *      6 : Output data pointer | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      */ | ||||||
|  |     void ReceiveDataTimeout(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * ReceiveDataImpl: | ||||||
|  |      *  Implements ReceiveData and ReceiveDataTimeout service functions | ||||||
|  |      */ | ||||||
|  |     void ReceiveDataImpl(Kernel::HLERequestContext& ctx, bool timeout); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * HTTP_C::AddRequestHeader service function |      * HTTP_C::AddRequestHeader service function | ||||||
|      *  Inputs: |      *  Inputs: | ||||||
|  | @ -347,6 +393,33 @@ private: | ||||||
|      */ |      */ | ||||||
|     void AddPostDataAscii(Kernel::HLERequestContext& ctx); |     void AddPostDataAscii(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::GetResponseStatusCode service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : Context handle | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      *      2 : HTTP response status code | ||||||
|  |      */ | ||||||
|  |     void GetResponseStatusCode(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::GetResponseStatusCode service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : Context handle | ||||||
|  |      *    2-3 : u64 nanoseconds timeout | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      *      2 : HTTP response status code | ||||||
|  |      */ | ||||||
|  |     void GetResponseStatusCodeTimeout(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * GetResponseStatusCodeImpl: | ||||||
|  |      *  Implements GetResponseStatusCode and GetResponseStatusCodeTimeout service functions | ||||||
|  |      */ | ||||||
|  |     void GetResponseStatusCodeImpl(Kernel::HLERequestContext& ctx, bool timeout); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * HTTP_C::SetClientCertContext service function |      * HTTP_C::SetClientCertContext service function | ||||||
|      *  Inputs: |      *  Inputs: | ||||||
|  | @ -408,6 +481,12 @@ private: | ||||||
|      */ |      */ | ||||||
|     void Finalize(Kernel::HLERequestContext& ctx); |     void Finalize(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |     [[nodiscard]] SessionData* EnsureSessionInitialized(Kernel::HLERequestContext& ctx, | ||||||
|  |                                                         IPC::RequestParser rp); | ||||||
|  | 
 | ||||||
|  |     [[nodiscard]] bool PerformStateChecks(Kernel::HLERequestContext& ctx, IPC::RequestParser rp, | ||||||
|  |                                           Context::Handle context_handle); | ||||||
|  | 
 | ||||||
|     void DecryptClCertA(); |     void DecryptClCertA(); | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<Kernel::SharedMemory> shared_memory = nullptr; |     std::shared_ptr<Kernel::SharedMemory> shared_memory = nullptr; | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| #include "core/hle/kernel/handle_table.h" | #include "core/hle/kernel/handle_table.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
| #include "core/hle/kernel/shared_memory.h" | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/service/mic_u.h" | #include "core/hle/service/mic/mic_u.h" | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U) | SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U) | ||||||
| SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U) | SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U) | ||||||
|  | @ -19,22 +19,23 @@ | ||||||
| #include "core/hle/service/apt/apt.h" | #include "core/hle/service/apt/apt.h" | ||||||
| #include "core/hle/service/boss/boss.h" | #include "core/hle/service/boss/boss.h" | ||||||
| #include "core/hle/service/cam/cam.h" | #include "core/hle/service/cam/cam.h" | ||||||
|  | #include "core/hle/service/cam/y2r_u.h" | ||||||
| #include "core/hle/service/cecd/cecd.h" | #include "core/hle/service/cecd/cecd.h" | ||||||
| #include "core/hle/service/cfg/cfg.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
| #include "core/hle/service/csnd/csnd_snd.h" | #include "core/hle/service/csnd/csnd_snd.h" | ||||||
| #include "core/hle/service/dlp/dlp.h" | #include "core/hle/service/dlp/dlp.h" | ||||||
| #include "core/hle/service/dsp/dsp_dsp.h" | #include "core/hle/service/dsp/dsp_dsp.h" | ||||||
| #include "core/hle/service/err_f.h" | #include "core/hle/service/err/err_f.h" | ||||||
| #include "core/hle/service/frd/frd.h" | #include "core/hle/service/frd/frd.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/hle/service/fs/fs_user.h" | #include "core/hle/service/fs/fs_user.h" | ||||||
| #include "core/hle/service/gsp/gsp.h" | #include "core/hle/service/gsp/gsp.h" | ||||||
| #include "core/hle/service/gsp/gsp_lcd.h" | #include "core/hle/service/gsp/gsp_lcd.h" | ||||||
| #include "core/hle/service/hid/hid.h" | #include "core/hle/service/hid/hid.h" | ||||||
| #include "core/hle/service/http_c.h" | #include "core/hle/service/http/http_c.h" | ||||||
| #include "core/hle/service/ir/ir.h" | #include "core/hle/service/ir/ir.h" | ||||||
| #include "core/hle/service/ldr_ro/ldr_ro.h" | #include "core/hle/service/ldr_ro/ldr_ro.h" | ||||||
| #include "core/hle/service/mic_u.h" | #include "core/hle/service/mic/mic_u.h" | ||||||
| #include "core/hle/service/mvd/mvd.h" | #include "core/hle/service/mvd/mvd.h" | ||||||
| #include "core/hle/service/ndm/ndm_u.h" | #include "core/hle/service/ndm/ndm_u.h" | ||||||
| #include "core/hle/service/news/news.h" | #include "core/hle/service/news/news.h" | ||||||
|  | @ -50,9 +51,8 @@ | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| #include "core/hle/service/sm/sm.h" | #include "core/hle/service/sm/sm.h" | ||||||
| #include "core/hle/service/sm/srv.h" | #include "core/hle/service/sm/srv.h" | ||||||
| #include "core/hle/service/soc_u.h" | #include "core/hle/service/soc/soc_u.h" | ||||||
| #include "core/hle/service/ssl_c.h" | #include "core/hle/service/ssl/ssl_c.h" | ||||||
| #include "core/hle/service/y2r_u.h" |  | ||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/shared_memory.h" | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/soc_u.h" | #include "core/hle/service/soc/soc_u.h" | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| #include <winsock2.h> | #include <winsock2.h> | ||||||
|  | @ -868,7 +868,7 @@ void SOC_U::Accept(Kernel::HLERequestContext& ctx) { | ||||||
|         rb.Push(ERR_INVALID_HANDLE); |         rb.Push(ERR_INVALID_HANDLE); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     [[maybe_unused]] const auto max_addr_len = static_cast<socklen_t>(rp.Pop<u32>()); |     const auto max_addr_len = rp.Pop<u32>(); | ||||||
|     rp.PopPID(); |     rp.PopPID(); | ||||||
|     sockaddr addr; |     sockaddr addr; | ||||||
|     socklen_t addr_len = sizeof(addr); |     socklen_t addr_len = sizeof(addr); | ||||||
|  | @ -889,6 +889,11 @@ void SOC_U::Accept(Kernel::HLERequestContext& ctx) { | ||||||
|         std::memcpy(ctr_addr_buf.data(), &ctr_addr, sizeof(ctr_addr)); |         std::memcpy(ctr_addr_buf.data(), &ctr_addr, sizeof(ctr_addr)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (ctr_addr_buf.size() > max_addr_len) { | ||||||
|  |         LOG_WARNING(Frontend, "CTRSockAddr is too long, truncating data."); | ||||||
|  |         ctr_addr_buf.resize(max_addr_len); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push(ret); |     rb.Push(ret); | ||||||
|  | @ -1264,7 +1269,7 @@ void SOC_U::GetSockName(Kernel::HLERequestContext& ctx) { | ||||||
|         rb.Push(ERR_INVALID_HANDLE); |         rb.Push(ERR_INVALID_HANDLE); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     [[maybe_unused]] const auto max_addr_len = rp.Pop<u32>(); |     const auto max_addr_len = rp.Pop<u32>(); | ||||||
|     rp.PopPID(); |     rp.PopPID(); | ||||||
| 
 | 
 | ||||||
|     sockaddr dest_addr; |     sockaddr dest_addr; | ||||||
|  | @ -1278,6 +1283,11 @@ void SOC_U::GetSockName(Kernel::HLERequestContext& ctx) { | ||||||
|     if (ret != 0) |     if (ret != 0) | ||||||
|         ret = TranslateError(GET_ERRNO); |         ret = TranslateError(GET_ERRNO); | ||||||
| 
 | 
 | ||||||
|  |     if (dest_addr_buff.size() > max_addr_len) { | ||||||
|  |         LOG_WARNING(Frontend, "CTRSockAddr is too long, truncating data."); | ||||||
|  |         dest_addr_buff.resize(max_addr_len); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push(ret); |     rb.Push(ret); | ||||||
|  | @ -1358,7 +1368,7 @@ void SOC_U::GetPeerName(Kernel::HLERequestContext& ctx) { | ||||||
|         rb.Push(ERR_INVALID_HANDLE); |         rb.Push(ERR_INVALID_HANDLE); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     [[maybe_unused]] const auto max_addr_len = rp.Pop<u32>(); |     const auto max_addr_len = rp.Pop<u32>(); | ||||||
|     rp.PopPID(); |     rp.PopPID(); | ||||||
| 
 | 
 | ||||||
|     sockaddr dest_addr; |     sockaddr dest_addr; | ||||||
|  | @ -1374,6 +1384,11 @@ void SOC_U::GetPeerName(Kernel::HLERequestContext& ctx) { | ||||||
|         result = TranslateError(GET_ERRNO); |         result = TranslateError(GET_ERRNO); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (dest_addr_buff.size() > max_addr_len) { | ||||||
|  |         LOG_WARNING(Frontend, "CTRSockAddr is too long, truncating data."); | ||||||
|  |         dest_addr_buff.resize(max_addr_len); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push(result); |     rb.Push(result); | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/ipc.h" | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/service/ssl_c.h" | #include "core/hle/service/ssl/ssl_c.h" | ||||||
| 
 | 
 | ||||||
| SERIALIZE_EXPORT_IMPL(Service::SSL::SSL_C) | SERIALIZE_EXPORT_IMPL(Service::SSL::SSL_C) | ||||||
| namespace Service::SSL { | namespace Service::SSL { | ||||||
|  | @ -12,7 +12,7 @@ | ||||||
| #include "common/microprofileui.h" | #include "common/microprofileui.h" | ||||||
| #include "common/vector_math.h" | #include "common/vector_math.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/service/y2r_u.h" | #include "core/hle/service/cam/y2r_u.h" | ||||||
| #include "core/hw/y2r.h" | #include "core/hw/y2r.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue