sf: Change interface definition methodology (#1074)

* sf: Begin experimenting with new interface declaration format

* sf: convert fs interfaces to new format

* sf: finish conversion of libstrat to new definitions

* sf: convert loader to new format

* sf: convert spl to new format

* sf: update ncm for new format

* sf: convert pm to new format

* sf: convert ro/sm to new format

* sf: update fatal for new format

* sf: support building dmnt under new scheme

* sf: update ams.mitm for new format

* sf: correct invocation def for pointer holder

* fs: correct 10.x+ user bindings for Get*SpaceSize
This commit is contained in:
SciresM
2020-07-07 17:07:23 -07:00
committed by GitHub
parent 94eb2195d3
commit 9fde97cfdd
190 changed files with 3220 additions and 3172 deletions

View File

@@ -16,7 +16,7 @@
#include <stratosphere.hpp>
#include "pm_boot_mode_service.hpp"
namespace ams::pm::bm {
namespace ams::pm {
namespace {
@@ -26,12 +26,16 @@ namespace ams::pm::bm {
}
/* Override of weakly linked boot_mode_api functions. */
BootMode GetBootMode() {
return g_boot_mode;
}
namespace bm {
BootMode GetBootMode() {
return g_boot_mode;
}
void SetMaintenanceBoot() {
g_boot_mode = BootMode::Maintenance;
}
void SetMaintenanceBoot() {
g_boot_mode = BootMode::Maintenance;
}
/* Service command implementations. */

View File

@@ -16,23 +16,13 @@
#pragma once
#include <stratosphere.hpp>
namespace ams::pm::bm {
namespace ams::pm {
class BootModeService final : public sf::IServiceObject {
private:
enum class CommandId {
GetBootMode = 0,
SetMaintenanceBoot = 1,
};
private:
/* Actual command implementations. */
class BootModeService final {
public:
void GetBootMode(sf::Out<u32> out);
void SetMaintenanceBoot();
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(GetBootMode),
MAKE_SERVICE_COMMAND_META(SetMaintenanceBoot),
};
};
static_assert(pm::impl::IsIBootModeInterface<BootModeService>);
}

View File

@@ -17,49 +17,49 @@
#include "pm_debug_monitor_service.hpp"
#include "impl/pm_process_manager.hpp"
namespace ams::pm::dmnt {
namespace ams::pm {
/* Actual command implementations. */
Result DebugMonitorServiceBase::GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused) {
Result DebugMonitorService::GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused) {
R_UNLESS(out_buf.GetSize() <= std::numeric_limits<s32>::max(), pm::ResultInvalidSize());
return impl::GetModuleIdList(out_count.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), unused);
}
Result DebugMonitorServiceBase::GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids) {
Result DebugMonitorService::GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids) {
R_UNLESS(out_process_ids.GetSize() <= std::numeric_limits<s32>::max(), pm::ResultInvalidSize());
return impl::GetExceptionProcessIdList(out_count.GetPointer(), out_process_ids.GetPointer(), out_process_ids.GetSize());
}
Result DebugMonitorServiceBase::StartProcess(os::ProcessId process_id) {
Result DebugMonitorService::StartProcess(os::ProcessId process_id) {
return impl::StartProcess(process_id);
}
Result DebugMonitorServiceBase::GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id) {
Result DebugMonitorService::GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id) {
return impl::GetProcessId(out.GetPointer(), program_id);
}
Result DebugMonitorServiceBase::HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id) {
Result DebugMonitorService::HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id) {
return impl::HookToCreateProcess(out_hook.GetHandlePointer(), program_id);
}
Result DebugMonitorServiceBase::GetApplicationProcessId(sf::Out<os::ProcessId> out) {
Result DebugMonitorService::GetApplicationProcessId(sf::Out<os::ProcessId> out) {
return impl::GetApplicationProcessId(out.GetPointer());
}
Result DebugMonitorServiceBase::HookToCreateApplicationProcess(sf::OutCopyHandle out_hook) {
Result DebugMonitorService::HookToCreateApplicationProcess(sf::OutCopyHandle out_hook) {
return impl::HookToCreateApplicationProcess(out_hook.GetHandlePointer());
}
Result DebugMonitorServiceBase::ClearHook(u32 which) {
Result DebugMonitorService::ClearHook(u32 which) {
return impl::ClearHook(which);
}
/* Atmosphere extension commands. */
Result DebugMonitorServiceBase::AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id) {
Result DebugMonitorService::AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id) {
return impl::AtmosphereGetProcessInfo(out_process_handle.GetHandlePointer(), out_loc.GetPointer(), out_status.GetPointer(), process_id);
}
Result DebugMonitorServiceBase::AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource) {
Result DebugMonitorService::AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource) {
return impl::AtmosphereGetCurrentLimitInfo(out_cur_val.GetPointer(), out_lim_val.GetPointer(), group, resource);
}

View File

@@ -16,90 +16,24 @@
#pragma once
#include <stratosphere.hpp>
namespace ams::pm::dmnt {
namespace ams::pm {
class DebugMonitorServiceBase : public sf::IServiceObject {
protected:
class DebugMonitorService final {
public:
/* Actual command implementations. */
virtual Result GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused);
virtual Result GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids);
virtual Result StartProcess(os::ProcessId process_id);
virtual Result GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
virtual Result HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id);
virtual Result GetApplicationProcessId(sf::Out<os::ProcessId> out);
virtual Result HookToCreateApplicationProcess(sf::OutCopyHandle out_hook);
virtual Result ClearHook(u32 which);
Result GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused);
Result GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids);
Result StartProcess(os::ProcessId process_id);
Result GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
Result HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id);
Result GetApplicationProcessId(sf::Out<os::ProcessId> out);
Result HookToCreateApplicationProcess(sf::OutCopyHandle out_hook);
Result ClearHook(u32 which);
/* Atmosphere extension commands. */
virtual Result AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
virtual Result AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource);
};
/* This represents modern DebugMonitorService (5.0.0+). */
class DebugMonitorService final : public DebugMonitorServiceBase {
private:
enum class CommandId {
GetExceptionProcessIdList = 0,
StartProcess = 1,
GetProcessId = 2,
HookToCreateProcess = 3,
GetApplicationProcessId = 4,
HookToCreateApplicationProcess = 5,
ClearHook = 6,
AtmosphereGetProcessInfo = 65000,
AtmosphereGetCurrentLimitInfo = 65001,
};
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 5.0.0-* */
MAKE_SERVICE_COMMAND_META(GetExceptionProcessIdList),
MAKE_SERVICE_COMMAND_META(StartProcess),
MAKE_SERVICE_COMMAND_META(GetProcessId),
MAKE_SERVICE_COMMAND_META(HookToCreateProcess),
MAKE_SERVICE_COMMAND_META(GetApplicationProcessId),
MAKE_SERVICE_COMMAND_META(HookToCreateApplicationProcess),
/* 6.0.0-* */
MAKE_SERVICE_COMMAND_META(ClearHook, hos::Version_6_0_0),
/* Atmosphere extensions. */
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
MAKE_SERVICE_COMMAND_META(AtmosphereGetCurrentLimitInfo),
};
};
/* This represents deprecated DebugMonitorService (1.0.0-4.1.0). */
class DebugMonitorServiceDeprecated final : public DebugMonitorServiceBase {
private:
enum class CommandId {
GetModuleIdList = 0,
GetExceptionProcessIdList = 1,
StartProcess = 2,
GetProcessId = 3,
HookToCreateProcess = 4,
GetApplicationProcessId = 5,
HookToCreateApplicationProcess = 6,
AtmosphereGetProcessInfo = 65000,
AtmosphereGetCurrentLimitInfo = 65001,
};
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0-4.1.0 */
MAKE_SERVICE_COMMAND_META(GetModuleIdList),
MAKE_SERVICE_COMMAND_META(GetExceptionProcessIdList),
MAKE_SERVICE_COMMAND_META(StartProcess),
MAKE_SERVICE_COMMAND_META(GetProcessId),
MAKE_SERVICE_COMMAND_META(HookToCreateProcess),
MAKE_SERVICE_COMMAND_META(GetApplicationProcessId),
MAKE_SERVICE_COMMAND_META(HookToCreateApplicationProcess),
/* Atmosphere extensions. */
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
MAKE_SERVICE_COMMAND_META(AtmosphereGetCurrentLimitInfo),
};
Result AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
Result AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource);
};
static_assert(pm::impl::IsIDebugMonitorInterface<DebugMonitorService>);
}

