diff --git a/nx/include/switch.h b/nx/include/switch.h index 2dbcc022..34b81dc0 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -110,6 +110,7 @@ extern "C" { #include "switch/services/capsu.h" #include "switch/services/capssc.h" #include "switch/services/capssu.h" +#include "switch/services/capmtp.h" #include "switch/services/nfc.h" #include "switch/services/wlaninf.h" #include "switch/services/pctl.h" diff --git a/nx/include/switch/services/capmtp.h b/nx/include/switch/services/capmtp.h index 23300f41..050db228 100644 --- a/nx/include/switch/services/capmtp.h +++ b/nx/include/switch/services/capmtp.h @@ -9,13 +9,13 @@ #include "../kernel/event.h" #include "../sf/service.h" -Result capmtpInitialize(void* mem, size_t size, u32 app_count, u32 max_img, u32 max_vid, const char *other_name); +Result capmtpInitialize(void* mem, size_t size, u32 app_count, u32 max_img, u32 max_vid, const uint_least16_t *other_name); void capmtpExit(void); Result capmtpStartCommandHandler(void); Result capmtpStopCommandHandler(void); -Event *capmtpGetEvent1(void); -Event *capmtpGetEvent2(void); -Result capmtpIsRunning(bool *out); -Result capmtpUnkBool(bool *out); -Result capmtpGetResult(void); +bool capmtpIsRunning(void); +Event *capmtpGetConnectionEvent(void); +bool capmtpIsConnected(void); +Event *capmtpGetScanErrorEvent(void); +Result capmtpGetScanError(void); diff --git a/nx/source/services/capmtp.c b/nx/source/services/capmtp.c index ae010170..2f1e1809 100644 --- a/nx/source/services/capmtp.c +++ b/nx/source/services/capmtp.c @@ -1,45 +1,46 @@ -#include - +#include "service_guard.h" #include "kernel/tmem.h" #include "runtime/hosversion.h" #include "services/capmtp.h" #include "services/sm.h" -static Service g_capmtpRoot, g_capmtp; +static Service g_capmtpRoot; +static Service g_capmtp; static TransferMemory g_tmem; -static Event g_event1, g_event2; +static Event g_connectEvent, g_scanErrorEvent; static Result _capmtpOpenSession(Service *srv); -static Result _capmtpOpen(u32 app_count, u32 max_img, u32 max_vid, const char *other_name); +static Result _capmtpOpen(u32 max_folders, u32 max_img, u32 max_vid, const uint_least16_t *other_name); static Result _capmtpClose(void); static Result _capmtpNoInEventOut(u32 id, Event* event, bool autoclear); -Result capmtpInitialize(void* mem, size_t size, u32 app_count, u32 max_img, u32 max_vid, const char *other_name) { - Result rc=0; +NX_GENERATE_SERVICE_GUARD_PARAMS(capmtp, (void* mem, size_t size, u32 max_folders, u32 max_img, u32 max_vid, const uint_least16_t *other_name), (mem, size, max_folders, max_img, max_vid, other_name)); - if (hosversionBefore(11,0,0)) - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); +Result _capmtpInitialize(void* mem, size_t size, u32 max_folders, u32 max_img, u32 max_vid, const uint_least16_t *other_name) { + Result rc=0; rc = tmemCreateFromMemory(&g_tmem, mem, size, Perm_None); if (R_SUCCEEDED(rc)) rc = smGetService(&g_capmtpRoot, "capmtp"); + if (R_SUCCEEDED(rc)) rc = serviceConvertToDomain(&g_capmtpRoot); if (R_SUCCEEDED(rc)) rc = _capmtpOpenSession(&g_capmtp); - if (R_SUCCEEDED(rc)) rc = _capmtpOpen(app_count, max_img, max_vid, other_name); - if (R_SUCCEEDED(rc)) rc = _capmtpNoInEventOut(5, &g_event1, false); - if (R_SUCCEEDED(rc)) rc = _capmtpNoInEventOut(7, &g_event2, false); + + if (R_SUCCEEDED(rc)) rc = _capmtpOpen(max_folders, max_img, max_vid, other_name); + if (R_SUCCEEDED(rc)) rc = _capmtpNoInEventOut(5, &g_connectEvent, false); + if (R_SUCCEEDED(rc)) rc = _capmtpNoInEventOut(7, &g_scanErrorEvent, false); if (R_FAILED(rc)) capmtpExit(); return rc; } -void capmtpExit(void) { +void _capmtpCleanup(void) { + eventClose(&g_scanErrorEvent); + eventClose(&g_connectEvent); _capmtpClose(); - eventClose(&g_event2); - eventClose(&g_event1); - serviceClose(&g_capmtpRoot); serviceClose(&g_capmtp); + serviceClose(&g_capmtpRoot); tmemClose(&g_tmem); } @@ -61,11 +62,9 @@ static Result _capmtpNoInEventOut(u32 id, Event* event, bool autoclear) { return rc; } -static Result _capmtpNoInBoolOut(u32 id, bool* out) { +static Result _capmtpNoInBoolOut(u32 id) { u8 tmp=0; - Result rc = serviceDispatchOut(&g_capmtp, id, tmp); - if (R_SUCCEEDED(rc)) *out = tmp & 1; - return rc; + return R_SUCCEEDED(serviceDispatchOut(&g_capmtp, id, tmp)) && tmp & 1; } static Result _capmtpOpenSession(Service *srv) { @@ -75,23 +74,29 @@ static Result _capmtpOpenSession(Service *srv) { ); } -static Result _capmtpOpen(u32 app_count, u32 max_img, u32 max_vid, const char *other_name) { +static Result _capmtpClose(void) { + return _capmtpNoIO(1); +} + +static Result _capmtpOpen(u32 max_folders, u32 max_img, u32 max_vid, const uint_least16_t *other_name) { + size_t len=0; + const uint_least16_t *tmp =other_name; + while(*tmp++) ++len; const struct { - u32 c[4]; - } in = { { app_count, max_img, max_vid, g_tmem.size } }; + u32 tmem_size; + u32 folder_count; + u32 max_images; + u32 max_videos; + } in = { (u32)g_tmem.size, max_folders, max_img, max_vid }; return serviceDispatchIn(&g_capmtp, 0, in, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, - .buffers = { { other_name, strlen(other_name) + 1 } }, + .buffers = { { other_name, 2*len + 1 } }, .in_num_handles = 1, .in_handles = { g_tmem.handle }, ); } -static Result _capmtpClose() { - return _capmtpNoIO(1); -} - Result capmtpStartCommandHandler(void) { return _capmtpNoIO(2); } @@ -100,22 +105,22 @@ Result capmtpStopCommandHandler(void) { return _capmtpNoIO(3); } -Event *capmtpGetEvent1(void) { - return &g_event1; +bool capmtpIsRunning(void) { + return _capmtpNoInBoolOut(4); } -Event *capmtpGetEvent2(void) { - return &g_event2; +Event *capmtpGetConnectionEvent(void) { + return &g_connectEvent; } -Result capmtpIsRunning(bool *out) { - return _capmtpNoInBoolOut(4, out); +bool capmtpIsConnected(void) { + return _capmtpNoInBoolOut(6); } -Result capmtpUnkBool(bool *out) { - return _capmtpNoInBoolOut(6, out); +Event *capmtpGetScanErrorEvent(void) { + return &g_scanErrorEvent; } -Result capmtpGetResult(void) { +Result capmtpGetScanError(void) { return _capmtpNoIO(8); }