INTERNET.CPP 32 KB

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