// Copyright 2017 plutoo #include #include Result tmemCreate(TransferMemory* t, size_t size, Permission perm) { Result rc = 0; t->MemHandle = INVALID_HANDLE; t->Size = size; t->Perm = perm; t->MappedAddr = NULL; t->SourceAddr = memalign(0x1000, size); if (t->SourceAddr == NULL) { rc = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM); } if (R_SUCCEEDED(rc)) { rc = svcCreateTransferMemory(&t->MemHandle, t->SourceAddr, size, perm); } return rc; } void tmemLoadRemote(TransferMemory* t, Handle handle, size_t size, Permission perm) { t->MemHandle = handle; t->Size = size; t->Perm = perm; t->MappedAddr = NULL; t->SourceAddr = NULL; } Result tmemMap(TransferMemory* t) { Result rc = 0; if (t->MappedAddr == NULL) { void* addr = virtmemReserve(t->Size); rc = svcMapTransferMemory(t->MemHandle, addr, t->Size, t->Perm); if (R_SUCCEEDED(rc)) { t->MappedAddr = addr; } else { virtmemFree(addr, t->Size); } } else { rc = LIBNX_ALREADYMAPPED; } return rc; } Result tmemUnmap(TransferMemory* t) { Result rc; rc = svcUnmapTransferMemory(t->MemHandle, t->MappedAddr, t->Size); if (R_SUCCEEDED(rc)) { t->MappedAddr = NULL; } return rc; } void* tmemGetAddr(TransferMemory* t) { return t->MappedAddr; } Result tmemClose(TransferMemory* t) { Result rc = 0; if (t->SourceAddr != NULL) { free(t->SourceAddr); } if (t->MappedAddr != NULL) { rc = tmemUnmap(t); } if (R_SUCCEEDED(rc)) { if (t->MemHandle != INVALID_HANDLE) { rc = svcCloseHandle(t->MemHandle); } t->SourceAddr = NULL; t->MemHandle = INVALID_HANDLE; } return rc; }