mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	hle: Use Switch formatted result codes.
This commit is contained in:
		
							parent
							
								
									3e80202604
								
							
						
					
					
						commit
						34571f4d2e
					
				@ -34,61 +34,15 @@ enum {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ResultCode ERROR_INVALID_PATH(ErrCodes::InvalidPath, ErrorModule::FS,
 | 
					// TODO(bunnei): Replace these with correct errors for Switch OS
 | 
				
			||||||
                                        ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
					constexpr ResultCode ERROR_INVALID_PATH(ResultCode(-1));
 | 
				
			||||||
constexpr ResultCode ERROR_UNSUPPORTED_OPEN_FLAGS(ErrCodes::UnsupportedOpenFlags, ErrorModule::FS,
 | 
					constexpr ResultCode ERROR_UNSUPPORTED_OPEN_FLAGS(ResultCode(-1));
 | 
				
			||||||
                                                  ErrorSummary::NotSupported, ErrorLevel::Usage);
 | 
					constexpr ResultCode ERROR_INVALID_OPEN_FLAGS(ResultCode(-1));
 | 
				
			||||||
constexpr ResultCode ERROR_INVALID_OPEN_FLAGS(ErrCodes::InvalidOpenFlags, ErrorModule::FS,
 | 
					constexpr ResultCode ERROR_FILE_NOT_FOUND(ResultCode(-1));
 | 
				
			||||||
                                              ErrorSummary::Canceled, ErrorLevel::Status);
 | 
					constexpr ResultCode ERROR_PATH_NOT_FOUND(ResultCode(-1));
 | 
				
			||||||
constexpr ResultCode ERROR_INVALID_READ_FLAG(ErrCodes::InvalidReadFlag, ErrorModule::FS,
 | 
					constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY(ResultCode(-1));
 | 
				
			||||||
                                             ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
					constexpr ResultCode ERROR_DIRECTORY_ALREADY_EXISTS(ResultCode(-1));
 | 
				
			||||||
constexpr ResultCode ERROR_FILE_NOT_FOUND(ErrCodes::FileNotFound, ErrorModule::FS,
 | 
					constexpr ResultCode ERROR_FILE_ALREADY_EXISTS(ResultCode(-1));
 | 
				
			||||||
                                          ErrorSummary::NotFound, ErrorLevel::Status);
 | 
					constexpr ResultCode ERROR_DIRECTORY_NOT_EMPTY(ResultCode(-1));
 | 
				
			||||||
constexpr ResultCode ERROR_PATH_NOT_FOUND(ErrCodes::PathNotFound, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                          ErrorSummary::NotFound, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_NOT_FOUND(ErrCodes::NotFound, ErrorModule::FS, ErrorSummary::NotFound,
 | 
					 | 
				
			||||||
                                     ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY(ErrCodes::UnexpectedFileOrDirectory,
 | 
					 | 
				
			||||||
                                                        ErrorModule::FS, ErrorSummary::NotSupported,
 | 
					 | 
				
			||||||
                                                        ErrorLevel::Usage);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY_SDMC(ErrCodes::NotAFile, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                                             ErrorSummary::Canceled,
 | 
					 | 
				
			||||||
                                                             ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_DIRECTORY_ALREADY_EXISTS(ErrCodes::DirectoryAlreadyExists,
 | 
					 | 
				
			||||||
                                                    ErrorModule::FS, ErrorSummary::NothingHappened,
 | 
					 | 
				
			||||||
                                                    ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_FILE_ALREADY_EXISTS(ErrCodes::FileAlreadyExists, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                               ErrorSummary::NothingHappened, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_ALREADY_EXISTS(ErrCodes::AlreadyExists, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                          ErrorSummary::NothingHappened, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_DIRECTORY_NOT_EMPTY(ErrCodes::DirectoryNotEmpty, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                               ErrorSummary::Canceled, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_GAMECARD_NOT_INSERTED(ErrCodes::GameCardNotInserted, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                                 ErrorSummary::NotFound, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_INCORRECT_EXEFS_READ_SIZE(ErrCodes::IncorrectExeFSReadSize,
 | 
					 | 
				
			||||||
                                                     ErrorModule::FS, ErrorSummary::NotSupported,
 | 
					 | 
				
			||||||
                                                     ErrorLevel::Usage);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_ROMFS_NOT_FOUND(ErrCodes::RomFSNotFound, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                           ErrorSummary::NotFound, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_COMMAND_NOT_ALLOWED(ErrCodes::CommandNotAllowed, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                               ErrorSummary::WrongArgument, ErrorLevel::Permanent);
 | 
					 | 
				
			||||||
constexpr ResultCode ERROR_EXEFS_SECTION_NOT_FOUND(ErrCodes::ExeFSSectionNotFound, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                                   ErrorSummary::NotFound, ErrorLevel::Status);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Returned when a function is passed an invalid archive handle.
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_ARCHIVE_HANDLE(ErrCodes::ArchiveNotMounted, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                                ErrorSummary::NotFound,
 | 
					 | 
				
			||||||
                                                ErrorLevel::Status); // 0xC8804465
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_WRITE_BEYOND_END(ErrCodes::WriteBeyondEnd, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                          ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Variant of ERROR_NOT_FOUND returned in some places in the code. Unknown if these usages are
 | 
					 | 
				
			||||||
 * correct or a bug.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_NOT_FOUND_INVALID_STATE(ErrCodes::NotFound, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                                 ErrorSummary::InvalidState, ErrorLevel::Status);
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_NOT_FORMATTED(ErrCodes::NotFormatted, ErrorModule::FS,
 | 
					 | 
				
			||||||
                                       ErrorSummary::InvalidState, ErrorLevel::Status);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace FileSys
 | 
					} // namespace FileSys
 | 
				
			||||||
 | 
				
			|||||||
@ -26,9 +26,8 @@ ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path,
 | 
				
			|||||||
ResultCode IVFCArchive::DeleteFile(const Path& path) const {
 | 
					ResultCode IVFCArchive::DeleteFile(const Path& path) const {
 | 
				
			||||||
    LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).",
 | 
					    LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).",
 | 
				
			||||||
                 GetName().c_str());
 | 
					                 GetName().c_str());
 | 
				
			||||||
    // TODO(Subv): Verify error code
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
    return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled,
 | 
					    return ResultCode(-1);
 | 
				
			||||||
                      ErrorLevel::Status);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
 | 
					ResultCode IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
 | 
				
			||||||
@ -55,9 +54,8 @@ ResultCode IVFCArchive::DeleteDirectoryRecursively(const Path& path) const {
 | 
				
			|||||||
ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
 | 
					ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
 | 
				
			||||||
    LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).",
 | 
					    LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).",
 | 
				
			||||||
                 GetName().c_str());
 | 
					                 GetName().c_str());
 | 
				
			||||||
    // TODO: Verify error code
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
    return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported,
 | 
					    return ResultCode(-1);
 | 
				
			||||||
                      ErrorLevel::Permanent);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode IVFCArchive::CreateDirectory(const Path& path) const {
 | 
					ResultCode IVFCArchive::CreateDirectory(const Path& path) const {
 | 
				
			||||||
 | 
				
			|||||||
@ -128,10 +128,8 @@ ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_pa
 | 
				
			|||||||
        return RESULT_SUCCESS;
 | 
					        return RESULT_SUCCESS;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
    // exist or similar. Verify.
 | 
					    return ResultCode(-1);
 | 
				
			||||||
    return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
 | 
					 | 
				
			||||||
                      ErrorSummary::NothingHappened, ErrorLevel::Status);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
@ -223,8 +221,9 @@ ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) cons
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_ERROR(Service_FS, "Too large file");
 | 
					    LOG_ERROR(Service_FS, "Too large file");
 | 
				
			||||||
    return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource,
 | 
					
 | 
				
			||||||
                      ErrorLevel::Info);
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
 | 
					    return ResultCode(-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
 | 
					ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
 | 
				
			||||||
@ -260,8 +259,9 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", mount_point.c_str());
 | 
					    LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", mount_point.c_str());
 | 
				
			||||||
    return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled,
 | 
					
 | 
				
			||||||
                      ErrorLevel::Status);
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
 | 
					    return ResultCode(-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
 | 
					ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
 | 
				
			||||||
@ -287,10 +287,8 @@ ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& de
 | 
				
			|||||||
        return RESULT_SUCCESS;
 | 
					        return RESULT_SUCCESS;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't
 | 
					    // TODO(bunnei): Use correct error code
 | 
				
			||||||
    // exist or similar. Verify.
 | 
					    return ResultCode(-1);
 | 
				
			||||||
    return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
 | 
					 | 
				
			||||||
                      ErrorSummary::NothingHappened, ErrorLevel::Status);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory(
 | 
					ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory(
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,6 @@ constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
 | 
				
			|||||||
// These errors are commonly returned by invalid IPC translations, so alias them here for
 | 
					// These errors are commonly returned by invalid IPC translations, so alias them here for
 | 
				
			||||||
// convenience.
 | 
					// convenience.
 | 
				
			||||||
// TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
 | 
					// TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
 | 
				
			||||||
using Kernel::ERR_INVALID_BUFFER_DESCRIPTOR;
 | 
					 | 
				
			||||||
constexpr auto ERR_INVALID_HANDLE = Kernel::ERR_INVALID_HANDLE_OS;
 | 
					constexpr auto ERR_INVALID_HANDLE = Kernel::ERR_INVALID_HANDLE_OS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,81 +23,27 @@ enum {
 | 
				
			|||||||
// WARNING: The kernel is quite inconsistent in it's usage of errors code. Make sure to always
 | 
					// WARNING: The kernel is quite inconsistent in it's usage of errors code. Make sure to always
 | 
				
			||||||
// double check that the code matches before re-using the constant.
 | 
					// double check that the code matches before re-using the constant.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ResultCode ERR_OUT_OF_HANDLES(ErrCodes::OutOfHandles, ErrorModule::Kernel,
 | 
					// TODO(bunnei): Replace these with correct errors for Switch OS
 | 
				
			||||||
                                        ErrorSummary::OutOfResource,
 | 
					constexpr ResultCode ERR_OUT_OF_HANDLES(-1);
 | 
				
			||||||
                                        ErrorLevel::Permanent); // 0xD8600413
 | 
					constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(-1);
 | 
				
			||||||
constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(ErrCodes::SessionClosedByRemote, ErrorModule::OS,
 | 
					constexpr ResultCode ERR_PORT_NAME_TOO_LONG(-1);
 | 
				
			||||||
                                                  ErrorSummary::Canceled,
 | 
					constexpr ResultCode ERR_WRONG_PERMISSION(-1);
 | 
				
			||||||
                                                  ErrorLevel::Status); // 0xC920181A
 | 
					constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
 | 
				
			||||||
constexpr ResultCode ERR_PORT_NAME_TOO_LONG(ErrCodes::PortNameTooLong, ErrorModule::OS,
 | 
					constexpr ResultCode ERR_INVALID_ENUM_VALUE(-1);
 | 
				
			||||||
                                            ErrorSummary::InvalidArgument,
 | 
					constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(-1);
 | 
				
			||||||
                                            ErrorLevel::Usage); // 0xE0E0181E
 | 
					constexpr ResultCode ERR_INVALID_COMBINATION(-1);
 | 
				
			||||||
constexpr ResultCode ERR_WRONG_PERMISSION(ErrCodes::WrongPermission, ErrorModule::OS,
 | 
					constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(-1);
 | 
				
			||||||
                                          ErrorSummary::WrongArgument, ErrorLevel::Permanent);
 | 
					constexpr ResultCode ERR_OUT_OF_MEMORY(-1);
 | 
				
			||||||
constexpr ResultCode ERR_INVALID_BUFFER_DESCRIPTOR(ErrCodes::InvalidBufferDescriptor,
 | 
					constexpr ResultCode ERR_INVALID_ADDRESS(-1);
 | 
				
			||||||
                                                   ErrorModule::OS, ErrorSummary::WrongArgument,
 | 
					constexpr ResultCode ERR_INVALID_ADDRESS_STATE(-1);
 | 
				
			||||||
                                                   ErrorLevel::Permanent);
 | 
					constexpr ResultCode ERR_INVALID_HANDLE(-1);
 | 
				
			||||||
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(ErrCodes::MaxConnectionsReached, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                                 ErrorSummary::WouldBlock,
 | 
					 | 
				
			||||||
                                                 ErrorLevel::Temporary); // 0xD0401834
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_NOT_AUTHORIZED(ErrorDescription::NotAuthorized, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                        ErrorSummary::WrongArgument,
 | 
					 | 
				
			||||||
                                        ErrorLevel::Permanent); // 0xD9001BEA
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                            ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                            ErrorLevel::Permanent); // 0xD8E007ED
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(ErrorDescription::InvalidEnumValue,
 | 
					 | 
				
			||||||
                                                ErrorModule::FND, ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                                ErrorLevel::Permanent); // 0xD8E093ED
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_COMBINATION(ErrorDescription::InvalidCombination, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                             ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                             ErrorLevel::Usage); // 0xE0E01BEE
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(ErrorDescription::InvalidCombination,
 | 
					 | 
				
			||||||
                                                    ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                                    ErrorSummary::WrongArgument,
 | 
					 | 
				
			||||||
                                                    ErrorLevel::Permanent); // 0xD90007EE
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_MISALIGNED_ADDRESS(ErrorDescription::MisalignedAddress, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                            ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                            ErrorLevel::Usage); // 0xE0E01BF1
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_MISALIGNED_SIZE(ErrorDescription::MisalignedSize, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                         ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                         ErrorLevel::Usage); // 0xE0E01BF2
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_OUT_OF_MEMORY(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                       ErrorSummary::OutOfResource,
 | 
					 | 
				
			||||||
                                       ErrorLevel::Permanent); // 0xD86007F3
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_NOT_IMPLEMENTED(ErrorDescription::NotImplemented, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                         ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                         ErrorLevel::Usage); // 0xE0E01BF4
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_ADDRESS(ErrorDescription::InvalidAddress, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                         ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                         ErrorLevel::Usage); // 0xE0E01BF5
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_ADDRESS_STATE(ErrorDescription::InvalidAddress, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                               ErrorSummary::InvalidState,
 | 
					 | 
				
			||||||
                                               ErrorLevel::Usage); // 0xE0A01BF5
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_POINTER(ErrorDescription::InvalidPointer, ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                         ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                         ErrorLevel::Permanent); // 0xD8E007F6
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                        ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                        ErrorLevel::Permanent); // 0xD8E007F7
 | 
					 | 
				
			||||||
/// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths.
 | 
					/// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths.
 | 
				
			||||||
constexpr ResultCode ERR_INVALID_HANDLE_OS(ErrorDescription::InvalidHandle, ErrorModule::OS,
 | 
					constexpr ResultCode ERR_INVALID_HANDLE_OS(-1);
 | 
				
			||||||
                                           ErrorSummary::WrongArgument,
 | 
					constexpr ResultCode ERR_NOT_FOUND(-1);
 | 
				
			||||||
                                           ErrorLevel::Permanent); // 0xD9001BF7
 | 
					constexpr ResultCode ERR_OUT_OF_RANGE(-1);
 | 
				
			||||||
constexpr ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
 | 
					constexpr ResultCode ERR_OUT_OF_RANGE_KERNEL(-1);
 | 
				
			||||||
                                   ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
 | 
					constexpr ResultCode RESULT_TIMEOUT(-1);
 | 
				
			||||||
constexpr ResultCode ERR_OUT_OF_RANGE(ErrorDescription::OutOfRange, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                      ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                      ErrorLevel::Usage); // 0xE0E01BFD
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_OUT_OF_RANGE_KERNEL(ErrorDescription::OutOfRange, ErrorModule::Kernel,
 | 
					 | 
				
			||||||
                                             ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                             ErrorLevel::Permanent); // 0xD8E007FD
 | 
					 | 
				
			||||||
constexpr ResultCode RESULT_TIMEOUT(ErrorDescription::Timeout, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                    ErrorSummary::StatusChanged, ErrorLevel::Info);
 | 
					 | 
				
			||||||
/// Returned when Accept() is called on a port with no sessions to be accepted.
 | 
					/// Returned when Accept() is called on a port with no sessions to be accepted.
 | 
				
			||||||
constexpr ResultCode ERR_NO_PENDING_SESSIONS(ErrCodes::NoPendingSessions, ErrorModule::OS,
 | 
					constexpr ResultCode ERR_NO_PENDING_SESSIONS(-1);
 | 
				
			||||||
                                             ErrorSummary::WouldBlock,
 | 
					 | 
				
			||||||
                                             ErrorLevel::Permanent); // 0xD8401823
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Kernel
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -386,9 +386,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
 | 
					    if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
 | 
				
			||||||
        LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point);
 | 
					        LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point);
 | 
				
			||||||
        // TODO: Verify error
 | 
					        // TODO (bunnei): Find the correct error code to use here
 | 
				
			||||||
        return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
 | 
					        return ResultCode(-1);
 | 
				
			||||||
                          ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SharedPtr<Thread> thread(new Thread);
 | 
					    SharedPtr<Thread> thread(new Thread);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,41 +11,14 @@
 | 
				
			|||||||
#include "common/common_funcs.h"
 | 
					#include "common/common_funcs.h"
 | 
				
			||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// All the constants in this file come from http://3dbrew.org/wiki/Error_codes
 | 
					// All the constants in this file come from http://switchbrew.org/index.php?title=Error_codes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Detailed description of the error. Code 0 always means success. Codes 1000 and above are
 | 
					 * Detailed description of the error. Code 0 always means success.
 | 
				
			||||||
 * considered "well-known" and have common values between all modules. The meaning of other codes
 | 
					 | 
				
			||||||
 * vary by module.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
enum class ErrorDescription : u32 {
 | 
					enum class ErrorDescription : u32 {
 | 
				
			||||||
    Success = 0,
 | 
					    Success = 0,
 | 
				
			||||||
 | 
					    RemoteProcessDead = 301,
 | 
				
			||||||
    // Codes 1000 and above are considered "well-known" and have common values between all modules.
 | 
					 | 
				
			||||||
    InvalidSection = 1000,
 | 
					 | 
				
			||||||
    TooLarge = 1001,
 | 
					 | 
				
			||||||
    NotAuthorized = 1002,
 | 
					 | 
				
			||||||
    AlreadyDone = 1003,
 | 
					 | 
				
			||||||
    InvalidSize = 1004,
 | 
					 | 
				
			||||||
    InvalidEnumValue = 1005,
 | 
					 | 
				
			||||||
    InvalidCombination = 1006,
 | 
					 | 
				
			||||||
    NoData = 1007,
 | 
					 | 
				
			||||||
    Busy = 1008,
 | 
					 | 
				
			||||||
    MisalignedAddress = 1009,
 | 
					 | 
				
			||||||
    MisalignedSize = 1010,
 | 
					 | 
				
			||||||
    OutOfMemory = 1011,
 | 
					 | 
				
			||||||
    NotImplemented = 1012,
 | 
					 | 
				
			||||||
    InvalidAddress = 1013,
 | 
					 | 
				
			||||||
    InvalidPointer = 1014,
 | 
					 | 
				
			||||||
    InvalidHandle = 1015,
 | 
					 | 
				
			||||||
    NotInitialized = 1016,
 | 
					 | 
				
			||||||
    AlreadyInitialized = 1017,
 | 
					 | 
				
			||||||
    NotFound = 1018,
 | 
					 | 
				
			||||||
    CancelRequested = 1019,
 | 
					 | 
				
			||||||
    AlreadyExists = 1020,
 | 
					 | 
				
			||||||
    OutOfRange = 1021,
 | 
					 | 
				
			||||||
    Timeout = 1022,
 | 
					 | 
				
			||||||
    InvalidResultValue = 1023,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -56,150 +29,64 @@ enum class ErrorDescription : u32 {
 | 
				
			|||||||
enum class ErrorModule : u32 {
 | 
					enum class ErrorModule : u32 {
 | 
				
			||||||
    Common = 0,
 | 
					    Common = 0,
 | 
				
			||||||
    Kernel = 1,
 | 
					    Kernel = 1,
 | 
				
			||||||
    Util = 2,
 | 
					    FS = 2,
 | 
				
			||||||
    FileServer = 3,
 | 
					    NvidiaTransferMemory = 3,
 | 
				
			||||||
    LoaderServer = 4,
 | 
					    NCM = 5,
 | 
				
			||||||
    TCB = 5,
 | 
					    DD = 6,
 | 
				
			||||||
    OS = 6,
 | 
					    LR = 8,
 | 
				
			||||||
    DBG = 7,
 | 
					    Loader = 9,
 | 
				
			||||||
    DMNT = 8,
 | 
					    CMIF = 10,
 | 
				
			||||||
    PDN = 9,
 | 
					    HIPC = 11,
 | 
				
			||||||
    GX = 10,
 | 
					    PM = 15,
 | 
				
			||||||
    I2C = 11,
 | 
					    NS = 16,
 | 
				
			||||||
    GPIO = 12,
 | 
					    HTC = 18,
 | 
				
			||||||
    DD = 13,
 | 
					    SM = 21,
 | 
				
			||||||
    CODEC = 14,
 | 
					    RO = 22,
 | 
				
			||||||
    SPI = 15,
 | 
					    SDMMC = 24,
 | 
				
			||||||
    PXI = 16,
 | 
					    SPL = 26,
 | 
				
			||||||
    FS = 17,
 | 
					    ETHC = 100,
 | 
				
			||||||
    DI = 18,
 | 
					    I2C = 101,
 | 
				
			||||||
    HID = 19,
 | 
					    Settings = 105,
 | 
				
			||||||
    CAM = 20,
 | 
					    NIFM = 110,
 | 
				
			||||||
    PI = 21,
 | 
					    Display = 114,
 | 
				
			||||||
    PM = 22,
 | 
					    NTC = 116,
 | 
				
			||||||
    PM_LOW = 23,
 | 
					    FGM = 117,
 | 
				
			||||||
    FSI = 24,
 | 
					    PCIE = 120,
 | 
				
			||||||
    SRV = 25,
 | 
					    Friends = 121,
 | 
				
			||||||
    NDM = 26,
 | 
					    SSL = 123,
 | 
				
			||||||
    NWM = 27,
 | 
					    Account = 124,
 | 
				
			||||||
    SOC = 28,
 | 
					    Mii = 126,
 | 
				
			||||||
    LDR = 29,
 | 
					    AM = 128,
 | 
				
			||||||
    ACC = 30,
 | 
					    PlayReport = 129,
 | 
				
			||||||
    RomFS = 31,
 | 
					    PCV = 133,
 | 
				
			||||||
    AM = 32,
 | 
					    OMM = 134,
 | 
				
			||||||
    HIO = 33,
 | 
					    NIM = 137,
 | 
				
			||||||
    Updater = 34,
 | 
					    PSC = 138,
 | 
				
			||||||
    MIC = 35,
 | 
					    USB = 140,
 | 
				
			||||||
    FND = 36,
 | 
					    BTM = 143,
 | 
				
			||||||
    MP = 37,
 | 
					    ERPT = 147,
 | 
				
			||||||
    MPWL = 38,
 | 
					    APM = 148,
 | 
				
			||||||
    AC = 39,
 | 
					    NPNS = 154,
 | 
				
			||||||
    HTTP = 40,
 | 
					    ARP = 157,
 | 
				
			||||||
    DSP = 41,
 | 
					    BOOT = 158,
 | 
				
			||||||
    SND = 42,
 | 
					    NFC = 161,
 | 
				
			||||||
    DLP = 43,
 | 
					    UserlandAssert = 162,
 | 
				
			||||||
    HIO_LOW = 44,
 | 
					    UserlandCrash = 168,
 | 
				
			||||||
    CSND = 45,
 | 
					    HID = 203,
 | 
				
			||||||
    SSL = 46,
 | 
					    Capture = 206,
 | 
				
			||||||
    AM_LOW = 47,
 | 
					    TC = 651,
 | 
				
			||||||
    NEX = 48,
 | 
					    GeneralWebApplet = 800,
 | 
				
			||||||
    Friends = 49,
 | 
					    WifiWebAuthApplet = 809,
 | 
				
			||||||
    RDT = 50,
 | 
					    WhitelistedApplet = 810,
 | 
				
			||||||
    Applet = 51,
 | 
					    ShopN = 811,
 | 
				
			||||||
    NIM = 52,
 | 
					 | 
				
			||||||
    PTM = 53,
 | 
					 | 
				
			||||||
    MIDI = 54,
 | 
					 | 
				
			||||||
    MC = 55,
 | 
					 | 
				
			||||||
    SWC = 56,
 | 
					 | 
				
			||||||
    FatFS = 57,
 | 
					 | 
				
			||||||
    NGC = 58,
 | 
					 | 
				
			||||||
    CARD = 59,
 | 
					 | 
				
			||||||
    CARDNOR = 60,
 | 
					 | 
				
			||||||
    SDMC = 61,
 | 
					 | 
				
			||||||
    BOSS = 62,
 | 
					 | 
				
			||||||
    DBM = 63,
 | 
					 | 
				
			||||||
    Config = 64,
 | 
					 | 
				
			||||||
    PS = 65,
 | 
					 | 
				
			||||||
    CEC = 66,
 | 
					 | 
				
			||||||
    IR = 67,
 | 
					 | 
				
			||||||
    UDS = 68,
 | 
					 | 
				
			||||||
    PL = 69,
 | 
					 | 
				
			||||||
    CUP = 70,
 | 
					 | 
				
			||||||
    Gyroscope = 71,
 | 
					 | 
				
			||||||
    MCU = 72,
 | 
					 | 
				
			||||||
    NS = 73,
 | 
					 | 
				
			||||||
    News = 74,
 | 
					 | 
				
			||||||
    RO = 75,
 | 
					 | 
				
			||||||
    GD = 76,
 | 
					 | 
				
			||||||
    CardSPI = 77,
 | 
					 | 
				
			||||||
    EC = 78,
 | 
					 | 
				
			||||||
    WebBrowser = 79,
 | 
					 | 
				
			||||||
    Test = 80,
 | 
					 | 
				
			||||||
    ENC = 81,
 | 
					 | 
				
			||||||
    PIA = 82,
 | 
					 | 
				
			||||||
    ACT = 83,
 | 
					 | 
				
			||||||
    VCTL = 84,
 | 
					 | 
				
			||||||
    OLV = 85,
 | 
					 | 
				
			||||||
    NEIA = 86,
 | 
					 | 
				
			||||||
    NPNS = 87,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    AVD = 90,
 | 
					 | 
				
			||||||
    L2B = 91,
 | 
					 | 
				
			||||||
    MVD = 92,
 | 
					 | 
				
			||||||
    NFC = 93,
 | 
					 | 
				
			||||||
    UART = 94,
 | 
					 | 
				
			||||||
    SPM = 95,
 | 
					 | 
				
			||||||
    QTM = 96,
 | 
					 | 
				
			||||||
    NFP = 97,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Application = 254,
 | 
					 | 
				
			||||||
    InvalidResult = 255
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A less specific error cause.
 | 
					 | 
				
			||||||
enum class ErrorSummary : u32 {
 | 
					 | 
				
			||||||
    Success = 0,
 | 
					 | 
				
			||||||
    NothingHappened = 1,
 | 
					 | 
				
			||||||
    WouldBlock = 2,
 | 
					 | 
				
			||||||
    OutOfResource = 3, ///< There are no more kernel resources (memory, table slots) to
 | 
					 | 
				
			||||||
                       ///< execute the operation.
 | 
					 | 
				
			||||||
    NotFound = 4,      ///< A file or resource was not found.
 | 
					 | 
				
			||||||
    InvalidState = 5,
 | 
					 | 
				
			||||||
    NotSupported = 6,    ///< The operation is not supported or not implemented.
 | 
					 | 
				
			||||||
    InvalidArgument = 7, ///< Returned when a passed argument is invalid in the current runtime
 | 
					 | 
				
			||||||
                         ///< context. (Invalid handle, out-of-bounds pointer or size, etc.)
 | 
					 | 
				
			||||||
    WrongArgument = 8,   ///< Returned when a passed argument is in an incorrect format for use
 | 
					 | 
				
			||||||
                         ///< with the function. (E.g. Invalid enum value)
 | 
					 | 
				
			||||||
    Canceled = 9,
 | 
					 | 
				
			||||||
    StatusChanged = 10,
 | 
					 | 
				
			||||||
    Internal = 11,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    InvalidResult = 63
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// The severity of the error.
 | 
					 | 
				
			||||||
enum class ErrorLevel : u32 {
 | 
					 | 
				
			||||||
    Success = 0,
 | 
					 | 
				
			||||||
    Info = 1,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Status = 25,
 | 
					 | 
				
			||||||
    Temporary = 26,
 | 
					 | 
				
			||||||
    Permanent = 27,
 | 
					 | 
				
			||||||
    Usage = 28,
 | 
					 | 
				
			||||||
    Reinitialize = 29,
 | 
					 | 
				
			||||||
    Reset = 30,
 | 
					 | 
				
			||||||
    Fatal = 31
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Encapsulates a CTR-OS error code, allowing it to be separated into its constituent fields.
 | 
					/// Encapsulates a CTR-OS error code, allowing it to be separated into its constituent fields.
 | 
				
			||||||
union ResultCode {
 | 
					union ResultCode {
 | 
				
			||||||
    u32 raw;
 | 
					    u32 raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BitField<0, 10, u32> description;
 | 
					    BitField<0, 9, ErrorModule> module;
 | 
				
			||||||
    BitField<10, 8, ErrorModule> module;
 | 
					    BitField<9, 13, u32> description;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    BitField<21, 6, ErrorSummary> summary;
 | 
					 | 
				
			||||||
    BitField<27, 5, ErrorLevel> level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The last bit of `level` is checked by apps and the kernel to determine if a result code is an
 | 
					    // The last bit of `level` is checked by apps and the kernel to determine if a result code is an
 | 
				
			||||||
    // error
 | 
					    // error
 | 
				
			||||||
@ -207,14 +94,11 @@ union ResultCode {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    constexpr explicit ResultCode(u32 raw) : raw(raw) {}
 | 
					    constexpr explicit ResultCode(u32 raw) : raw(raw) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr ResultCode(ErrorDescription description, ErrorModule module, ErrorSummary summary,
 | 
					    constexpr ResultCode(ErrorModule module, ErrorDescription description)
 | 
				
			||||||
                         ErrorLevel level)
 | 
					        : ResultCode(module, static_cast<u32>(description)) {}
 | 
				
			||||||
        : ResultCode(static_cast<u32>(description), module, summary, level) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr ResultCode(u32 description_, ErrorModule module_, ErrorSummary summary_,
 | 
					    constexpr ResultCode(ErrorModule module_, u32 description_)
 | 
				
			||||||
                         ErrorLevel level_)
 | 
					        : raw(module.FormatValue(module_) | description.FormatValue(description_)) {}
 | 
				
			||||||
        : raw(description.FormatValue(description_) | module.FormatValue(module_) |
 | 
					 | 
				
			||||||
              summary.FormatValue(summary_) | level.FormatValue(level_)) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr ResultCode& operator=(const ResultCode& o) {
 | 
					    constexpr ResultCode& operator=(const ResultCode& o) {
 | 
				
			||||||
        raw = o.raw;
 | 
					        raw = o.raw;
 | 
				
			||||||
@ -243,12 +127,6 @@ constexpr bool operator!=(const ResultCode& a, const ResultCode& b) {
 | 
				
			|||||||
/// The default success `ResultCode`.
 | 
					/// The default success `ResultCode`.
 | 
				
			||||||
constexpr ResultCode RESULT_SUCCESS(0);
 | 
					constexpr ResultCode RESULT_SUCCESS(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Might be returned instead of a dummy success for unimplemented APIs.
 | 
					 | 
				
			||||||
constexpr ResultCode UnimplementedFunction(ErrorModule module) {
 | 
					 | 
				
			||||||
    return ResultCode(ErrorDescription::NotImplemented, module, ErrorSummary::NotSupported,
 | 
					 | 
				
			||||||
                      ErrorLevel::Permanent);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This is an optional value type. It holds a `ResultCode` and, if that code is a success code,
 | 
					 * This is an optional value type. It holds a `ResultCode` and, if that code is a success code,
 | 
				
			||||||
 * also holds a result of type `T`. If the code is an error code then trying to access the inner
 | 
					 * also holds a result of type `T`. If the code is an error code then trying to access the inner
 | 
				
			||||||
 | 
				
			|||||||
@ -35,19 +35,11 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Controller;
 | 
					class Controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(1, ErrorModule::SRV, ErrorSummary::WouldBlock,
 | 
					constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1);
 | 
				
			||||||
                                                ErrorLevel::Temporary); // 0xD0406401
 | 
					constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
 | 
				
			||||||
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(2, ErrorModule::SRV, ErrorSummary::WouldBlock,
 | 
					constexpr ResultCode ERR_INVALID_NAME_SIZE(-1);
 | 
				
			||||||
                                                 ErrorLevel::Temporary); // 0xD0406402
 | 
					constexpr ResultCode ERR_NAME_CONTAINS_NUL(-1);
 | 
				
			||||||
constexpr ResultCode ERR_INVALID_NAME_SIZE(5, ErrorModule::SRV, ErrorSummary::WrongArgument,
 | 
					constexpr ResultCode ERR_ALREADY_REGISTERED(-1);
 | 
				
			||||||
                                           ErrorLevel::Permanent); // 0xD9006405
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_ACCESS_DENIED(6, ErrorModule::SRV, ErrorSummary::InvalidArgument,
 | 
					 | 
				
			||||||
                                       ErrorLevel::Permanent); // 0xD8E06406
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument,
 | 
					 | 
				
			||||||
                                           ErrorLevel::Permanent); // 0xD9006407
 | 
					 | 
				
			||||||
constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, ErrorModule::OS,
 | 
					 | 
				
			||||||
                                            ErrorSummary::WrongArgument,
 | 
					 | 
				
			||||||
                                            ErrorLevel::Permanent); // 0xD9001BFC
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ServiceManager {
 | 
					class ServiceManager {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user