INTERNET.CPP 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /counterstrike/INTERNET.CPP 6 3/17/97 1:05a Steve_tall $ */
  15. /*************************************************************************************
  16. ** 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 **
  17. *************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer - Red Alert *
  20. * *
  21. * File Name : INTERNET.CPP *
  22. * *
  23. * Programmer : Steve Tall *
  24. * *
  25. * Start Date : March 11th, 1996 *
  26. * *
  27. * Last Update : August 5th, 1996 [ST] *
  28. * *
  29. *-----------------------------------------------------------------------------------*
  30. * Overview: *
  31. * *
  32. * Miscellaneous junk related to H2H internet connection. *
  33. * *
  34. *-----------------------------------------------------------------------------------*
  35. * Functions: *
  36. * Check_From_WChat -- Interprets start game packet from WChat *
  37. * Read_Game_Options -- Read the game setup options from the wchat packet *
  38. * Is_User_WChat_Registered -- retrieve the users wchat entry from registry *
  39. * Spawn_WChat -- spawns or switches focus to wchat *
  40. * Spawn_Registration_App -- spawns the C&C/Planet westwood registration app *
  41. * Do_The_Internet_Menu_Thang -- Handle case where user clicks on 'Internet' button *
  42. * *
  43. * *
  44. * *
  45. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  46. #ifdef WIN32
  47. #include "function.h"
  48. #include "tcpip.h"
  49. #include "ccdde.h"
  50. extern bool SpawnedFromWChat;
  51. #ifndef WOLAPI_INTEGRATION
  52. int Read_Game_Options(void);
  53. #endif
  54. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  55. extern bool Is_Mission_126x126 (char *file_name);
  56. extern bool Is_Mission_Aftermath (char *file_name);
  57. extern bool Is_Mission_Counterstrike (char *file_name);
  58. #endif
  59. /***************************************************************************
  60. ** Internet specific globals
  61. */
  62. char PlanetWestwoodHandle[] = {"Handle"}; //Planet WW user name
  63. char PlanetWestwoodPassword[] = {"Password"}; //Planet WW password
  64. char PlanetWestwoodIPAddress[IP_ADDRESS_MAX] = {"206.154.108.87"}; //IP of server or other player
  65. long PlanetWestwoodPortNumber = 1234; //Port number to send to
  66. bool PlanetWestwoodIsHost = false; //Flag true if player has control of game options
  67. unsigned long PlanetWestwoodGameID; //Game ID
  68. unsigned long PlanetWestwoodStartTime; //Time that game was started
  69. HWND WChatHWND = 0; //Handle to Wchat window.
  70. bool GameStatisticsPacketSent; //Flag that game stats have been sent to wchat
  71. bool ConnectionLost; //Flag that the connection to the other player was lost
  72. int WChatMaxAhead;
  73. int WChatSendRate;
  74. bool SpawnedFromWChat;
  75. int ShowCommand;
  76. #ifdef FRENCH
  77. #define TXT_HACKHACK "Connexion En Cours..."
  78. #endif
  79. #if defined(ENGLISH) || defined(GERMAN)
  80. #define TXT_HACKHACK Text_String(TXT_CONNECTING)
  81. #endif
  82. /***********************************************************************************************
  83. * Check_From_WChat -- This function reads in C&CSPAWN.INI and interprets it. *
  84. * C&CSPAWN.INI is now sent to us by WCHAT via DDE *
  85. * *
  86. * *
  87. * INPUT: Name of C&CSPAWN.INI file. If NULL then get file from DDE Server. *
  88. * *
  89. * OUTPUT: Nothing *
  90. * *
  91. * WARNINGS: None *
  92. * *
  93. * HISTORY: *
  94. * 6/9/96 1:44PM ST : Created *
  95. *=============================================================================================*/
  96. #ifndef WOLAPI_INTEGRATION
  97. void Check_From_WChat(char *wchat_name)
  98. {
  99. char default_string[] = {"Error"};
  100. char key_string[256];
  101. char *ini_file;
  102. RawFileClass wchat_file;
  103. /*
  104. ** Get a pointer to C&CSPAWN.INI either by reading it from disk or getting it from
  105. ** the DDE server.
  106. */
  107. if (wchat_name){
  108. ini_file = new char [8192];
  109. }else{
  110. ini_file = DDEServer.Get_MPlayer_Game_Info();
  111. #ifdef NEVER
  112. /*
  113. ** Save it to disk as well so I can see it
  114. */
  115. RawFileClass anotherfile ("FROMCHAT.TXT");
  116. anotherfile.Write(ini_file, DDEServer.Get_MPlayer_Game_Info_Length());
  117. #endif
  118. }
  119. if (wchat_name){
  120. wchat_file.Set_Name(wchat_name);
  121. }
  122. if (!wchat_name || wchat_file.Is_Available()){
  123. /*
  124. ** Read the ini file from disk if we founf it there
  125. */
  126. if (wchat_name){
  127. wchat_file.Read(ini_file, wchat_file.Size());
  128. }
  129. /*
  130. ** Get the IP address
  131. */
  132. key_string[0] = 0;
  133. WWGetPrivateProfileString("Internet",
  134. "Address",
  135. default_string,
  136. key_string,
  137. sizeof(key_string),
  138. ini_file);
  139. if (!strcmp (key_string, default_string)) {
  140. if (wchat_name) delete ini_file;
  141. return;
  142. }
  143. strcpy (PlanetWestwoodIPAddress, key_string);
  144. /*
  145. ** Get the port number
  146. */
  147. key_string[0] = 0;
  148. WWGetPrivateProfileString("Internet",
  149. "Port",
  150. default_string,
  151. key_string,
  152. sizeof(key_string),
  153. ini_file);
  154. if (!strcmp (key_string, default_string)) {
  155. if (wchat_name) delete ini_file;
  156. return;
  157. }
  158. PlanetWestwoodPortNumber = atol(key_string);
  159. /*
  160. ** Get host or client
  161. */
  162. key_string[0] = 0;
  163. WWGetPrivateProfileString("Internet",
  164. "Host",
  165. default_string,
  166. key_string,
  167. sizeof(key_string),
  168. ini_file);
  169. if (!strcmp (key_string, default_string)) {
  170. if (wchat_name) delete ini_file;
  171. return;
  172. }
  173. if (strchr (key_string, '1')){
  174. PlanetWestwoodIsHost = true;
  175. }else{
  176. PlanetWestwoodIsHost = false;
  177. }
  178. Special.IsFromWChat = true;
  179. }
  180. if (wchat_name) delete ini_file;
  181. }
  182. #endif // !WOLAPI_INTEGRATION
  183. /***************************************************************************
  184. * Read_Game_Options -- reads multiplayer game options from disk *
  185. * *
  186. * This routine is used for multiplayer games which read the game options *
  187. * from disk, rather than through a connection dialog. *
  188. * *
  189. * INPUT: *
  190. * name of C&CSPAWN.INI file. Null if data should be got from DDE server* *
  191. * OUTPUT: *
  192. * 1 = OK, 0 = error *
  193. * *
  194. * WARNINGS: \ *
  195. * none. *
  196. * *
  197. * HISTORY: *
  198. * 01/11/1996 BRR : Created. *
  199. *=========================================================================*/
  200. #ifndef WOLAPI_INTEGRATION
  201. int Read_Game_Options(char *name)
  202. {
  203. char *buffer;
  204. char filename[256] = {"INVALID.123"};
  205. if (name){
  206. strcpy (filename, name);
  207. }
  208. /*------------------------------------------------------------------------
  209. Create filename and read the file.
  210. ------------------------------------------------------------------------*/
  211. CCFileClass file (filename);
  212. if (name && !file.Is_Available()) {
  213. return(0);
  214. } else {
  215. if (name){
  216. buffer = new char [8192]; // INI staging buffer pointer.
  217. memset(buffer, '\0', 8192);
  218. file.Read(buffer, 8192-1);
  219. file.Close();
  220. }else{
  221. buffer = DDEServer.Get_MPlayer_Game_Info();
  222. }
  223. }
  224. /*------------------------------------------------------------------------
  225. Get the player's name
  226. ------------------------------------------------------------------------*/
  227. WWGetPrivateProfileString("Options", "Handle", "Noname", Session.Handle,
  228. sizeof(Session.Handle), buffer);
  229. strcpy(Session.GameName, Session.Handle);
  230. Session.ColorIdx = (PlayerColorType) WWGetPrivateProfileInt("Options", "Color", 0, buffer);
  231. Session.PrefColor = Session.ColorIdx;
  232. int temp = WWGetPrivateProfileInt("Options", "Side", 0, buffer);
  233. Session.House = (HousesType) ((int)HOUSE_USSR + temp);
  234. Session.Options.Credits = WWGetPrivateProfileInt("Options", "Credits", 0, buffer);
  235. Session.Options.Bases = WWGetPrivateProfileInt("Options", "Bases", 0, buffer);
  236. Session.Options.Tiberium = WWGetPrivateProfileInt("Options", "Tiberium", 0, buffer);
  237. Session.Options.Goodies = WWGetPrivateProfileInt("Options", "Crates", 0, buffer);
  238. Special.IsShadowGrow = WWGetPrivateProfileInt ("Options", "Shadow", 0, buffer);
  239. BuildLevel = WWGetPrivateProfileInt("Options", "BuildLevel", 0, buffer);
  240. Session.Options.UnitCount = WWGetPrivateProfileInt("Options", "UnitCount", 0, buffer);
  241. Seed = WWGetPrivateProfileInt("Options", "Seed", 0, buffer);
  242. Special.IsCaptureTheFlag = WWGetPrivateProfileInt("Options", "CapFlag", 0, buffer);
  243. UnitBuildPenalty = WWGetPrivateProfileInt ("Options", "BuildRate", 100, buffer);
  244. PlanetWestwoodGameID = WWGetPrivateProfileInt("Internet", "GameID", 0, buffer);
  245. PlanetWestwoodStartTime = WWGetPrivateProfileInt ("Internet", "StartTime", 0, buffer);
  246. WChatHWND = (HWND) WWGetPrivateProfileInt("Internet", "HWND", (int)FindWindow("OWL_Window", "Westwood Chat"), buffer);
  247. Session.Options.AIPlayers = WWGetPrivateProfileInt("Options", "AI", 0, buffer); //Number of AI players
  248. if (Session.Options.AIPlayers){
  249. Session.Options.Ghosts = 1;
  250. }
  251. if (Session.Options.Tiberium) {
  252. Special.IsTGrowth = 1;
  253. Special.IsTSpread = 1;
  254. } else {
  255. Special.IsTGrowth = 0;
  256. Special.IsTSpread = 0;
  257. }
  258. /*
  259. ** Read the scenario name from the .INI and try to match it with a scenario file in our list.
  260. */
  261. WWGetPrivateProfileString("Options", "Scenario", "SCM01EA.INI",
  262. Session.Options.ScenarioDescription,
  263. sizeof (Session.Options.ScenarioDescription),
  264. buffer);
  265. //WWDebugString ("RA95I - Scenario is ");
  266. //WWDebugString (Session.Options.ScenarioDescription);
  267. //WWDebugString ("\n");
  268. Session.Options.ScenarioIndex = -1;
  269. for (int i = 0; i < Session.Scenarios.Count(); i++) {
  270. if (!strcmp (Session.Scenarios[i]->Description(), Session.Options.ScenarioDescription) ){
  271. Session.Options.ScenarioIndex = i;
  272. break;
  273. }
  274. }
  275. if (PlanetWestwoodIsHost){
  276. /*
  277. ** Special new kludge for counterstrike.
  278. **
  279. ** The only time the file can be unavailable is if its a counterstrike
  280. ** mission and the CS CD is not in the drive so
  281. ** make sure the counterstrike CD is in the drive.
  282. **
  283. ** If Counterstrike is installed then force the CD
  284. ** to be there.
  285. **
  286. */
  287. if (Session.Options.ScenarioIndex == -1) {
  288. //WWDebugString ("RA95I - Session.Options.ScenarioIndex == -1\n");
  289. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  290. if( (Expansion_CS_Present() && Is_Mission_Counterstrike(Session.ScenarioFileName)) ||
  291. (Expansion_AM_Present() && Is_Mission_Aftermath(Session.ScenarioFileName)) ) {
  292. #else
  293. if ( Expansion_CS_Present() ) {
  294. #endif
  295. int current_drive = CCFileClass::Get_CD_Drive();
  296. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  297. int index=Get_CD_Index(current_drive, 1*60);
  298. bool needcd = false;
  299. if (Is_Mission_Counterstrike(Session.ScenarioFileName)) {
  300. if (index != 2 && index != 3) {
  301. RequiredCD = 2;
  302. needcd = true;
  303. }
  304. }
  305. if (Is_Mission_Aftermath(Session.ScenarioFileName)) {
  306. if (index != 3) {
  307. RequiredCD = 3;
  308. needcd = true;
  309. }
  310. }
  311. if (needcd) {
  312. #else
  313. if ( Get_CD_Index(current_drive, 1*60) != 2 ){
  314. RequiredCD = 2;
  315. #endif
  316. //WWDebugString ("RA95I - CounterStrike CD not in drive\n");
  317. if (!Force_CD_Available (RequiredCD)){
  318. if (!RunningAsDLL) { //PG
  319. Emergency_Exit(EXIT_FAILURE);
  320. }
  321. }
  322. //WWDebugString ("RA95I - Returned from Force_CD_Available()\n");
  323. /*
  324. ** Update the internal list of scenarios to include the counterstrike
  325. ** list.
  326. */
  327. Session.Read_Scenario_Descriptions();
  328. }
  329. }
  330. /*
  331. ** See if that scenario is available now. Its fatal if it isnt.
  332. */
  333. Session.Options.ScenarioIndex = -1;
  334. for (int i = 0; i < Session.Scenarios.Count(); i++) {
  335. if (!strcmp (Session.Scenarios[i]->Description(), Session.Options.ScenarioDescription) ){
  336. Session.Options.ScenarioIndex = i;
  337. break;
  338. }
  339. }
  340. //if (Session.Options.ScenarioIndex == -1)
  341. // WWDebugString ("RA95I - Session.Options.ScenarioIndex is still -1\n");
  342. }
  343. }
  344. Options.GameSpeed = 0;
  345. //MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse);
  346. Session.MaxAhead = WChatMaxAhead = WWGetPrivateProfileInt("Timing", "MaxAhead", 9, buffer);
  347. Session.FrameSendRate = WChatSendRate = WWGetPrivateProfileInt("Timing", "SendRate", 3, buffer);
  348. if (name) delete buffer;
  349. return (1);
  350. }
  351. #endif // !WOLAPI_INTEGRATION
  352. /***********************************************************************************************
  353. * Get_Registry_Sub_Key -- search a registry key for a sub-key *
  354. * *
  355. * *
  356. * *
  357. * INPUT: handle of key to search *
  358. * text to search for *
  359. * true if old key should be closed when new key opened *
  360. * *
  361. * OUTPUT: handle to the key we found or 0 *
  362. * *
  363. * WARNINGS: None *
  364. * *
  365. * HISTORY: *
  366. * 1/12/96 2:11PM ST : Created *
  367. *=============================================================================================*/
  368. extern HKEY Get_Registry_Sub_Key (HKEY base_key, char *search_key, BOOL close);
  369. void Just_Path(char *path, char *destpath)
  370. {
  371. char *terminator = NULL; //He'll be back.
  372. strcpy (destpath, path);
  373. terminator = strrchr (destpath, '\\');
  374. if (terminator){
  375. *terminator = 0;
  376. }
  377. }
  378. /***********************************************************************************************
  379. * Is_User_WChat_Registered -- retrieve the users wchat entry from the registry *
  380. * *
  381. * *
  382. * *
  383. * INPUT: Nothing *
  384. * *
  385. * OUTPUT: TRUE if users wchat entry was found in the registry *
  386. * *
  387. * WARNINGS: None *
  388. * *
  389. * HISTORY: *
  390. * 1/12/96 2:13PM ST : Created *
  391. *=============================================================================================*/
  392. bool Is_User_WChat_Registered(char *buffer, int buffer_len)
  393. {
  394. // ST - 5/13/2019
  395. buffer; buffer_len;
  396. return false;
  397. #if (0)
  398. HKEY key;
  399. char user_handle[256];
  400. DWORD user_handle_size = sizeof (user_handle);
  401. char user_pword[256];
  402. DWORD user_pword_size = sizeof (user_pword);
  403. /*
  404. ** Check HKEY_CLASSES_ROOT first. Old versions of Wchat register there
  405. */
  406. key = Get_Registry_Sub_Key (HKEY_CLASSES_ROOT, "Wchat", FALSE);
  407. if (key){
  408. key = Get_Registry_Sub_Key (key, "Nick1", TRUE);
  409. if (key){
  410. if (RegQueryValue(key, "Nick", user_handle, (long*)&user_handle_size) == ERROR_SUCCESS){
  411. if (RegQueryValue(key, "Pass", user_pword, (long*)&user_pword_size) == ERROR_SUCCESS){
  412. /*
  413. ** If the first char of the users name is non-numberic and there is a password
  414. ** then return success
  415. */
  416. if ((user_handle[0] < '0' || user_handle[0] > '9') && user_pword[0]){
  417. RegCloseKey( key );
  418. return (TRUE);
  419. }
  420. }
  421. }
  422. }
  423. RegCloseKey ( key );
  424. }
  425. /*
  426. ** Check HKEY_LOCAL_MACKINE/Software
  427. */
  428. user_handle_size = sizeof (user_handle);
  429. key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE);
  430. if (!key) return (FALSE);
  431. key = Get_Registry_Sub_Key (key, "Westwood", TRUE);
  432. if (!key) return (FALSE);
  433. key = Get_Registry_Sub_Key (key, "InetReg", TRUE);
  434. if (!key) return (FALSE);
  435. if (RegQueryValueEx(key, "UserName", NULL, NULL, (unsigned char*)user_handle, &user_handle_size) != ERROR_SUCCESS){
  436. RegCloseKey(key);
  437. return (FALSE);
  438. }
  439. RegCloseKey(key);
  440. memcpy (buffer, user_handle, min((unsigned)buffer_len, user_handle_size));
  441. /*
  442. ** If the first char of the users name is non-numeric then return success
  443. */
  444. if (user_handle[0] < '0' || user_handle[0] > '9'){
  445. return (TRUE);
  446. }else{
  447. return (FALSE);
  448. }
  449. #endif
  450. }
  451. /***********************************************************************************************
  452. * Spawn_WChat -- spawns or switches focus to wchat *
  453. * *
  454. * *
  455. * *
  456. * INPUT: can launch. If set then we are allowed to launch WChat if not already running *
  457. * *
  458. * OUTPUT: True if wchat was spawned *
  459. * *
  460. * WARNINGS: None *
  461. * *
  462. * HISTORY: *
  463. * 6/8/96 12:33PM ST : Created *
  464. *=============================================================================================*/
  465. #ifndef WOLAPI_INTEGRATION
  466. bool Poke_WChat(void);
  467. bool Spawn_WChat(bool can_launch)
  468. {
  469. // ST - 5/13/2019
  470. can_launch;
  471. return false;
  472. #if (0)
  473. WWDebugString ("RA95 - In Spawn_WChat.\n");
  474. char packet[10] = {"Hello"};
  475. HWND chat_window = NULL;
  476. /*
  477. ** See if WChat is already running...
  478. */
  479. if (WChatHWND && IsWindow (WChatHWND) ){
  480. chat_window = WChatHWND;
  481. }else{
  482. chat_window = FindWindow ( "OWL_Window", "Westwood Chat" );
  483. }
  484. if (chat_window){
  485. /*
  486. ** WChat is already running. Minimize myself then try to give it focus.
  487. */
  488. BlackPalette.Set();
  489. VisiblePage.Clear();
  490. ShowWindow (MainWindow, SW_MINIMIZE);
  491. /*
  492. ** Give windoze a couple of secs to sort itself out.
  493. */
  494. CountDownTimerClass wibble_timer;
  495. wibble_timer.Set ( 60 * 3, true);
  496. while (wibble_timer.Time()){
  497. /*
  498. ** Call our message loop to make sure we get all the messages that are sent to us
  499. ** when we minimise.
  500. */
  501. Keyboard->Check();
  502. }
  503. /*
  504. ** Send chat a tickle message so it knows to send the game stats to the server.
  505. */
  506. if (GameStatisticsPacketSent && !PlanetWestwoodIsHost) {
  507. Send_Data_To_DDE_Server (packet, strlen(packet), DDEServerClass::DDE_TICKLE);
  508. }
  509. //Send_Data_To_DDE_Server (packet, strlen(packet), DDEServerClass::DDE_TICKLE);
  510. /*
  511. ** Give the focus to WChat
  512. */
  513. SetForegroundWindow ( chat_window );
  514. ShowWindow ( chat_window, SW_RESTORE );
  515. return(true);
  516. }
  517. /*
  518. ** Fail if we aren't allowed to launch wchat and we couldnt find its window.
  519. */
  520. if (!can_launch) return (false);
  521. /*
  522. ** Find where WChat was installed to
  523. */
  524. HKEY key;
  525. char wchat_loc[256];
  526. DWORD wchat_loc_size = 256;
  527. key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE);
  528. if (!key) return (FALSE);
  529. key = Get_Registry_Sub_Key (key, "Westwood", TRUE);
  530. if (!key) return (FALSE);
  531. key = Get_Registry_Sub_Key (key, "WChat", TRUE);
  532. if (!key) return (FALSE);
  533. //key = Get_Registry_Sub_Key (key, "UserName", TRUE);
  534. //if (!key) return (FALSE);
  535. //key = Get_Registry_Sub_Key (key, "Nick", TRUE);
  536. //if (!key) return (FALSE);
  537. if (RegQueryValueEx(key, "InstallPath", NULL, NULL, (unsigned char*)wchat_loc, &wchat_loc_size) != ERROR_SUCCESS){
  538. RegCloseKey(key);
  539. return (FALSE);
  540. }
  541. RegCloseKey(key);
  542. PROCESS_INFORMATION process_info;
  543. STARTUPINFO start_info;
  544. memset ((void*)&start_info, 0, sizeof(start_info));
  545. start_info.cb = sizeof(start_info);
  546. char justpath [256];
  547. Just_Path(wchat_loc, justpath);
  548. /*
  549. ** We found WChat in the registry. Minimize myself then try to spawn it.
  550. */
  551. BlackPalette.Set();
  552. VisiblePage.Clear();
  553. ShowWindow (MainWindow, SW_MINIMIZE);
  554. /*
  555. ** Give windoze a couple of secs to sort itself out.
  556. */
  557. CountDownTimerClass wibble_timer;
  558. wibble_timer.Set ( 60 * 3, true);
  559. while (wibble_timer.Time()){
  560. /*
  561. ** Call our message loop to make sure we get all the messages that are sent to us
  562. ** when we minimise.
  563. */
  564. Keyboard->Check();
  565. }
  566. bool success = CreateProcess (wchat_loc, NULL, NULL, NULL, false, 0, NULL, justpath, &start_info, &process_info);
  567. if (success){
  568. return (true);
  569. }else{
  570. ShowWindow (MainWindow, SW_RESTORE);
  571. while ( Keyboard->Check() ) {};
  572. return (false);
  573. }
  574. #endif
  575. }
  576. #endif //#ifndef WOLAPI_INTEGRATION
  577. /***********************************************************************************************
  578. * Spawn_Registration_App -- spawns the C&C/Planet westwood registration app *
  579. * *
  580. * *
  581. * *
  582. * INPUT: Nothing *
  583. * *
  584. * OUTPUT: True if app was spawned *
  585. * *
  586. * WARNINGS: None *
  587. * *
  588. * HISTORY: *
  589. * 6/8/96 12:33PM ST : Created *
  590. *=============================================================================================*/
  591. #ifndef WOLAPI_INTEGRATION
  592. bool Spawn_Registration_App(void)
  593. {
  594. // ST - 5/13/2019
  595. return false;
  596. #if (0)
  597. /*
  598. ** Find where inetreg was installed to
  599. */
  600. HKEY key;
  601. char inetreg_loc[256];
  602. DWORD inetreg_loc_size = 256;
  603. key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "SOFTWARE", FALSE);
  604. if (!key) return (FALSE);
  605. key = Get_Registry_Sub_Key (key, "Westwood", TRUE);
  606. if (!key) return (FALSE);
  607. key = Get_Registry_Sub_Key (key, "InetReg", TRUE);
  608. if (!key) return (FALSE);
  609. if (RegQueryValueEx(key, "InstallPath", NULL, NULL, (unsigned char*)inetreg_loc, &inetreg_loc_size) != ERROR_SUCCESS){
  610. RegCloseKey(key);
  611. return (FALSE);
  612. }
  613. RegCloseKey(key);
  614. PROCESS_INFORMATION process_info;
  615. STARTUPINFO start_info;
  616. char justpath [256];
  617. memset ((void*)&start_info, 0, sizeof(start_info));
  618. start_info.cb = sizeof(start_info);
  619. Just_Path(inetreg_loc, justpath);
  620. BOOL success = CreateProcess (inetreg_loc, NULL, NULL, NULL, false, 0, NULL, justpath, &start_info, &process_info);
  621. if (success){
  622. //WaitForSingleObject (process_info.hProcess, 1000*10000);
  623. //SetForegroundWindow ( MainWindow );
  624. //ShowWindow ( MainWindow, SW_RESTORE );
  625. }
  626. return (success);
  627. #endif
  628. }
  629. #endif //#ifndef WOLAPI_INTEGRATION
  630. /***********************************************************************************************
  631. * Do_The_Internet_Menu_Thang -- Handle case where user clicks on 'Internet' button *
  632. * *
  633. * *
  634. * *
  635. * INPUT: Nothing *
  636. * *
  637. * OUTPUT: Nothing *
  638. * *
  639. * WARNINGS: None *
  640. * *
  641. * HISTORY: *
  642. * 6/7/96 8:30PM ST : Created *
  643. *=============================================================================================*/
  644. #ifndef WOLAPI_INTEGRATION
  645. bool Do_The_Internet_Menu_Thang(void)
  646. {
  647. #if (0) //PG
  648. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  649. char packet[10] = {"Hello"};
  650. /*
  651. ** Dialog & button dimensions
  652. */
  653. int d_dialog_w = 120 *factor; // dialog width
  654. int d_dialog_h = 80*factor; // dialog height
  655. int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord
  656. int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord
  657. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord
  658. int d_margin1=10;
  659. int d_txt6_h=15;
  660. #if (GERMAN | FRENCH)
  661. int d_cancel_w = 50*factor;
  662. #else
  663. int d_cancel_w = 40*factor;
  664. #endif
  665. int d_cancel_h = 9*factor;
  666. int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
  667. int d_cancel_y = d_dialog_y + d_dialog_h - 20*factor;
  668. int width;
  669. int height;
  670. Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(),
  671. TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
  672. Format_Window_String((char*)TXT_HACKHACK, SeenBuff.Get_Height(), width, height);
  673. /*
  674. ** Button Enumerations
  675. */
  676. enum {
  677. BUTTON_CANCEL = 100,
  678. };
  679. /*
  680. ** Buttons
  681. */
  682. //TextButtonClass *buttons; // button list
  683. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL,
  684. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  685. //#if (GERMAN | FRENCH)
  686. // d_cancel_x, d_cancel_y);
  687. //#else
  688. d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
  689. //#endif
  690. //buttons = &cancelbtn;
  691. Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(),
  692. TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
  693. char users_name[256];
  694. int buffer_len = sizeof (users_name);
  695. bool process;
  696. bool display;
  697. KeyNumType input;
  698. if (!Special.IsFromWChat && !SpawnedFromWChat){
  699. /*
  700. ** If the user is registered with Planet Westwood then spawn WChat.
  701. */
  702. if (Is_User_WChat_Registered(users_name, buffer_len)){
  703. GameStatisticsPacketSent = false;
  704. if (!Spawn_WChat(true)){
  705. Set_Logic_Page(SeenBuff);
  706. Load_Title_Page(true);
  707. Set_Palette(CCPalette);
  708. WWMessageBox().Process(TXT_ERROR_UNABLE_TO_RUN_WCHAT, TXT_OK);
  709. LogicPage->Clear();
  710. return(false);
  711. }
  712. }else{
  713. /*
  714. ** OK, whatever, just run WChat anyway.
  715. */
  716. if (!Spawn_WChat (true)){
  717. Set_Logic_Page(SeenBuff);
  718. Load_Title_Page(true);
  719. Set_Palette(CCPalette);
  720. //WWMessageBox().Process(TXT_EXPLAIN_REGISTRATION, TXT_CANCEL);
  721. WWMessageBox().Process(TXT_NO_REG_APP, TXT_CANCEL);
  722. }
  723. Load_Title_Page(true);
  724. return(false);
  725. }
  726. }
  727. /*
  728. **
  729. ** User is registered and we spawned WChat. Wait for a game start message from WChat.
  730. **
  731. */
  732. process = true;
  733. display = true;
  734. while (process){
  735. /*
  736. ** If we have just received input focus again after running in the background then
  737. ** we need to redraw.
  738. */
  739. if (AllSurfaces.SurfacesRestored){
  740. AllSurfaces.SurfacesRestored = FALSE;
  741. display = true;
  742. }
  743. if (display) {
  744. Set_Logic_Page(SeenBuff);
  745. Hide_Mouse();
  746. /*
  747. ** Redraw backgound & dialog box
  748. */
  749. Load_Title_Page(true);
  750. Set_Palette(CCPalette);
  751. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  752. /*
  753. ** Dialog & Field labels
  754. */
  755. Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w);
  756. Fancy_Text_Print(TXT_HACKHACK, d_dialog_cx-width/2, d_dialog_y + 25*factor,
  757. GadgetClass::Get_Color_Scheme(), TBLACK,
  758. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  759. //cancelbtn.Zap();
  760. //buttons = &cancelbtn;
  761. /*
  762. .................... Rebuild the button list ....................
  763. */
  764. //buttons->Draw_All();
  765. cancelbtn.Draw_Me(true);
  766. Show_Mouse();
  767. display = false;
  768. }
  769. /*
  770. ** See if the game start packet has arrived from wchat yet.
  771. */
  772. if (DDEServer.Get_MPlayer_Game_Info()){
  773. //MessageBox (NULL, "About to restore focus to C&C95", "C&C95", MB_OK);
  774. //SetForegroundWindow ( MainWindow );
  775. //ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
  776. return(true);
  777. }
  778. //input = buttons->Input();
  779. input = cancelbtn.Input();
  780. /*
  781. ---------------------------- Process input ----------------------------
  782. */
  783. switch (input) {
  784. /*
  785. ** Cancel. Just return to the main menu
  786. */
  787. case (KN_ESC):
  788. case (BUTTON_CANCEL | KN_BUTTON):
  789. process = false;
  790. Send_Data_To_DDE_Server (packet, strlen(packet), DDEServerClass::DDE_CONNECTION_FAILED);
  791. GameStatisticsPacketSent = false;
  792. Spawn_WChat(false);
  793. break;
  794. }
  795. }
  796. #endif
  797. return (false);
  798. }
  799. #endif //#ifndef WOLAPI_INTEGRATION
  800. #endif //WIN32