CopyProtection.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: CopyProtection.cpp //////////////////////////////////////////////////
  24. // Author: Matthew D. Campbell
  25. // Taken From: Denzil Long's code in Tiberian Sun, by way of Yuri's Revenge
  26. //////////////////////////////////////////////////////////////////////////////
  27. #include "PreRTS.h"
  28. #include "Common/CopyProtection.h"
  29. #ifndef DO_COPY_PROTECTION
  30. //#pragma MESSAGE("*********************************************************")
  31. //#pragma MESSAGE("************* COPY PROTECTION IS DISABLED ***************")
  32. //#pragma MESSAGE("*********************************************************")
  33. #else
  34. LPVOID CopyProtect::s_protectedData = NULL;
  35. static const char* const LAUNCHER_GUID =
  36. "150C6462-4E49-4ccf-B073-57579569D994"; // Generals Multiplayer Test Launcher GUID
  37. static const char* const protectGUID =
  38. "6096561D-8A70-48ed-9FF8-18552419E50D"; // Generals Multiplayer Test Protect GUID
  39. /*
  40. static const char* const LAUNCHER_GUID =
  41. "FB327081-64F2-43d8-9B72-503C3B765134"; // Generals Launcher GUID
  42. static const char* const protectGUID =
  43. "7BEB9006-CC19-4aca-913A-C870A88DE01A"; // Generals Protect GUID
  44. */
  45. #if defined(_DEBUG) || defined(_INTERNAL)
  46. Bool skipProtection(void)
  47. {
  48. //return FALSE;
  49. if (FindWindow("Afx:400000:8:10011:0:fe8e0125", NULL) != NULL) // DevStudio
  50. {
  51. DEBUG_LOG(("DevStudio is running - skipping notifyLauncher()\n"));
  52. return TRUE;
  53. }
  54. //return FALSE;
  55. return TRUE;
  56. }
  57. #endif
  58. // ---------------------------------------------------------------------------
  59. Bool CopyProtect::isLauncherRunning(void)
  60. {
  61. DEBUG_LOG(("COPYPROTECTION - Checking if launcher is running\n"));
  62. HANDLE launcherMutex = CreateMutex(NULL, FALSE, LAUNCHER_GUID);
  63. Bool isRunning = (GetLastError() == ERROR_ALREADY_EXISTS);
  64. if (launcherMutex != NULL)
  65. {
  66. CloseHandle(launcherMutex);
  67. }
  68. DEBUG_LOG(("result was %d\n", (int)isRunning));
  69. #if defined(_DEBUG) || defined(_INTERNAL)
  70. if (skipProtection())
  71. {
  72. DEBUG_LOG(("DevStudio is running - forcing to TRUE\n"));
  73. return TRUE;
  74. }
  75. #endif
  76. return isRunning;
  77. }
  78. // ---------------------------------------------------------------------------
  79. Bool CopyProtect::notifyLauncher(void)
  80. {
  81. DEBUG_LOG(("COPYPROTECTION - Notify launcher\n"));
  82. #if defined(_DEBUG) || defined(_INTERNAL)
  83. if (skipProtection())
  84. {
  85. DEBUG_LOG(("DevStudio is running - skipping notifyLauncher()\n"));
  86. return TRUE;
  87. }
  88. #endif
  89. // Force system to create message queue
  90. MSG msg;
  91. PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
  92. // Signal launcher to send the beef
  93. unsigned long eventTime = (timeGetTime() + 60000);
  94. HANDLE event = NULL;
  95. while (timeGetTime() < eventTime)
  96. {
  97. event = OpenEvent(EVENT_MODIFY_STATE, TRUE, protectGUID);
  98. if (event)
  99. {
  100. break;
  101. }
  102. Sleep(0);
  103. }
  104. if (event)
  105. {
  106. SetEvent(event);
  107. CloseHandle(event);
  108. DEBUG_LOG(("Launcher notified.\n"));
  109. DEBUG_LOG(("Waiting for message from launcher.\n"));
  110. unsigned long endTime = (timeGetTime() + 10000);
  111. while (timeGetTime() <= endTime)
  112. {
  113. if (PeekMessage(&msg, NULL, 0xBEEF, 0xBEEF, PM_REMOVE))
  114. {
  115. // 0xBEEF is in the WM_APP - 0xBFFF range
  116. if (msg.message == 0xBEEF)
  117. {
  118. DEBUG_LOG(("COPYPROTECTION - Received message from launcher (Elapsed time %ld).\n",
  119. (10000 - (endTime - timeGetTime()))));
  120. HANDLE mappedFile = (HANDLE)msg.lParam;
  121. s_protectedData = MapViewOfFileEx(mappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
  122. if (s_protectedData == NULL)
  123. {
  124. DEBUG_LOG(("***** MapViewOfFileEx() Failed!\n"));
  125. break;
  126. }
  127. DEBUG_LOG(("The message says: %s\n", s_protectedData));
  128. return TRUE;
  129. }
  130. }
  131. Sleep(0);
  132. }
  133. DEBUG_LOG(("***** Failed to notify launcher!\n"));
  134. return FALSE;
  135. }
  136. else
  137. {
  138. DEBUG_LOG(("***** Failed to notify launcher!\n"));
  139. }
  140. return FALSE;
  141. }
  142. // ---------------------------------------------------------------------------
  143. void CopyProtect::checkForMessage(UINT message, LPARAM lParam)
  144. {
  145. // 0xBEEF is in the WM_APP - 0xBFFF range
  146. if (message == 0xBEEF)
  147. {
  148. DEBUG_LOG(("COPYPROTECTION - Received message from launcher.\n"));
  149. HANDLE mappedFile = (HANDLE)lParam;
  150. s_protectedData = MapViewOfFileEx(mappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
  151. if (s_protectedData == NULL)
  152. {
  153. DEBUG_LOG(("***** MapViewOfFileEx() Failed!"));
  154. return;
  155. }
  156. DEBUG_LOG(("The message says: %s\n", s_protectedData));
  157. }
  158. }
  159. // ---------------------------------------------------------------------------
  160. Bool CopyProtect::validate(void)
  161. {
  162. DEBUG_LOG(("COPYPROTECTION - Validating\n"));
  163. DEBUG_LOG(("s_protectedData = %d (%s)\n", s_protectedData, (s_protectedData)?s_protectedData:"EEK!"));
  164. if (s_protectedData != NULL)
  165. {
  166. return (strcmp((const char*)s_protectedData,
  167. "Play the \"Command & Conquer: Generals\" Multiplayer Test.") == 0);
  168. }
  169. #if defined(_DEBUG) || defined(_INTERNAL)
  170. if (skipProtection())
  171. {
  172. DEBUG_LOG(("DevStudio is running - forcing to TRUE\n"));
  173. return TRUE;
  174. }
  175. #endif
  176. return FALSE;
  177. }
  178. // ---------------------------------------------------------------------------
  179. void CopyProtect::shutdown(void)
  180. {
  181. DEBUG_LOG(("COPYPROTECTION - Shutdown\n"));
  182. if (s_protectedData != NULL)
  183. {
  184. UnmapViewOfFile(s_protectedData);
  185. s_protectedData = NULL;
  186. }
  187. }
  188. #endif // DO_COPY_PROTECTION