CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

INTERNET.CPP (33607B)


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