summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-04-28 18:53:39 -0400
committerGravatar Zach Hilman2019-09-30 17:23:26 -0400
commit8812018c1defbd76b9a44aaf8e050bf97c73aeae (patch)
treefd56fd41e2c49f7c46a215c5b9ec88e92a7472f7 /src
parentbcat: Implement IDeliveryCacheStorageService commands (diff)
downloadyuzu-8812018c1defbd76b9a44aaf8e050bf97c73aeae.tar.gz
yuzu-8812018c1defbd76b9a44aaf8e050bf97c73aeae.tar.xz
yuzu-8812018c1defbd76b9a44aaf8e050bf97c73aeae.zip
bcat: Implement IDeliveryCacheDirectoryService commands
Used to list and get directories at the root level.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/bcat/module.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 2d8341359..6645599f2 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -40,6 +40,105 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 40 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
41 rb.Push(RESULT_SUCCESS); 41 rb.Push(RESULT_SUCCESS);
42 rb.PushIpcInterface<IBcatService>(*backend); 42 rb.PushIpcInterface<IBcatService>(*backend);
43class IDeliveryCacheDirectoryService final
44 : public ServiceFramework<IDeliveryCacheDirectoryService> {
45public:
46 IDeliveryCacheDirectoryService(FileSys::VirtualDir root_)
47 : ServiceFramework{"IDeliveryCacheDirectoryService"}, root(std::move(root_)) {
48 // clang-format off
49 static const FunctionInfo functions[] = {
50 {0, &IDeliveryCacheDirectoryService::Open, "Open"},
51 {1, &IDeliveryCacheDirectoryService::Read, "Read"},
52 {2, &IDeliveryCacheDirectoryService::GetCount, "GetCount"},
53 };
54 // clang-format on
55
56 RegisterHandlers(functions);
57 }
58
59private:
60 void Open(Kernel::HLERequestContext& ctx) {
61 IPC::RequestParser rp{ctx};
62 const auto name_raw = rp.PopRaw<DirectoryName>();
63 const auto name =
64 Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size());
65
66 LOG_DEBUG(Service_BCAT, "called, name={}", name);
67
68 if (!VerifyNameValidDir(ctx, name_raw))
69 return;
70
71 if (current_dir != nullptr) {
72 LOG_ERROR(Service_BCAT, "A file has already been opened on this interface!");
73 IPC::ResponseBuilder rb{ctx, 2};
74 rb.Push(ERROR_ENTITY_ALREADY_OPEN);
75 return;
76 }
77
78 current_dir = root->GetSubdirectory(name);
79
80 if (current_dir == nullptr) {
81 LOG_ERROR(Service_BCAT, "Failed to open the directory name={}!", name);
82 IPC::ResponseBuilder rb{ctx, 2};
83 rb.Push(ERROR_FAILED_OPEN_ENTITY);
84 return;
85 }
86
87 IPC::ResponseBuilder rb{ctx, 2};
88 rb.Push(RESULT_SUCCESS);
89 }
90
91 void Read(Kernel::HLERequestContext& ctx) {
92 auto write_size = ctx.GetWriteBufferSize() / sizeof(DeliveryCacheDirectoryEntry);
93
94 LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", write_size);
95
96 if (current_dir == nullptr) {
97 LOG_ERROR(Service_BCAT, "There is no open directory!");
98 IPC::ResponseBuilder rb{ctx, 2};
99 rb.Push(ERROR_NO_OPEN_ENTITY);
100 return;
101 }
102
103 const auto files = current_dir->GetFiles();
104 write_size = std::min(write_size, files.size());
105 std::vector<DeliveryCacheDirectoryEntry> entries(write_size);
106 std::transform(
107 files.begin(), files.begin() + write_size, entries.begin(), [](const auto& file) {
108 FileName name{};
109 std::memcpy(name.data(), file->GetName().data(),
110 std::min(file->GetName().size(), name.size()));
111 return DeliveryCacheDirectoryEntry{name, file->GetSize(), DigestFile(file)};
112 });
113
114 ctx.WriteBuffer(entries);
115
116 IPC::ResponseBuilder rb{ctx, 3};
117 rb.Push(RESULT_SUCCESS);
118 rb.Push<u32>(write_size * sizeof(DeliveryCacheDirectoryEntry));
119 }
120
121 void GetCount(Kernel::HLERequestContext& ctx) {
122 LOG_DEBUG(Service_BCAT, "called");
123
124 if (current_dir == nullptr) {
125 LOG_ERROR(Service_BCAT, "There is no open directory!");
126 IPC::ResponseBuilder rb{ctx, 2};
127 rb.Push(ERROR_NO_OPEN_ENTITY);
128 return;
129 }
130
131 const auto files = current_dir->GetFiles();
132
133 IPC::ResponseBuilder rb{ctx, 3};
134 rb.Push(RESULT_SUCCESS);
135 rb.Push<u32>(files.size());
136 }
137
138 FileSys::VirtualDir root;
139 FileSys::VirtualDir current_dir;
140};
141
43class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> { 142class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> {
44public: 143public:
45 IDeliveryCacheStorageService(FileSys::VirtualDir root_) 144 IDeliveryCacheStorageService(FileSys::VirtualDir root_)