diff --git a/doc/strings.md b/doc/strings.md index 5d3ce1b55..319e279f7 100644 --- a/doc/strings.md +++ b/doc/strings.md @@ -79,26 +79,29 @@ The following functions are provided to convert `cc_string` strings into operati ### cc_string -> Windows string -`Platform_EncodeUtf16` converts a `cc_string` into a null terminated `WCHAR` string +`Platform_EncodeString` converts a `cc_string` into a null terminated `WCHAR` and `CHAR` string #### Example ```C void SetWorkingDir(cc_string* title) { - WCHAR buffer[NATIVE_STR_LEN]; - Platform_EncodeUtf16(buffer, title); - SetCurrentDirectoryW(buffer); + cc_winstring str; + Platform_EncodeUtf16(&str, title); + SetCurrentDirectoryW(str.uni); + + // it's recommended that you DON'T use the ansi format whenever possible + //SetCurrentDirectoryA(str.ansi); } ``` -### cc_string -> Unix string +### cc_string -> UTF8 string -`Platform_EncodeUtf8` converts a `cc_string` into a null terminated UTF8-encoded `char*` string +`String_EncodeUtf8` converts a `cc_string` into a null terminated UTF8-encoded `char*` string #### Example ```C void SetWorkingDir(cc_string* title) { char buffer[NATIVE_STR_LEN]; - Platform_EncodeUtf8(buffer, title); + String_EncodeUtf8(buffer, title); chdir(buffer); } ``` diff --git a/src/Game.c b/src/Game.c index a2a868583..0459b70e2 100644 --- a/src/Game.c +++ b/src/Game.c @@ -665,7 +665,7 @@ cc_bool Game_ShouldClose(void) { /* Try to intercept Ctrl+W or Cmd+W for multiplayer */ if (Input_IsCtrlPressed() || Input_IsWinPressed()) return false; /* Also try to intercept mouse back button (Mouse4) */ - return !Input_Pressed[CCMOUSE_X1]; + return !Input.Pressed[CCMOUSE_X1]; } #else static void Game_RunLoop(void) { diff --git a/src/Platform.h b/src/Platform.h index 5e5ac685c..1ccf001d1 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -46,10 +46,6 @@ typedef struct cc_winstring_ { void Platform_EncodeString(cc_winstring* dst, const cc_string* src); cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib); -#else -/* Encodes a string in UTF8 format, also null terminating the string. */ -/* Returns the number of bytes written, excluding trailing NULL terminator. */ -int Platform_EncodeUtf8(void* data, const cc_string* src); #endif /* Initialises the platform specific state. */ diff --git a/src/SSL.c b/src/SSL.c index 2580eeb99..61a2fbb42 100644 --- a/src/SSL.c +++ b/src/SSL.c @@ -480,6 +480,149 @@ cc_result SSL_Free(void* ctx_) { sslcContext* ctx = (sslcContext*)ctx_; return sslcDestroyContext(ctx); } +#elif defined CC_BUILD_GCWII && defined HW_RVL +/* Based off https://wiibrew.org/wiki//dev/net/ssl/code */ +#include +#include "SSL.h" +#include "Platform.h" +#include "Logger.h" +#include "String.h" +#define IOCTLV_SSL_NEW 1 +#define IOCTLV_SSL_CONNECT 2 +#define IOCTLV_SSL_HANDSHAKE 3 +#define IOCTLV_SSL_READ 4 +#define IOCTLV_SSL_WRITE 5 +#define IOCTLV_SSL_SHUTDOWN 6 +#define SSL_HEAP_SIZE 0xB000 +static char SSL_fs[] ATTRIBUTE_ALIGN(32) = "/dev/net/ssl"; +static s32 SSL_fd = -1; +static s32 SSL_hid = -1; +void SSLBackend_Init(cc_bool verifyCerts) { + if (SSL_hid >= 0) return; + + SSL_hid = iosCreateHeap(SSL_HEAP_SIZE); + if (SSL_hid < 0) Logger_Abort("Failed to create SSL heap"); +} +cc_bool SSLBackend_DescribeError(cc_result res, cc_string* dst) { return false; } +static u32 ssl_open(void) { + s32 ret; + if (SSL_fd >= 0) return 0; + if (SSL_hid < 0) return ERR_OUT_OF_MEMORY; + ret = IOS_Open(SSL_fs, 0); + if (ret < 0) return ret; + SSL_fd = ret; + return 0; +} +static u32 ssl_close(void) { + s32 ret; + if (SSL_fd < 0) return 0; + ret = IOS_Close(SSL_fd); + SSL_fd = -1; + return ret; +} + +static s32 ssl_new(const cc_string* host, u32 ssl_verify_options) { + s32 ret; + + u8 aCN[1024] ATTRIBUTE_ALIGN(32); + s32 aContext[8] ATTRIBUTE_ALIGN(32); + u32 aVerify_options[8] ATTRIBUTE_ALIGN(32); + String_EncodeUtf8(aCN, host); + if ((ret = ssl_open())) return ret; + aVerify_options[0] = ssl_verify_options; + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_NEW, "d:dd", aContext, 0x20, aVerify_options, 0x20, aCN, 0x100); + ssl_close(); + return ret ? ret : aContext[0]; +} +static s32 ssl_connect(s32 ssl_context, s32 socket) { + s32 ret; + s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); + s32 aSocket[8] ATTRIBUTE_ALIGN(32); + s32 aResponse[8] ATTRIBUTE_ALIGN(32); + if ((ret = ssl_open())) return ret; + aSsl_context[0] = ssl_context; + aSocket[0] = socket; + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_CONNECT, "d:dd", aResponse, 0x20, aSsl_context, 0x20, aSocket, 0x20); + ssl_close(); + return ret ? ret : aResponse[0]; +} +static s32 ssl_handshake(s32 ssl_context) { + s32 ret; + s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); + s32 aResponse[8] ATTRIBUTE_ALIGN(32); + if ((ret = ssl_open())) return ret; + aSsl_context[0] = ssl_context; + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_HANDSHAKE, "d:d", aResponse, 0x20, aSsl_context, 0x20); + ssl_close(); + return ret ? ret : aResponse[0]; +} +cc_result SSL_Init(cc_socket socket, const cc_string* host, void** ctx) { + int sslCtx, ret; + + sslCtx = ssl_new(host, 0); + if (sslCtx < 0) return sslCtx; + + int* mem = Mem_Alloc(1, sizeof(int), "SSL context"); + *mem = sslCtx; + *ctx = mem; + + if ((ret = ssl_connect(sslCtx, socket))) return ret; + if ((ret = ssl_handshake(sslCtx))) return ret; + return 0; +} + +cc_result SSL_Read(void* ctx, cc_uint8* data, cc_uint32 count, cc_uint32* read) { + int sslCtx = *(int*)ctx; + *read = 0; + s32 ret; + + s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); + s32 aResponse[8] ATTRIBUTE_ALIGN(32); + if ((ret = ssl_open())) return ret; + u8* aBuffer = NULL; + aBuffer = iosAlloc(SSL_hid, count); + if (!aBuffer) return IPC_ENOMEM; + aSsl_context[0] = sslCtx; + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_READ, "dd:d", aResponse, 0x20, aBuffer, count, aSsl_context, 0x20); + ssl_close(); + if (ret == IPC_OK) { + Mem_Copy(data, aBuffer, aResponse[0]); + } + *read = aResponse[0]; + iosFree(SSL_hid, aBuffer); + return ret; +} +cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) { + int sslCtx = *(int*)ctx; + *wrote = 0; + s32 ret; + + s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); + s32 aResponse[8] ATTRIBUTE_ALIGN(32); + if ((ret = ssl_open())) return ret; + u8* aBuffer = NULL; + aBuffer = iosAlloc(SSL_hid, count); + if (!aBuffer) return IPC_ENOMEM; + aSsl_context[0] = sslCtx; + Mem_Copy(aBuffer, data, count); + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_WRITE, "d:dd", aResponse, 0x20, aSsl_context, 0x20, aBuffer, count); + ssl_close(); + + *wrote = aResponse[0]; + iosFree(SSL_hid, aBuffer); + return ret; +} +cc_result SSL_Free(void* ctx) { + int sslCtx = *(int*)ctx; + s32 ret; + s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); + s32 aResponse[8] ATTRIBUTE_ALIGN(32); + if ((ret = ssl_open())) return ret; + aSsl_context[0] = sslCtx; + ret = IOS_IoctlvFormat(SSL_hid, SSL_fd, IOCTLV_SSL_SHUTDOWN, "d:d", aResponse, 0x20, aSsl_context, 0x20); + ssl_close(); + return ret; +} #else void SSLBackend_Init(cc_bool verifyCerts) { } cc_bool SSLBackend_DescribeError(cc_result res, cc_string* dst) { return false; } @@ -497,4 +640,4 @@ cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* } cc_result SSL_Free(void* ctx) { return 0; } -#endif +#endif \ No newline at end of file