dllmain.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <Windows.h>
  2. #include <intrin.h>
  3. #include "client/hooks/egress/runtime.h"
  4. #include "client/hooks/network/investment/internal.h"
  5. #include "core/runtime/core_runtime.h"
  6. #include "steam/runtime/internal.h"
  7. #include "steam/runtime/runtime.h"
  8. namespace {
  9. HMODULE g_module{};
  10. }
  11. /** @return True when the egress guard and Core initialize from this DLL module. */
  12. extern "C" __declspec(dllexport) bool SunriseInitialize() noexcept {
  13. if (!sunrise::client::hooks::egress::install() || !sunrise::core::initialize(g_module)) {
  14. return false;
  15. }
  16. // This export is one of two entry points; the guard reports once, whichever ran first.
  17. sunrise::client::hooks::egress::report_installation();
  18. return true;
  19. }
  20. /** @return True when the guard is in place and Client hooks activate. */
  21. extern "C" __declspec(dllexport) bool SunriseActivateClient() noexcept {
  22. return sunrise::client::hooks::egress::is_installed()
  23. && sunrise::steam::runtime::activate_main_once();
  24. }
  25. /** @return True when the whole runtime shuts down cleanly. */
  26. extern "C" __declspec(dllexport) bool SunriseShutdown() noexcept {
  27. return sunrise::steam::shutdown();
  28. }
  29. /** @return True when the Steam-compatible runtime initializes. */
  30. extern "C" __declspec(dllexport) bool SteamAPI_Init() noexcept {
  31. return sunrise::steam::initialize(g_module);
  32. }
  33. /** Stops the Steam-compatible runtime. */
  34. extern "C" __declspec(dllexport) void SteamAPI_Shutdown() noexcept {
  35. (void)sunrise::steam::shutdown();
  36. }
  37. /** Delivers one batch of callbacks on the caller thread. */
  38. extern "C" __declspec(dllexport) void SteamAPI_RunCallbacks() noexcept {
  39. sunrise::steam::run_callbacks();
  40. }
  41. /**
  42. * Stores the app id. The process is never restarted.
  43. * @return False because the in-process shim never asks for a restart.
  44. */
  45. extern "C" __declspec(dllexport) bool SteamAPI_RestartAppIfNecessary(DWORD appId) noexcept {
  46. sunrise::steam::set_app_id(appId);
  47. return false;
  48. }
  49. /** @return True because this DLL provides the process-local Steam runtime. */
  50. extern "C" __declspec(dllexport) bool SteamAPI_IsSteamRunning() noexcept {
  51. return sunrise::steam::is_running();
  52. }
  53. /** @return The shim's single Steam user handle. */
  54. extern "C" __declspec(dllexport) sunrise::steam::UserHandle SteamAPI_GetHSteamUser() noexcept {
  55. return sunrise::steam::user_handle();
  56. }
  57. /** @return The shim's single Steam pipe handle. */
  58. extern "C" __declspec(dllexport) sunrise::steam::PipeHandle SteamAPI_GetHSteamPipe() noexcept {
  59. return sunrise::steam::pipe_handle();
  60. }
  61. /**
  62. * Registers a Steam callback object.
  63. * @param callback Steam-owned callback object.
  64. * @param callbackId Steam callback type id.
  65. */
  66. extern "C" __declspec(dllexport) void SteamAPI_RegisterCallback(void* callback,
  67. int callbackId) noexcept {
  68. sunrise::steam::register_callback(callback, callbackId);
  69. }
  70. /** @param callback Steam-owned callback object removed from registrations. */
  71. extern "C" __declspec(dllexport) void SteamAPI_UnregisterCallback(void* callback) noexcept {
  72. sunrise::steam::unregister_callback(callback);
  73. }
  74. /**
  75. * Registers a Steam API call-result object.
  76. * @param callback Steam-owned call-result object.
  77. * @param call Async API call id. Must not be zero.
  78. */
  79. extern "C" __declspec(dllexport) void
  80. SteamAPI_RegisterCallResult(void* callback, sunrise::steam::ApiCall call) noexcept {
  81. sunrise::steam::register_call_result(callback, call);
  82. }
  83. /**
  84. * Removes a Steam API call-result object.
  85. * @param callback Steam-owned call-result object.
  86. * @param call API call to remove, or zero for every call owned by the object.
  87. */
  88. extern "C" __declspec(dllexport) void
  89. SteamAPI_UnregisterCallResult(void* callback, sunrise::steam::ApiCall call) noexcept {
  90. sunrise::steam::unregister_call_result(callback, call);
  91. }
  92. /** @param data Steam-owned context table. @return Address of the interface field, after init. */
  93. extern "C" __declspec(dllexport) void* SteamInternal_ContextInit(void* data) noexcept {
  94. return sunrise::steam::context_init(data);
  95. }
  96. /** @param version Interface version. @return Supported client interface or null. */
  97. extern "C" __declspec(dllexport) void* SteamInternal_CreateInterface(const char* version) noexcept {
  98. return sunrise::steam::create_interface(version, _ReturnAddress());
  99. }
  100. /**
  101. * Finds a supported user interface.
  102. * @param user Process-global zero handle, or the shim's local user handle.
  103. * @param version Interface version.
  104. * @return Supported user interface or null.
  105. */
  106. extern "C" __declspec(dllexport) void*
  107. SteamInternal_FindOrCreateUserInterface(sunrise::steam::UserHandle user,
  108. const char* version) noexcept {
  109. return sunrise::steam::find_or_create_user_interface(user, version);
  110. }
  111. /**
  112. * Saves the DLL module and turns off unused thread notifications. Runs under the loader lock.
  113. * @param instance Loaded DLL module.
  114. * @return TRUE for every supported loader notification.
  115. */
  116. BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID) {
  117. if (reason == DLL_PROCESS_ATTACH) {
  118. g_module = instance;
  119. DisableThreadLibraryCalls(instance);
  120. // Preserve the tested low-address placement; reserve before boot content fills that space.
  121. sunrise::client::hooks::network::investment::reserve_socket_menu_routing_storage();
  122. } else if (reason == DLL_PROCESS_DETACH) {
  123. g_module = nullptr;
  124. }
  125. return TRUE;
  126. }