View File

@@ -17,11 +17,15 @@
#include "pm_info_service.hpp"
#include "impl/pm_process_manager.hpp"
namespace ams::pm::info {
namespace ams::pm {
/* Overrides for libstratosphere pm::info commands. */
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
return ldr::pm::HasLaunchedProgram(out, program_id);
namespace info {
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
return ldr::pm::HasLaunchedProgram(out, program_id);
}
}
/* Actual command implementations. */

View File

@@ -16,18 +16,10 @@
#pragma once
#include <stratosphere.hpp>
namespace ams::pm::info {
namespace ams::pm {
class InformationService final : public sf::IServiceObject {
private:
enum class CommandId {
GetProgramId = 0,
AtmosphereGetProcessId = 65000,
AtmosphereHasLaunchedProgram = 65001,
AtmosphereGetProcessInfo = 65002,
};
private:
class InformationService final {
public:
/* Actual command implementations. */
Result GetProgramId(sf::Out<ncm::ProgramId> out, os::ProcessId process_id);
@@ -35,14 +27,7 @@ namespace ams::pm::info {
Result AtmosphereGetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
Result AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id);
Result AtmosphereGetProcessInfo(sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(GetProgramId),
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessId),
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
};
};
static_assert(pm::impl::IsIInformationInterface<InformationService>);
}

View File

@@ -196,14 +196,14 @@ int main(int argc, char **argv)
/* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */
/* Also Note: PM was rewritten in 5.0.0, so the shell and dmnt services are different before/after. */
if (hos::GetVersion() >= hos::Version_5_0_0) {
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellService>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IShellInterface, pm::ShellService>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDebugMonitorInterface, pm::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
} else {
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellServiceDeprecated>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorServiceDeprecated>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDeprecatedShellInterface, pm::ShellService>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDeprecatedDebugMonitorInterface, pm::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
}
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::bm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::info::InformationService>(InformationServiceName, InformationMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IBootModeInterface, pm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IInformationInterface, pm::InformationService>(InformationServiceName, InformationMaxSessions)));
/* Loop forever, servicing our services. */
g_server_manager.LoopProcess();

View File

@@ -17,59 +17,63 @@
#include "pm_shell_service.hpp"
#include "impl/pm_process_manager.hpp"
namespace ams::pm::shell {
namespace ams::pm {
/* Overrides for libstratosphere pm::shell commands. */
Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) {
return impl::LaunchProgram(out_process_id, loc, launch_flags);
namespace shell {
Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) {
return impl::LaunchProgram(out_process_id, loc, launch_flags);
}
}
/* Service command implementations. */
Result ShellServiceBase::LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags) {
Result ShellService::LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags) {
return pm::shell::LaunchProgram(out_process_id.GetPointer(), loc, flags);
}
Result ShellServiceBase::TerminateProcess(os::ProcessId process_id) {
Result ShellService::TerminateProcess(os::ProcessId process_id) {
return impl::TerminateProcess(process_id);
}
Result ShellServiceBase::TerminateProgram(ncm::ProgramId program_id) {
Result ShellService::TerminateProgram(ncm::ProgramId program_id) {
return impl::TerminateProgram(program_id);
}
void ShellServiceBase::GetProcessEventHandle(sf::OutCopyHandle out) {
void ShellService::GetProcessEventHandle(sf::OutCopyHandle out) {
R_ABORT_UNLESS(impl::GetProcessEventHandle(out.GetHandlePointer()));
}
void ShellServiceBase::GetProcessEventInfo(sf::Out<ProcessEventInfo> out) {
void ShellService::GetProcessEventInfo(sf::Out<ProcessEventInfo> out) {
R_ABORT_UNLESS(impl::GetProcessEventInfo(out.GetPointer()));
}
Result ShellServiceBase::CleanupProcess(os::ProcessId process_id) {
Result ShellService::CleanupProcess(os::ProcessId process_id) {
return impl::CleanupProcess(process_id);
}
Result ShellServiceBase::ClearExceptionOccurred(os::ProcessId process_id) {
Result ShellService::ClearExceptionOccurred(os::ProcessId process_id) {
return impl::ClearExceptionOccurred(process_id);
}
void ShellServiceBase::NotifyBootFinished() {
void ShellService::NotifyBootFinished() {
R_ABORT_UNLESS(impl::NotifyBootFinished());
}
Result ShellServiceBase::GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out) {
Result ShellService::GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out) {
return impl::GetApplicationProcessId(out.GetPointer());
}
Result ShellServiceBase::BoostSystemMemoryResourceLimit(u64 boost_size) {
Result ShellService::BoostSystemMemoryResourceLimit(u64 boost_size) {
return impl::BoostSystemMemoryResourceLimit(boost_size);
}
Result ShellServiceBase::BoostApplicationThreadResourceLimit() {
Result ShellService::BoostApplicationThreadResourceLimit() {
return impl::BoostApplicationThreadResourceLimit();
}
void ShellServiceBase::GetBootFinishedEventHandle(sf::OutCopyHandle out) {
void ShellService::GetBootFinishedEventHandle(sf::OutCopyHandle out) {
R_ABORT_UNLESS(impl::GetBootFinishedEventHandle(out.GetHandlePointer()));
}

View File

@@ -16,91 +16,24 @@
#pragma once
#include <stratosphere.hpp>
namespace ams::pm::shell {
namespace ams::pm {
class ShellServiceBase : public sf::IServiceObject {
protected:
class ShellService final {
public:
/* Actual command implementations. */
virtual Result LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags);
virtual Result TerminateProcess(os::ProcessId process_id);
virtual Result TerminateProgram(ncm::ProgramId program_id);
virtual void GetProcessEventHandle(sf::OutCopyHandle out);
virtual void GetProcessEventInfo(sf::Out<ProcessEventInfo> out);
virtual Result CleanupProcess(os::ProcessId process_id);
virtual Result ClearExceptionOccurred(os::ProcessId process_id);
virtual void NotifyBootFinished();
virtual Result GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out);
virtual Result BoostSystemMemoryResourceLimit(u64 boost_size);
virtual Result BoostApplicationThreadResourceLimit();
virtual void GetBootFinishedEventHandle(sf::OutCopyHandle out);
};
/* This represents modern ShellService (5.0.0+). */
class ShellService final : public ShellServiceBase {
private:
enum class CommandId {
LaunchProgram = 0,
TerminateProcess = 1,
TerminateProgram = 2,
GetProcessEventHandle = 3,
GetProcessEventInfo = 4,
NotifyBootFinished = 5,
GetApplicationProcessIdForShell = 6,
BoostSystemMemoryResourceLimit = 7,
BoostApplicationThreadResourceLimit = 8,
GetBootFinishedEventHandle = 9,
};
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 5.0.0-* */
MAKE_SERVICE_COMMAND_META(LaunchProgram),
MAKE_SERVICE_COMMAND_META(TerminateProcess),
MAKE_SERVICE_COMMAND_META(TerminateProgram),
MAKE_SERVICE_COMMAND_META(GetProcessEventHandle),
MAKE_SERVICE_COMMAND_META(GetProcessEventInfo),
MAKE_SERVICE_COMMAND_META(NotifyBootFinished),
MAKE_SERVICE_COMMAND_META(GetApplicationProcessIdForShell),
MAKE_SERVICE_COMMAND_META(BoostSystemMemoryResourceLimit),
/* 7.0.0-* */
MAKE_SERVICE_COMMAND_META(BoostApplicationThreadResourceLimit, hos::Version_7_0_0),
/* 8.0.0-* */
MAKE_SERVICE_COMMAND_META(GetBootFinishedEventHandle, hos::Version_8_0_0),
};
};
/* This represents deprecated ShellService (1.0.0-4.1.0). */
class ShellServiceDeprecated final : public ShellServiceBase {
private:
enum class CommandId {
LaunchProgram = 0,
TerminateProcess = 1,
TerminateProgram = 2,
GetProcessEventHandle = 3,
GetProcessEventInfo = 4,
CleanupProcess = 5,
ClearExceptionOccurred = 6,
NotifyBootFinished = 7,
GetApplicationProcessIdForShell = 8,
BoostSystemMemoryResourceLimit = 9,
};
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0-4.1.0 */
MAKE_SERVICE_COMMAND_META(LaunchProgram),
MAKE_SERVICE_COMMAND_META(TerminateProcess),
MAKE_SERVICE_COMMAND_META(TerminateProgram),
MAKE_SERVICE_COMMAND_META(GetProcessEventHandle),
MAKE_SERVICE_COMMAND_META(GetProcessEventInfo),
MAKE_SERVICE_COMMAND_META(CleanupProcess),
MAKE_SERVICE_COMMAND_META(ClearExceptionOccurred),
MAKE_SERVICE_COMMAND_META(NotifyBootFinished),
MAKE_SERVICE_COMMAND_META(GetApplicationProcessIdForShell),
/* 4.0.0-4.1.0 */
MAKE_SERVICE_COMMAND_META(BoostSystemMemoryResourceLimit, hos::Version_4_0_0),
};
Result LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags);
Result TerminateProcess(os::ProcessId process_id);
Result TerminateProgram(ncm::ProgramId program_id);
void GetProcessEventHandle(sf::OutCopyHandle out);
void GetProcessEventInfo(sf::Out<ProcessEventInfo> out);
Result CleanupProcess(os::ProcessId process_id);
Result ClearExceptionOccurred(os::ProcessId process_id);
void NotifyBootFinished();
Result GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out);
Result BoostSystemMemoryResourceLimit(u64 boost_size);
Result BoostApplicationThreadResourceLimit();
void GetBootFinishedEventHandle(sf::OutCopyHandle out);
};
static_assert(pm::impl::IsIShellInterface<ShellService>);
}