diff --git a/libctru/include/3ds/services/sslc.h b/libctru/include/3ds/services/sslc.h index aa9b2f0..5971ea0 100644 --- a/libctru/include/3ds/services/sslc.h +++ b/libctru/include/3ds/services/sslc.h @@ -8,6 +8,7 @@ typedef struct { Handle servhandle; ///< Service handle. u32 sslchandle; ///< SSLC handle. + Handle sharedmem_handle; } sslcContext; typedef enum { @@ -198,3 +199,11 @@ Result sslcContextGetProtocolCipher(sslcContext *context, char *outprotocols, u3 */ Result sslcContextGetState(sslcContext *context, u32 *out); +/* + * @brief This initializes sharedmem for the specified context. + * @param context sslc context. + * @param buf Sharedmem buffer with address aligned to 0x1000-bytes. + * @param size Sharedmem size aligned to 0x1000-bytes. + */ +Result sslcContextInitSharedmem(sslcContext *context, u8 *buf, u32 size); + diff --git a/libctru/source/services/sslc.c b/libctru/source/services/sslc.c index bb2348f..721838e 100644 --- a/libctru/source/services/sslc.c +++ b/libctru/source/services/sslc.c @@ -361,10 +361,28 @@ static Result sslcipc_DestroyContext(sslcContext *context) return cmdbuf[1]; } +static Result sslcipc_ContextInitSharedmem(sslcContext *context, u32 size) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x1F,2,2); // 0x1F0082 + cmdbuf[1]=context->sslchandle; + cmdbuf[2]=size; + cmdbuf[3]=IPC_Desc_SharedHandles(1); + cmdbuf[4]=context->sharedmem_handle; + + Result ret=0; + if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret; + + return cmdbuf[1]; +} + Result sslcCreateContext(sslcContext *context, int sockfd, u32 input_opt, char *hostname) { Result ret=0; + memset(context, 0, sizeof(sslcContext)); + ret = SOCU_AddGlobalSocket(sockfd); if(R_FAILED(ret))return ret; @@ -399,6 +417,10 @@ Result sslcDestroyContext(sslcContext *context) svcCloseHandle(context->servhandle); ret = sslcipc_DestroyContext(context); + if(context->sharedmem_handle)svcCloseHandle(context->sharedmem_handle); + + memset(context, 0, sizeof(sslcContext)); + return ret; } @@ -442,3 +464,21 @@ Result sslcContextClearOpt(sslcContext *context, u32 bitmask) return sslcipc_ContextSetValue(context, 3, bitmask); } +Result sslcContextInitSharedmem(sslcContext *context, u8 *buf, u32 size) +{ + Result ret=0; + + ret = svcCreateMemoryBlock(&context->sharedmem_handle, (u32)buf, size, 1, 3); + if(R_FAILED(ret))return ret; + + ret = sslcipc_ContextInitSharedmem(context, size); + + if(R_FAILED(ret)) + { + svcCloseHandle(context->sharedmem_handle); + context->sharedmem_handle = 0; + } + + return ret; +} +