bool appIsInstalled(App app) { if(!serviceRequire("am")) { return false; } u32 titleCount; Result titleCountResult = AM_GetTitleCount(appMediatypeToByte(app.mediaType), &titleCount); if(titleCountResult != 0) { platformSetError(serviceParseError((u32) titleCountResult)); return false; } u64 titleIds[titleCount]; Result titleIdsResult = AM_GetTitleIdList(appMediatypeToByte(app.mediaType), titleCount, titleIds); if(titleIdsResult != 0) { platformSetError(serviceParseError((u32) titleIdsResult)); return false; } for(u32 i = 0; i < titleCount; i++) { if(titleIds[i] == app.titleId) { return true; } } return false; }
std::vector<App> appList(MediaType mediaType) { std::vector<App> titles; if(!serviceRequire("am")) { return titles; } u32 titleCount; Result titleCountResult = AM_GetTitleCount(appMediatypeToByte(mediaType), &titleCount); if(titleCountResult != 0) { platformSetError(serviceParseError((u32) titleCountResult)); return titles; } u64 titleIds[titleCount]; Result titleIdsResult = AM_GetTitleIdList(appMediatypeToByte(mediaType), titleCount, titleIds); if(titleIdsResult != 0) { platformSetError(serviceParseError((u32) titleIdsResult)); return titles; } TitleList titleList[titleCount]; Result titleListResult = AM_ListTitles(appMediatypeToByte(mediaType), titleCount, titleIds, titleList); if(titleListResult != 0) { platformSetError(serviceParseError((u32) titleListResult)); return titles; } for(u32 i = 0; i < titleCount; i++) { u64 titleId = titleList[i].titleID; App app; app.titleId = titleId; app.uniqueId = ((u32*) &titleId)[0]; AM_GetTitleProductCode(appMediatypeToByte(mediaType), titleId, app.productCode); if(strcmp(app.productCode, "") == 0) { strcpy(app.productCode, "<N/A>"); } app.mediaType = mediaType; app.platform = appPlatformFromId(((u16*) &titleId)[3]); app.category = appCategoryFromId(((u16*) &titleId)[2]); app.version = titleList[i].titleVersion; app.size = titleList[i].size; titles.push_back(app); } return titles; }
App appGetCiaInfo(const std::string file, MediaType mediaType) { if(!serviceRequire("am")) { return {}; } FS_archive archive = (FS_archive) {ARCH_SDMC, (FS_path) {PATH_EMPTY, 1, (u8*) ""}}; Result archiveResult = FSUSER_OpenArchive(NULL, &archive); if(archiveResult != 0) { platformSetError(serviceParseError((u32) archiveResult)); return {}; } Handle handle = 0; Result openResult = FSUSER_OpenFile(NULL, &handle, archive, FS_makePath(PATH_CHAR, file.c_str()), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(openResult != 0) { platformSetError(serviceParseError((u32) openResult)); return {}; } TitleList titleInfo; Result infoResult = AM_GetCiaFileInfo(appMediatypeToByte(mediaType), &titleInfo, handle); if(infoResult != 0) { platformSetError(serviceParseError((u32) infoResult)); return {}; } FSFILE_Close(handle); FSUSER_CloseArchive(NULL, &archive); App app; app.titleId = titleInfo.titleID; app.uniqueId = ((u32*) &titleInfo.titleID)[0]; strcpy(app.productCode, "<N/A>"); app.mediaType = mediaType; app.platform = appPlatformFromId(((u16*) &titleInfo.titleID)[3]); app.category = appCategoryFromId(((u16*) &titleInfo.titleID)[2]); app.version = titleInfo.titleVersion; app.size = titleInfo.size; return app; }
AppResult appLaunch(App app) { u8 buf0[0x300]; u8 buf1[0x20]; aptOpenSession(); Result prepareResult = APT_PrepareToDoAppJump(NULL, 0, app.titleId, appMediatypeToByte(app.mediaType)); if(prepareResult != 0) { aptCloseSession(); platformSetError(serviceParseError((u32) prepareResult)); return APP_LAUNCH_FAILED; } Result doResult = APT_DoAppJump(NULL, 0x300, 0x20, buf0, buf1); if(doResult != 0) { aptCloseSession(); platformSetError(serviceParseError((u32) doResult)); return APP_LAUNCH_FAILED; } aptCloseSession(); return APP_SUCCESS; }
AppResult appDelete(App app) { if(!serviceRequire("am")) { return APP_AM_INIT_FAILED; } Result res = AM_DeleteTitle(appMediatypeToByte(app.mediaType), app.titleId); if(res != 0) { platformSetError(serviceParseError((u32) res)); return APP_DELETE_FAILED; } return APP_SUCCESS; }
void irInit() { irBuffer = (u32*) memalign(0x1000, 0x1000); if(irBuffer == NULL) { irError = {MODULE_NN_IR, LEVEL_FATAL, SUMMARY_OUT_OF_RESOURCE, DESCRIPTION_OUT_OF_MEMORY}; return; } Result result = iruInit(irBuffer, 0x1000); if(result != 0 && serviceAcquire()) { result = iruInit(irBuffer, 0x1000); } if(result != 0) { free(irBuffer); irBuffer = NULL; irError = serviceParseError((u32) result); } hasIr = result == 0; }
AppResult appInstall(MediaType mediaType, FILE* fd, u64 size, std::function<bool(u64 pos, u64 totalSize)> onProgress) { if(!serviceRequire("am")) { return APP_AM_INIT_FAILED; } if(onProgress != NULL) { onProgress(0, size); } Handle ciaHandle; Result startResult = AM_StartCiaInstall(appMediatypeToByte(mediaType), &ciaHandle); if(startResult != 0) { platformSetError(serviceParseError((u32) startResult)); return APP_BEGIN_INSTALL_FAILED; } u32 bufSize = 1024 * 128; // 128KB void* buf = malloc(bufSize); bool cancelled = false; u64 pos = 0; while(platformIsRunning()) { if(onProgress != NULL && !onProgress(pos, size)) { cancelled = true; break; } size_t bytesRead = fread(buf, 1, bufSize, fd); if(bytesRead > 0) { Result writeResult = FSFILE_Write(ciaHandle, NULL, pos, buf, (u32) bytesRead, FS_WRITE_NOFLUSH); if(writeResult != 0) { AM_CancelCIAInstall(&ciaHandle); platformSetError(serviceParseError((u32) writeResult)); return APP_INSTALL_ERROR; } pos += bytesRead; } if((ferror(fd) && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINPROGRESS) || (size != 0 && pos == size)) { break; } } free(buf); if(cancelled) { AM_CancelCIAInstall(&ciaHandle); return APP_OPERATION_CANCELLED; } if(!platformIsRunning()) { AM_CancelCIAInstall(&ciaHandle); return APP_PROCESS_CLOSING; } if(size != 0 && pos != size) { AM_CancelCIAInstall(&ciaHandle); return APP_IO_ERROR; } if(onProgress != NULL) { onProgress(size, size); } Result finishResult = AM_FinishCiaInstall(appMediatypeToByte(mediaType), &ciaHandle); if(finishResult != 0) { platformSetError(serviceParseError((u32) finishResult)); return APP_FINALIZE_INSTALL_FAILED; } return APP_SUCCESS; }