void __attribute__((weak)) __appInit(void) { Result rc; // Initialize default services. rc = smInitialize(); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); rc = appletInitialize(); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_AM)); if (__nx_applet_type != AppletType_None) { rc = hidInitialize(); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_HID)); } rc = timeInitialize(); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_Time)); rc = fsInitialize(); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); fsdevMountSdmc(); }
static Result task_populate_pending_titles_from(populate_pending_titles_data* data, FS_MediaType mediaType) { Result res = 0; u32 pendingTitleCount = 0; if(R_SUCCEEDED(res = AM_GetPendingTitleCount(&pendingTitleCount, mediaType, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION))) { u64* pendingTitleIds = (u64*) calloc(pendingTitleCount, sizeof(u64)); if(pendingTitleIds != NULL) { if(R_SUCCEEDED(res = AM_GetPendingTitleList(&pendingTitleCount, pendingTitleCount, mediaType, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION, pendingTitleIds))) { qsort(pendingTitleIds, pendingTitleCount, sizeof(u64), util_compare_u64); AM_PendingTitleEntry* pendingTitleInfos = (AM_PendingTitleEntry*) calloc(pendingTitleCount, sizeof(AM_PendingTitleEntry)); if(pendingTitleInfos != NULL) { if(R_SUCCEEDED(res = AM_GetPendingTitleInfo(pendingTitleCount, mediaType, pendingTitleIds, pendingTitleInfos))) { for(u32 i = 0; i < pendingTitleCount && i < data->max; i++) { if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) { break; } pending_title_info* pendingTitleInfo = (pending_title_info*) calloc(1, sizeof(pending_title_info)); if(pendingTitleInfo != NULL) { pendingTitleInfo->mediaType = mediaType; pendingTitleInfo->titleId = pendingTitleIds[i]; pendingTitleInfo->version = pendingTitleInfos[i].version; list_item* item = &data->items[*data->count]; snprintf(item->name, NAME_MAX, "%016llX", pendingTitleIds[i]); if(mediaType == MEDIATYPE_NAND) { item->rgba = COLOR_NAND; } else if(mediaType == MEDIATYPE_SD) { item->rgba = COLOR_SD; } item->data = pendingTitleInfo; (*data->count)++; } } } free(pendingTitleInfos); } else { res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY); } } free(pendingTitleIds); } else { res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY); } } return res; }
static Result action_install_cdn_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) { install_cdn_data* installData = (install_cdn_data*) data; if(index == 0) { static u32 dataOffsets[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80}; u8* tmd = (u8*) initialReadBlock; u8 sigType = tmd[0x03]; installData->contentCount = __builtin_bswap16(*(u16*) &tmd[dataOffsets[sigType] + 0x9E]); if(installData->contentCount > CONTENTS_MAX) { return MAKERESULT(RL_PERMANENT, RS_INVALIDARG, RM_APPLICATION, RD_OUT_OF_RANGE); } for(u32 i = 0; i < installData->contentCount; i++) { u8* contentChunk = &tmd[dataOffsets[sigType] + 0x9C4 + (i * 0x30)]; installData->contentIds[i] = __builtin_bswap32(*(u32*) &contentChunk[0x00]); installData->contentIndices[i] = __builtin_bswap16(*(u16*) &contentChunk[0x04]); } installData->installInfo.total += installData->contentCount; return AM_InstallTmdBegin(handle); } else { return AM_InstallContentBegin(handle, installData->contentIndices[index - 1]); } }
Result srvSysInit() { Result rc = 0; if (!initLockinit) { RecursiveLock_Init(&initLock); } RecursiveLock_Lock(&initLock); if (srvRefCount > 0) { RecursiveLock_Unlock(&initLock); return MAKERESULT(RL_INFO, RS_NOP, 25, RD_ALREADY_INITIALIZED); } while (1) { rc = svcConnectToPort(&srvHandle, "srv:"); if (R_LEVEL(rc) != RL_PERMANENT || R_SUMMARY(rc) != RS_NOTFOUND || R_DESCRIPTION(rc) != RD_NOT_FOUND) break; svcSleepThread(500000); } if (R_SUCCEEDED(rc)) { rc = srvSysRegisterClient(); srvRefCount++; } RecursiveLock_Unlock(&initLock); return rc; }
Result ndspInit(void) { Result rc = 0; if (AtomicPostIncrement(&ndspRefCount)) return 0; if (!componentBin && !ndspFindAndLoadComponent()) { rc = MAKERESULT(RL_PERMANENT, RS_NOTFOUND, 41, RD_NOT_FOUND); goto _fail0; } LightLock_Init(&ndspMutex); ndspInitMaster(); ndspiInitChn(); rc = cfguInit(); if (R_SUCCEEDED(rc)) { u8 outMode; rc = CFGU_GetConfigInfoBlk2(sizeof(outMode), 0x70001, &outMode); if (R_SUCCEEDED(rc)) ndspMaster.outputMode = outMode; cfguExit(); } rc = dspInit(); if (R_FAILED(rc)) return rc; rc = ndspInitialize(false); if (R_FAILED(rc)) goto _fail1; rc = svcCreateEvent(&sleepEvent, 0); if (R_FAILED(rc)) goto _fail2; ndspThread = threadCreate(ndspThreadMain, 0x0, NDSP_THREAD_STACK_SIZE, 0x18, -2, true); if (!ndspThread) goto _fail3; aptHook(&aptCookie, ndspAptHook, NULL); return 0; _fail3: svcCloseHandle(sleepEvent); _fail2: ndspFinalize(false); _fail1: dspExit(); if (componentFree) { free((void*)componentBin); componentBin = NULL; } _fail0: AtomicDecrement(&ndspRefCount); return rc; }
Result srvSysExit() { Result rc; RecursiveLock_Lock(&initLock); if (srvRefCount > 1) { srvRefCount--; RecursiveLock_Unlock(&initLock); return MAKERESULT(RL_INFO, RS_NOP, 25, RD_BUSY); } if (srvHandle != 0) svcCloseHandle(srvHandle); else svcBreak(USERBREAK_ASSERT); rc = (Result)srvHandle; // yeah, I think this is a benign bug srvHandle = 0; srvRefCount--; RecursiveLock_Unlock(&initLock); return rc; }
void __attribute__((weak)) __libnx_initheap(void) { void* addr; size_t size = 0; size_t mem_available = 0, mem_used = 0; if (envHasHeapOverride()) { addr = envGetHeapOverrideAddr(); size = envGetHeapOverrideSize(); } else { if (__nx_heap_size==0) { svcGetInfo(&mem_available, 6, CUR_PROCESS_HANDLE, 0); svcGetInfo(&mem_used, 7, CUR_PROCESS_HANDLE, 0); if (mem_available > mem_used+0x200000) size = (mem_available - mem_used - 0x200000) & ~0x1FFFFF; if (size==0) size = 0x2000000*16; } else { size = __nx_heap_size; } Result rc = svcSetHeapSize(&addr, size); if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_HeapAllocFailed)); } // Newlib extern char* fake_heap_start; extern char* fake_heap_end; fake_heap_start = (char*)addr; fake_heap_end = (char*)addr + size; }
Result parcelTransact(Binder *session, u32 code, Parcel *in_parcel, Parcel *parcel_reply) { Result rc=0; u8 inparcel[0x400]; u8 outparcel[0x400]; size_t outparcel_size = sizeof(outparcel); u32 *inparcel32 = (u32*)inparcel; u32 *outparcel32 = (u32*)outparcel; u32 payloadSize = in_parcel->size; u32 ParcelObjectsSize = in_parcel->ParcelObjectsSize; memset(inparcel, 0, sizeof(inparcel)); memset(outparcel, 0, outparcel_size); if((size_t)payloadSize >= sizeof(inparcel) || (size_t)ParcelObjectsSize >= sizeof(inparcel) || ((size_t)payloadSize)+((size_t)ParcelObjectsSize)+0x10 >= sizeof(inparcel)) return MAKERESULT(Module_Libnx, LibnxError_BadInput); inparcel32[0] = payloadSize;//payloadSize inparcel32[1] = 0x10;//payloadOffset inparcel32[2] = ParcelObjectsSize;//ParcelObjectsSize inparcel32[3] = 0x10+payloadSize;//ParcelObjectsOffset if(in_parcel->payload && payloadSize)memcpy(&inparcel[inparcel32[1]], in_parcel->payload, payloadSize); if(in_parcel->ParcelObjects && ParcelObjectsSize)memcpy(&inparcel[inparcel32[3]], in_parcel->ParcelObjects, ParcelObjectsSize); rc = binderTransactParcel(session, code, inparcel, payloadSize+ParcelObjectsSize+0x10, outparcel, outparcel_size, 0); if (R_FAILED(rc)) return rc; if((size_t)outparcel32[1] >= outparcel_size || ((size_t)outparcel32[0])+((size_t)outparcel32[1]) >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); if((size_t)outparcel32[2] >= outparcel_size || ((size_t)outparcel32[2])+((size_t)outparcel32[3]) >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); if((size_t)outparcel32[0] >= outparcel_size || (size_t)outparcel32[3] >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); memcpy(parcel_reply->payload, &outparcel[outparcel32[1]], outparcel32[0]); parcel_reply->size = outparcel32[0]; #ifdef PARCEL_LOGGING if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) { memcpy(&parcel_reply_log[parcel_reply_log_size], inparcel, sizeof(inparcel)); parcel_reply_log_size+= sizeof(inparcel); memcpy(&parcel_reply_log[parcel_reply_log_size], outparcel, outparcel_size); parcel_reply_log_size+= outparcel_size; } #endif return 0; }
int main(int argc, char **argv) { (void) argc, (void) argv; Result res = MAKERESULT(RL_SUCCESS, RS_SUCCESS, 0, RD_SUCCESS); gfxInitDefault(); PrintConsole top; consoleInit(GFX_TOP, &top); util_debug_init(); consoleSelect(&top); if (R_FAILED(res = acInit())) { util_presult("acInit failed", res); goto ac_failure; } u32 wifi = 0; if (R_FAILED(res = ACU_GetWifiStatus(&wifi))) { util_presult("ACU_GetWifiStatus failed", res); fprintf(stderr, "Did you enable Wifi?\n"); goto wifi_check_failure; } if (!wifi) { fprintf(stderr, "Wifi disabled.\n"); goto wifi_check_failure; } if ((sock_ctx = memalign(SOCU_BUFSZ, SOCU_ALIGN)) == NULL) { util_perror("Allocating SOC buffer"); res = MAKERESULT( RL_PERMANENT, RS_OUTOFRESOURCE, RM_SOC, RD_OUT_OF_MEMORY); goto soc_alloc_failure; } if (R_FAILED(res = socInit(sock_ctx, SOCU_BUFSZ))) { util_presult("socInit failed", res); goto soc_failure; } if (R_FAILED(res = hidInit())) { util_presult("hidInit failed", res); goto hid_failure; } if (R_FAILED(res = HIDUSER_EnableAccelerometer())) { util_presult("Failed to enable accelerometer", res); goto accel_failure; } if (R_FAILED(res = ctrollerInit())) { fprintf(stderr, "Do you have a valid IP in\n '" CFG_FILE "'?"); goto failure; } bool isHomebrew = envIsHomebrew(); printf("Press %s to exit.\n", isHomebrew ? EXIT_DESC : "HOME"); fflush(stdout); while (aptMainLoop()) { if (isHomebrew) { if (hidKeysHeld() == EXIT_KEYS) { res = RL_SUCCESS; break; } } if (ctrollerSendHIDInfo()) { util_perror("Sending HID info"); fflush(stderr); for (int i = 3; i > 0; i--) { util_debug_printf("\rRetrying in %ds... ", i); svcSleepThread(1000000000L); } util_debug_printf("\rRetrying now.\x1b[K\n"); } gspWaitForVBlank(); gfxFlushBuffers(); gfxSwapBuffers(); } puts("Exiting..."); failure: HIDUSER_DisableAccelerometer(); accel_failure: hidExit(); hid_failure: socExit(); soc_failure: free(sock_ctx); soc_alloc_failure: wifi_check_failure: acExit(); ac_failure: if (R_FAILED(res)) { util_hang(res); } gfxExit(); return res; }
Result socketInitialize(const SocketInitConfig *config) { Result ret = 0; BsdInitConfig bcfg = { .version = config->bsdsockets_version, .tcp_tx_buf_size = config->tcp_tx_buf_size, .tcp_rx_buf_size = config->tcp_rx_buf_size, .tcp_tx_buf_max_size = config->tcp_tx_buf_max_size, .tcp_rx_buf_max_size = config->tcp_rx_buf_max_size, .udp_tx_buf_size = config->udp_tx_buf_size, .udp_rx_buf_size = config->udp_rx_buf_size, .sb_efficiency = config->sb_efficiency, }; SfdnsresConfig sfdnsresConfig = { .serialized_out_addrinfos_max_size = config->serialized_out_addrinfos_max_size, .serialized_out_hostent_max_size = config->serialized_out_hostent_max_size, .bypass_nsd = config->bypass_nsd, .timeout = config->dns_timeout, }; int dev = FindDevice("soc:"); if(dev != -1) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); ret = bsdInitialize(&bcfg); if(R_SUCCEEDED(ret)) dev = AddDevice(&g_socketDevoptab); else { socketExit(); return ret; } if(dev == -1) { socketExit(); return MAKERESULT(Module_Libnx, LibnxError_TooManyDevOpTabs); } else { g_bsdResult = 0; g_bsdErrno = 0; g_sfdnsresConfig = sfdnsresConfig; g_sfdnsresResult = 0; } return ret; } void socketExit(void) { RemoveDevice("soc:"); bsdExit(); } Result socketGetLastBsdResult(void) { return g_bsdResult; } Result socketGetLastSfdnsresResult(void) { return g_sfdnsresResult; } /***********************************************************************************************************************/ static int _socketGetFd(int fd) { __handle *handle = __get_handle(fd); if(handle == NULL) { errno = EBADF; return -1; } if(strcmp(devoptab_list[handle->device]->name, "soc") != 0) { errno = ENOTSOCK; return -1; } return *(int *)handle->fileStruct; }
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <liboath/oath.h> char const * TEST_ENCODED_SECRET = "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"; /* secret (base32) */ // TODO: How to account for daylight savings time? // TODO: LibCtrU includes an internal function that appears to use a timezone: // int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz); // Is this exported anywhere? // If not, perhaps modify LibCtrU to include this functionality? // See libctru\include\3ds\result.h for definitions Result const R_TINYTOT_SUCCESS = MAKERESULT(RL_SUCCESS,RS_SUCCESS,RM_APPLICATION,RD_SUCCESS); Result const R_TINYTOT_OVERFLOW = MAKERESULT(RL_FATAL,RS_INVALIDARG,RM_APPLICATION,RD_TOO_LARGE); Result const R_TINYTOT_OUTOFMEMORY = MAKERESULT(RL_FATAL,RS_OUTOFRESOURCE,RM_APPLICATION,RD_OUT_OF_MEMORY); unsigned long const INVALID_DECODED_SECRET = 0; unsigned long const REQUESTED_OTP_DIGITS = 6; signed long const INVALID_CLOCK_OFFSET = 0x1FFFF; // illegal value... see InitializeClockOffset() signed long g_SystemClockUtcOffset = 0x1FFFF; // NULL for non-pointer isn't correct bool IsValidTimeOffset(u32 timeOffset) { // timeOffset valid values are +/- 12 hours (+/- 43200 seconds) u32 x = 43200; u32 y = 0 - x; return ((timeOffset <= x) || (timeOffset >= y)); }
Result jitCreate(Jit* j, size_t size) { JitType type; // Use new jit primitive introduced in 4.0.0, if available. if (kernelAbove400() && envIsSyscallHinted(0x4B) && envIsSyscallHinted(0x4C)) { type = JitType_JitMemory; } // Fall back to MapProcessCodeMemory if available. else if (envIsSyscallHinted(0x73) && envIsSyscallHinted(0x77) && envIsSyscallHinted(0x78) && (envGetOwnProcessHandle() != INVALID_HANDLE)) { type = JitType_CodeMemory; } else { // Jit is unavailable. :( return MAKERESULT(Module_Libnx, LibnxError_JitUnavailable); } size = (size + 0xFFF) &~ 0xFFF; void* src_addr = memalign(size, 0x1000); if (src_addr == NULL) return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); j->type = type; j->size = size; j->src_addr = src_addr; j->rx_addr = virtmemReserve(j->size); j->handle = INVALID_HANDLE; Result rc = 0; switch (j->type) { case JitType_CodeMemory: j->rw_addr = j->src_addr; break; case JitType_JitMemory: j->rw_addr = virtmemReserve(j->size); rc = svcCreateJitMemory(&j->handle, j->src_addr, j->size); if (R_SUCCEEDED(rc)) { rc = svcMapJitMemory(j->handle, JitMapOperation_MapOwner, j->rw_addr, j->size, Perm_Rw); if (R_SUCCEEDED(rc)) { rc = svcMapJitMemory(j->handle, JitMapOperation_MapSlave, j->rx_addr, j->size, Perm_Rx); if (R_FAILED(rc)) { svcMapJitMemory(j->handle, JitMapOperation_UnmapOwner, j->rw_addr, j->size, 0); } } if (R_FAILED(rc)) { svcCloseHandle(j->handle); j->handle = INVALID_HANDLE; } } if (R_FAILED(rc)) { virtmemFree(j->rw_addr, j->size); j->rw_addr = NULL; } break; } if (R_FAILED(rc)) { virtmemFree(j->rx_addr, j->size); free(j->src_addr); j->src_addr = NULL; } return rc; }