MAIN.CPP 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. ** Command & Conquer Red Alert(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. C O N F I D E N T I A L --- W E S T W O O D S T U D I O S
  20. *******************************************************************************
  21. File: main.cpp
  22. Programmer: Neal Kettler
  23. StartDate: Feb 6, 1998
  24. LastUpdate: Feb 10, 1998
  25. -------------------------------------------------------------------------------
  26. Launcher application for games/apps using the chat API. This should be
  27. run by the user and it will start the actual game executable. If a patch
  28. file has been downloaded the patch will be applied before starting the game.
  29. This does not download patches or do version checks, the game/app is responsible
  30. for that. This just applies patches that are in the correct location for the
  31. game. All patches should be in the "Patches" folder of the app.
  32. The launcher should have a config file (launcher.cfg) so it knows which apps
  33. should be checked for patches. The file should look like this:
  34. # comment
  35. # RUN = the game to launch
  36. RUN = . notepad.exe # directory and app name
  37. #
  38. # Sku's to check for patches
  39. #
  40. SKU1 = 1100 SOFTWARE\Westwood\WOnline # skus and registry keys
  41. SKU2 = 1234 SOFTWARE\Westwood\FakeGame
  42. \*****************************************************************************/
  43. #include "dialog.h"
  44. #include "patch.h"
  45. #include "findpatch.h"
  46. #include "process.h"
  47. #include "wdebug.h"
  48. #include "monod.h"
  49. #include "filed.h"
  50. #include "configfile.h"
  51. #include <windows.h>
  52. #define UPDATE_RETVAL 123456789 // if a program returns this it means it wants to check for patches
  53. void CreatePrimaryWin(char *prefix);
  54. void myChdir(char *path);
  55. //
  56. // Called by WinMain
  57. //
  58. int main(int argc, char *argv[])
  59. {
  60. char patchFile[MAX_PATH];
  61. bit8 ok;
  62. int skuIndex=0;
  63. char cwd[MAX_PATH]; // save current directory before game start
  64. _getcwd(cwd,MAX_PATH);
  65. InitCommonControls();
  66. #ifdef DEBUG
  67. ///MonoD outputDevice;
  68. FileD outputDevice("launcher.out");
  69. MsgManager::setAllStreams(&outputDevice);
  70. DBGMSG("Launcher initialized");
  71. #endif
  72. // Goto the folder where launcher is installed
  73. myChdir(argv[0]);
  74. // extract the program name from argv[0]. Change the extension to
  75. // .lcf (Launcher ConFig). This is the name of our config file.
  76. char configName[MAX_PATH+3];
  77. strcpy(configName,argv[0]);
  78. char *extension=configName;
  79. char *tempptr;
  80. while((tempptr=strchr(extension+1,'.')))
  81. extension=tempptr;
  82. if (*extension=='.')
  83. *extension=0;
  84. strcat(configName,".lcf");
  85. DBGMSG("Config Name: "<<configName);
  86. ConfigFile config;
  87. FILE *in=fopen(configName,"r");
  88. if (in==NULL)
  89. {
  90. MessageBox(NULL,"You must run the game from its install directory.",
  91. "Launcher config file missing",MB_OK);
  92. exit(-1);
  93. }
  94. ok=config.readFile(in);
  95. fclose(in);
  96. if(ok==FALSE)
  97. {
  98. MessageBox(NULL,"File 'launcher.cfg' is corrupt","Error",MB_OK);
  99. exit(-1);
  100. }
  101. // Load process info
  102. Process proc;
  103. Read_Process_Info(config,proc);
  104. DBGMSG("Read process info");
  105. // Create the main window
  106. ///CreatePrimaryWin(proc.command);
  107. while((skuIndex=Find_Patch(patchFile,MAX_PATH,config))!=0)
  108. Apply_Patch(patchFile,config,skuIndex);
  109. Delete_Patches(config); // delete all patches
  110. for (int i=1; i<argc; i++)
  111. {
  112. strcat(proc.args," ");
  113. strcat(proc.args,argv[i]);
  114. }
  115. DBGMSG("ARGS: "<<proc.args);
  116. while(1)
  117. {
  118. myChdir(argv[0]);
  119. Create_Process(proc);
  120. Wait_Process(proc);
  121. if((skuIndex=Find_Patch(patchFile,MAX_PATH,config))!=0)
  122. {
  123. do
  124. {
  125. Apply_Patch(patchFile,config,skuIndex);
  126. } while((skuIndex=Find_Patch(patchFile,MAX_PATH,config))!=0);
  127. }
  128. else
  129. {
  130. break;
  131. }
  132. }
  133. myChdir(cwd);
  134. // Exit normally
  135. return(0);
  136. }
  137. //
  138. // Create a primary window
  139. //
  140. void CreatePrimaryWin(char *prefix)
  141. {
  142. HWND hwnd;
  143. WNDCLASS wc;
  144. char name[256];
  145. sprintf(name,"launcher_%s",prefix);
  146. DBGMSG("CreatePrimary: "<<name);
  147. /*
  148. ** set up and register window class
  149. */
  150. wc.style = CS_HREDRAW | CS_VREDRAW;
  151. wc.lpfnWndProc = DefWindowProc;
  152. wc.cbClsExtra = 0; // Don't need any extra class data
  153. wc.cbWndExtra = 0; // No extra win data
  154. wc.hInstance = Global_instance;
  155. wc.hIcon=LoadIcon(Global_instance, MAKEINTRESOURCE(IDI_ICON));
  156. wc.hCursor = NULL; /////////LoadCursor( NULL, IDC_ARROW );
  157. wc.hbrBackground = NULL;
  158. wc.lpszMenuName = name;
  159. wc.lpszClassName = name;
  160. RegisterClass( &wc );
  161. /*
  162. ** create a window
  163. */
  164. hwnd = CreateWindowEx(
  165. WS_EX_TOPMOST,
  166. name,
  167. name,
  168. WS_POPUP,
  169. 0, 0,
  170. GetSystemMetrics( SM_CXSCREEN ),
  171. GetSystemMetrics( SM_CYSCREEN ),
  172. NULL,
  173. NULL,
  174. Global_instance,
  175. NULL );
  176. if( !hwnd )
  177. {
  178. DBGMSG("Couldn't make window!");
  179. }
  180. else
  181. {
  182. DBGMSG("Window created!");
  183. }
  184. }
  185. //void DestroyPrimaryWin(void)
  186. //{
  187. // DestroyWindow(PrimaryWin);
  188. // UnregisterClass(classname);
  189. //}
  190. //
  191. // If given a file, it'll goto it's directory. If on a diff drive,
  192. // it'll go there.
  193. //
  194. void myChdir(char *path)
  195. {
  196. char drive[10];
  197. char dir[255];
  198. char file[255];
  199. char ext[64];
  200. char filepath[513];
  201. int abc;
  202. _splitpath( path, drive, dir, file, ext );
  203. _makepath ( filepath, drive, dir, NULL, NULL );
  204. if ( filepath[ strlen( filepath ) - 1 ] == '\\' )
  205. {
  206. filepath[ strlen( filepath ) - 1 ] = '\0';
  207. }
  208. abc = (unsigned)( toupper( filepath[0] ) - 'A' + 1 );
  209. if ( !_chdrive( abc ))
  210. {
  211. abc = chdir( filepath ); // Will fail with ending '\\'
  212. }
  213. // should be in proper folder now....
  214. }