void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x0802, 7, 2); rp.Skip(1, false); // Transaction. ArchiveHandle archive_handle = rp.Pop<u64>(); auto filename_type = rp.PopEnum<FileSys::LowPathType>(); u32 filename_size = rp.Pop<u32>(); FileSys::Mode mode{rp.Pop<u32>()}; u32 attributes = rp.Pop<u32>(); // TODO(Link Mauve): do something with those attributes. std::vector<u8> filename = rp.PopStaticBuffer(); ASSERT(filename.size() == filename_size); FileSys::Path file_path(filename_type, filename); LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes); ResultVal<std::shared_ptr<File>> file_res = archives.OpenFileFromArchive(archive_handle, file_path, mode); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(file_res.Code()); if (file_res.Succeeded()) { std::shared_ptr<File> file = *file_res; rb.PushMoveObjects(file->Connect()); } else { rb.PushMoveObjects<Kernel::Object>(nullptr); LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); } }
void File::OpenSubFile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x0801, 4, 0); s64 offset = rp.PopRaw<s64>(); s64 size = rp.PopRaw<s64>(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); const FileSessionSlot* original_file = GetSessionData(ctx.Session()); if (original_file->subfile) { // OpenSubFile can not be called on a file which is already as subfile rb.Push(FileSys::ERROR_UNSUPPORTED_OPEN_FLAGS); return; } if (offset < 0 || size < 0) { rb.Push(FileSys::ERR_WRITE_BEYOND_END); return; } std::size_t end = offset + size; // TODO(Subv): Check for overflow and return ERR_WRITE_BEYOND_END if (end > original_file->size) { rb.Push(FileSys::ERR_WRITE_BEYOND_END); return; } using Kernel::ClientSession; using Kernel::ServerSession; using Kernel::SharedPtr; auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get<SharedPtr<ServerSession>>(sessions); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); slot->priority = original_file->priority; slot->offset = offset; slot->size = size; slot->subfile = true; rb.Push(RESULT_SUCCESS); rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions)); }
void File::OpenLinkFile(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile {}", GetName()); using Kernel::ClientSession; using Kernel::ServerSession; using Kernel::SharedPtr; IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get<SharedPtr<ServerSession>>(sessions); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); const FileSessionSlot* original_file = GetSessionData(ctx.Session()); slot->priority = original_file->priority; slot->offset = 0; slot->size = backend->GetSize(); slot->subfile = false; rb.Push(RESULT_SUCCESS); rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions)); }
void IR_RST::GetHandles(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x01, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); rb.Push(RESULT_SUCCESS); rb.PushMoveObjects(shared_memory, update_event); }