DatGen.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. ** Command & Conquer Generals(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. // DatGen.cpp : Defines the entry point for the application.
  19. //
  20. #include <windows.h>
  21. #include <assert.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include "bfish.h"
  25. #include "SafeDisk\CdaPfn.h"
  26. #include <Debug\DebugPrint.h>
  27. void __cdecl doIt(void);
  28. CDAPFN_DECLARE_GLOBAL(doIt, CDAPFN_OVERHEAD_L5, CDAPFN_CONSTRAINT_NONE);
  29. static void doIt(void)
  30. {
  31. // Generate passkey
  32. char passKey[128];
  33. passKey[0] = '\0';
  34. unsigned char installPath[MAX_PATH] = "";
  35. // Get game information
  36. HKEY hKey;
  37. bool usesHKeycurrentUser = false;
  38. LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Electronic Arts\\EA Games\\Generals", 0, KEY_READ, &hKey);
  39. if (result != ERROR_SUCCESS)
  40. {
  41. result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Electronic Arts\\EA Games\\Generals", 0, KEY_READ, &hKey);
  42. usesHKeycurrentUser = true;
  43. }
  44. assert((result == ERROR_SUCCESS) && "Failed to open game registry key");
  45. if (result != ERROR_SUCCESS)
  46. {
  47. return;
  48. }
  49. // Retrieve install path
  50. DWORD type;
  51. DWORD sizeOfBuffer = sizeof(installPath);
  52. result = RegQueryValueEx(hKey, "InstallPath", NULL, &type, installPath, &sizeOfBuffer);
  53. assert((result == ERROR_SUCCESS) && "Failed to obtain game install path!");
  54. assert((strlen((const char*)installPath) > 0) && "Game install path invalid!");
  55. DebugPrint("Game install path: %s\n", installPath);
  56. // Retrieve Hard drive S/N
  57. char drive[8];
  58. _splitpath((const char*)installPath, drive, NULL, NULL, NULL);
  59. strcat(drive, "\\");
  60. DWORD volumeSerialNumber = 0;
  61. DWORD maxComponentLength;
  62. DWORD fileSystemFlags;
  63. BOOL volInfoSuccess = GetVolumeInformation((const char*)drive, NULL, 0,
  64. &volumeSerialNumber, &maxComponentLength, &fileSystemFlags, NULL, 0);
  65. if (volInfoSuccess == FALSE)
  66. {
  67. PrintWin32Error("***** GetVolumeInformation() Failed!");
  68. }
  69. DebugPrint("Drive Serial Number: %lx\n", volumeSerialNumber);
  70. // Add hard drive serial number portion
  71. char volumeSN[16];
  72. sprintf(volumeSN, "%lx-", volumeSerialNumber);
  73. strcat(passKey, volumeSN);
  74. // Retrieve game serial #
  75. unsigned char gameSerialNumber[64];
  76. gameSerialNumber[0] = '\0';
  77. sizeOfBuffer = sizeof(gameSerialNumber);
  78. if (usesHKeycurrentUser)
  79. {
  80. result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Electronic Arts\\EA Games\\Generals\\ergc", 0, KEY_READ, &hKey);
  81. }
  82. else
  83. {
  84. result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Electronic Arts\\EA Games\\Generals\\ergc", 0, KEY_READ, &hKey);
  85. }
  86. assert((result == ERROR_SUCCESS) && "Failed to open game serial registry key");
  87. if (result == ERROR_SUCCESS)
  88. {
  89. result = RegQueryValueEx(hKey, "", NULL, &type, gameSerialNumber, &sizeOfBuffer);
  90. assert((result == ERROR_SUCCESS) && "Failed to obtain game serial number!");
  91. assert((strlen((const char*)gameSerialNumber) > 0) && "Game serial number invalid!");
  92. }
  93. DebugPrint("Game serial number: %s\n", gameSerialNumber);
  94. RegCloseKey(hKey);
  95. // Add game serial number portion
  96. strcat(passKey, (char*)gameSerialNumber);
  97. // Obtain windows product ID
  98. result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &hKey);
  99. assert((result == ERROR_SUCCESS) && "Failed to open windows registry key!");
  100. if (result == ERROR_SUCCESS)
  101. {
  102. // Retrieve Windows Product ID
  103. unsigned char winProductID[64];
  104. winProductID[0] = '\0';
  105. DWORD type;
  106. DWORD sizeOfBuffer = sizeof(winProductID);
  107. result = RegQueryValueEx(hKey, "ProductID", NULL, &type, winProductID, &sizeOfBuffer);
  108. assert((result == ERROR_SUCCESS) && "Failed to obtain windows product ID!");
  109. assert((strlen((const char*)winProductID) > 0) && "Invalid windows product ID");
  110. DebugPrint("Windows Product ID: %s\n", winProductID);
  111. RegCloseKey(hKey);
  112. // Add windows product ID portion
  113. strcat(passKey, "-");
  114. strcat(passKey, (char*)winProductID);
  115. }
  116. DebugPrint("Retrieved PassKey: %s\n", passKey);
  117. const char *plainText = "Play the \"Command & Conquer: Generals\" Multiplayer Test.";
  118. int textLen = strlen(plainText);
  119. char cypherText[128];
  120. DebugPrint("Retrieved PassKey: %s\n", passKey);
  121. // Decrypt protected data into the memory mapped file
  122. BlowfishEngine blowfish;
  123. int len = strlen(passKey);
  124. if (len > BlowfishEngine::MAX_KEY_LENGTH)
  125. len = BlowfishEngine::MAX_KEY_LENGTH;
  126. blowfish.Submit_Key(passKey, len);
  127. blowfish.Encrypt(plainText, textLen, cypherText);
  128. cypherText[textLen] = 0;
  129. DebugPrint("Encrypted data: %s\n", cypherText);
  130. DebugPrint("Install dir = '%s'\n", installPath);
  131. char *lastBackslash = strrchr((char *)installPath, '\\');
  132. if (lastBackslash)
  133. *lastBackslash = 0; // strip of \\game.exe from install path
  134. strcat((char *)installPath, "\\Generals.dat");
  135. DebugPrint("DAT file = '%s'\n", installPath);
  136. FILE *fp = fopen((char *)installPath, "wb");
  137. if (fp)
  138. {
  139. fwrite(cypherText, textLen, 1, fp);
  140. fclose(fp);
  141. }
  142. CDAPFN_ENDMARK(doIt);
  143. }
  144. int APIENTRY WinMain(HINSTANCE hInstance,
  145. HINSTANCE hPrevInstance,
  146. LPSTR lpCmdLine,
  147. int nCmdShow)
  148. {
  149. doIt();
  150. return 0;
  151. }