summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-04 22:07:47 -0500
committerGravatar bunnei2014-12-04 22:07:47 -0500
commit5056329a8003115f61859b97c2fc6ef2f460a0d3 (patch)
tree9434ac214d06a5d55ff20848f57cb981647991dc /src/core/hle
parentMerge pull request #248 from lioncash/kernel (diff)
parentUpdated archive.cpp functions for proper error handling (diff)
downloadyuzu-5056329a8003115f61859b97c2fc6ef2f460a0d3.tar.gz
yuzu-5056329a8003115f61859b97c2fc6ef2f460a0d3.tar.xz
yuzu-5056329a8003115f61859b97c2fc6ef2f460a0d3.zip
Merge pull request #222 from archshift/renamexyz
Implemented RenameFile and RenameDirectory in FS:USER
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/archive.cpp79
-rw-r--r--src/core/hle/kernel/archive.h28
-rw-r--r--src/core/hle/service/fs_user.cpp94
3 files changed, 163 insertions, 38 deletions
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp
index e273444c9..647f0dea9 100644
--- a/src/core/hle/kernel/archive.cpp
+++ b/src/core/hle/kernel/archive.cpp
@@ -340,49 +340,68 @@ ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path
340 return MakeResult<Handle>(handle); 340 return MakeResult<Handle>(handle);
341} 341}
342 342
343/** 343ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path) {
344 * Delete a File from an Archive
345 * @param archive_handle Handle to an open Archive object
346 * @param path Path to the File inside of the Archive
347 * @return Whether deletion succeeded
348 */
349Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path) {
350 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); 344 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle);
351 if (archive == nullptr) 345 if (archive == nullptr)
352 return -1; 346 return InvalidHandle(ErrorModule::FS);
353 if (archive->backend->DeleteFile(path)) 347 if (archive->backend->DeleteFile(path))
354 return 0; 348 return RESULT_SUCCESS;
355 return -1; 349 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
350 ErrorSummary::Canceled, ErrorLevel::Status);
356} 351}
357 352
358/** 353ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path,
359 * Delete a Directory from an Archive 354 Handle dest_archive_handle, const FileSys::Path& dest_path) {
360 * @param archive_handle Handle to an open Archive object 355 Archive* src_archive = Kernel::g_object_pool.GetFast<Archive>(src_archive_handle);
361 * @param path Path to the Directory inside of the Archive 356 Archive* dest_archive = Kernel::g_object_pool.GetFast<Archive>(dest_archive_handle);
362 * @return Whether deletion succeeded 357 if (src_archive == nullptr || dest_archive == nullptr)
363 */ 358 return InvalidHandle(ErrorModule::FS);
364Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { 359 if (src_archive == dest_archive) {
360 if (src_archive->backend->RenameFile(src_path, dest_path))
361 return RESULT_SUCCESS;
362 } else {
363 // TODO: Implement renaming across archives
364 return UnimplementedFunction(ErrorModule::FS);
365 }
366 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
367 ErrorSummary::NothingHappened, ErrorLevel::Status);
368}
369
370ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) {
365 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); 371 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle);
366 if (archive == nullptr) 372 if (archive == nullptr)
367 return -1; 373 return InvalidHandle(ErrorModule::FS);
368 if (archive->backend->DeleteDirectory(path)) 374 if (archive->backend->DeleteDirectory(path))
369 return 0; 375 return RESULT_SUCCESS;
370 return -1; 376 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
377 ErrorSummary::Canceled, ErrorLevel::Status);
371} 378}
372 379
373/** 380ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) {
374 * Create a Directory from an Archive
375 * @param archive_handle Handle to an open Archive object
376 * @param path Path to the Directory inside of the Archive
377 * @return Whether creation succeeded
378 */
379Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) {
380 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); 381 Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle);
381 if (archive == nullptr) 382 if (archive == nullptr)
382 return -1; 383 return InvalidHandle(ErrorModule::FS);
383 if (archive->backend->CreateDirectory(path)) 384 if (archive->backend->CreateDirectory(path))
384 return 0; 385 return RESULT_SUCCESS;
385 return -1; 386 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
387 ErrorSummary::Canceled, ErrorLevel::Status);
388}
389
390ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path,
391 Handle dest_archive_handle, const FileSys::Path& dest_path) {
392 Archive* src_archive = Kernel::g_object_pool.GetFast<Archive>(src_archive_handle);
393 Archive* dest_archive = Kernel::g_object_pool.GetFast<Archive>(dest_archive_handle);
394 if (src_archive == nullptr || dest_archive == nullptr)
395 return InvalidHandle(ErrorModule::FS);
396 if (src_archive == dest_archive) {
397 if (src_archive->backend->RenameDirectory(src_path, dest_path))
398 return RESULT_SUCCESS;
399 } else {
400 // TODO: Implement renaming across archives
401 return UnimplementedFunction(ErrorModule::FS);
402 }
403 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
404 ErrorSummary::NothingHappened, ErrorLevel::Status);
386} 405}
387 406
388/** 407/**
diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/kernel/archive.h
index 6fc4f0f25..b50833a2b 100644
--- a/src/core/hle/kernel/archive.h
+++ b/src/core/hle/kernel/archive.h
@@ -50,7 +50,18 @@ ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path
50 * @param path Path to the File inside of the Archive 50 * @param path Path to the File inside of the Archive
51 * @return Whether deletion succeeded 51 * @return Whether deletion succeeded
52 */ 52 */
53Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path); 53ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path);
54
55/**
56 * Rename a File between two Archives
57 * @param src_archive_handle Handle to the source Archive object
58 * @param src_path Path to the File inside of the source Archive
59 * @param dest_archive_handle Handle to the destination Archive object
60 * @param dest_path Path to the File inside of the destination Archive
61 * @return Whether rename succeeded
62 */
63ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path,
64 Handle dest_archive_handle, const FileSys::Path& dest_path);
54 65
55/** 66/**
56 * Delete a Directory from an Archive 67 * Delete a Directory from an Archive
@@ -58,7 +69,7 @@ Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path);
58 * @param path Path to the Directory inside of the Archive 69 * @param path Path to the Directory inside of the Archive
59 * @return Whether deletion succeeded 70 * @return Whether deletion succeeded
60 */ 71 */
61Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); 72ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path);
62 73
63/** 74/**
64 * Create a Directory from an Archive 75 * Create a Directory from an Archive
@@ -66,7 +77,18 @@ Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& pa
66 * @param path Path to the Directory inside of the Archive 77 * @param path Path to the Directory inside of the Archive
67 * @return Whether creation of directory succeeded 78 * @return Whether creation of directory succeeded
68 */ 79 */
69Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); 80ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path);
81
82/**
83 * Rename a Directory between two Archives
84 * @param src_archive_handle Handle to the source Archive object
85 * @param src_path Path to the Directory inside of the source Archive
86 * @param dest_archive_handle Handle to the destination Archive object
87 * @param dest_path Path to the Directory inside of the destination Archive
88 * @return Whether rename succeeded
89 */
90ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path,
91 Handle dest_archive_handle, const FileSys::Path& dest_path);
70 92
71/** 93/**
72 * Open a Directory from an Archive 94 * Open a Directory from an Archive
diff --git a/src/core/hle/service/fs_user.cpp b/src/core/hle/service/fs_user.cpp
index 34af78cb9..51e8b579e 100644
--- a/src/core/hle/service/fs_user.cpp
+++ b/src/core/hle/service/fs_user.cpp
@@ -159,7 +159,49 @@ void DeleteFile(Service::Interface* self) {
159 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", 159 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s",
160 filename_type, filename_size, file_path.DebugStr().c_str()); 160 filename_type, filename_size, file_path.DebugStr().c_str());
161 161
162 cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path); 162 cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path).raw;
163
164 DEBUG_LOG(KERNEL, "called");
165}
166
167/*
168 * FS_User::RenameFile service function
169 * Inputs:
170 * 2 : Source archive handle lower word
171 * 3 : Source archive handle upper word
172 * 4 : Source file path type
173 * 5 : Source file path size
174 * 6 : Dest archive handle lower word
175 * 7 : Dest archive handle upper word
176 * 8 : Dest file path type
177 * 9 : Dest file path size
178 * 11: Source file path string data
179 * 13: Dest file path string
180 * Outputs:
181 * 1 : Result of function, 0 on success, otherwise error code
182 */
183void RenameFile(Service::Interface* self) {
184 u32* cmd_buff = Service::GetCommandBuffer();
185
186 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
187 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
188 Handle src_archive_handle = static_cast<Handle>(cmd_buff[3]);
189 auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
190 u32 src_filename_size = cmd_buff[5];
191 Handle dest_archive_handle = static_cast<Handle>(cmd_buff[7]);
192 auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]);
193 u32 dest_filename_size = cmd_buff[9];
194 u32 src_filename_ptr = cmd_buff[11];
195 u32 dest_filename_ptr = cmd_buff[13];
196
197 FileSys::Path src_file_path(src_filename_type, src_filename_size, src_filename_ptr);
198 FileSys::Path dest_file_path(dest_filename_type, dest_filename_size, dest_filename_ptr);
199
200 DEBUG_LOG(KERNEL, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s",
201 src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(),
202 dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str());
203
204 cmd_buff[1] = Kernel::RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw;
163 205
164 DEBUG_LOG(KERNEL, "called"); 206 DEBUG_LOG(KERNEL, "called");
165} 207}
@@ -190,7 +232,7 @@ void DeleteDirectory(Service::Interface* self) {
190 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", 232 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s",
191 dirname_type, dirname_size, dir_path.DebugStr().c_str()); 233 dirname_type, dirname_size, dir_path.DebugStr().c_str());
192 234
193 cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path); 235 cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path).raw;
194 236
195 DEBUG_LOG(KERNEL, "called"); 237 DEBUG_LOG(KERNEL, "called");
196} 238}
@@ -220,11 +262,53 @@ static void CreateDirectory(Service::Interface* self) {
220 262
221 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); 263 DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str());
222 264
223 cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path); 265 cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path).raw;
224 266
225 DEBUG_LOG(KERNEL, "called"); 267 DEBUG_LOG(KERNEL, "called");
226} 268}
227 269
270/*
271 * FS_User::RenameDirectory service function
272 * Inputs:
273 * 2 : Source archive handle lower word
274 * 3 : Source archive handle upper word
275 * 4 : Source dir path type
276 * 5 : Source dir path size
277 * 6 : Dest archive handle lower word
278 * 7 : Dest archive handle upper word
279 * 8 : Dest dir path type
280 * 9 : Dest dir path size
281 * 11: Source dir path string data
282 * 13: Dest dir path string
283 * Outputs:
284 * 1 : Result of function, 0 on success, otherwise error code
285 */
286void RenameDirectory(Service::Interface* self) {
287 u32* cmd_buff = Service::GetCommandBuffer();
288
289 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
290 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
291 Handle src_archive_handle = static_cast<Handle>(cmd_buff[3]);
292 auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
293 u32 src_dirname_size = cmd_buff[5];
294 Handle dest_archive_handle = static_cast<Handle>(cmd_buff[7]);
295 auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]);
296 u32 dest_dirname_size = cmd_buff[9];
297 u32 src_dirname_ptr = cmd_buff[11];
298 u32 dest_dirname_ptr = cmd_buff[13];
299
300 FileSys::Path src_dir_path(src_dirname_type, src_dirname_size, src_dirname_ptr);
301 FileSys::Path dest_dir_path(dest_dirname_type, dest_dirname_size, dest_dirname_ptr);
302
303 DEBUG_LOG(KERNEL, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s",
304 src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(),
305 dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str());
306
307 cmd_buff[1] = Kernel::RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw;
308
309 DEBUG_LOG(KERNEL, "called");
310}
311
228static void OpenDirectory(Service::Interface* self) { 312static void OpenDirectory(Service::Interface* self) {
229 u32* cmd_buff = Service::GetCommandBuffer(); 313 u32* cmd_buff = Service::GetCommandBuffer();
230 314
@@ -314,12 +398,12 @@ const Interface::FunctionInfo FunctionTable[] = {
314 {0x080201C2, OpenFile, "OpenFile"}, 398 {0x080201C2, OpenFile, "OpenFile"},
315 {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, 399 {0x08030204, OpenFileDirectly, "OpenFileDirectly"},
316 {0x08040142, DeleteFile, "DeleteFile"}, 400 {0x08040142, DeleteFile, "DeleteFile"},
317 {0x08050244, nullptr, "RenameFile"}, 401 {0x08050244, RenameFile, "RenameFile"},
318 {0x08060142, DeleteDirectory, "DeleteDirectory"}, 402 {0x08060142, DeleteDirectory, "DeleteDirectory"},
319 {0x08070142, nullptr, "DeleteDirectoryRecursively"}, 403 {0x08070142, nullptr, "DeleteDirectoryRecursively"},
320 {0x08080202, nullptr, "CreateFile"}, 404 {0x08080202, nullptr, "CreateFile"},
321 {0x08090182, CreateDirectory, "CreateDirectory"}, 405 {0x08090182, CreateDirectory, "CreateDirectory"},
322 {0x080A0244, nullptr, "RenameDirectory"}, 406 {0x080A0244, RenameDirectory, "RenameDirectory"},
323 {0x080B0102, OpenDirectory, "OpenDirectory"}, 407 {0x080B0102, OpenDirectory, "OpenDirectory"},
324 {0x080C00C2, OpenArchive, "OpenArchive"}, 408 {0x080C00C2, OpenArchive, "OpenArchive"},
325 {0x080D0144, nullptr, "ControlArchive"}, 409 {0x080D0144, nullptr, "ControlArchive"},