WOL_MAIN.CPP (8298B)
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 #ifdef WOLAPI_INTEGRATION 17 18 // Wol_Main.cpp - Bottom level wolapi-stuff function. 19 // ajw 07/16/98 20 21 #include "function.h" 22 #include "WolapiOb.h" 23 #include "wol_gsup.h" 24 #include "WolStrng.h" 25 26 int WOL_Login_Dialog( WolapiObject* pWolapi ); 27 int WOL_Chat_Dialog( WolapiObject* pWolapi ); 28 const char* Game_Registry_Key(); 29 30 bool ReregisterWolapiDLL(); 31 void HandleDLLFail(); 32 33 WolapiObject* pWolapi = NULL; 34 35 #include "WolDebug.h" 36 37 //*********************************************************************************************** 38 // The first time through, pWolapi is NULL thus wolapi gets set up. WOL_Login_Dialog presents the user 39 // with the login dialog and attempts to log us on to the server. If the user continues on all the 40 // way to a game start, we will drop out of here with pWolapi still pointing to a valid WolapiObject, 41 // and with pWolapi's iLobbyReturnAfterGame set to the number of the lobby to return to automatically 42 // after the game ends. 43 // Init() automatically brings us here if pWolapi is non-null. 44 //*********************************************************************************************** 45 int WOL_Main() 46 { 47 // Return values: 48 // 0 = cancel 49 // 1 = start game 50 // -1 = patch downloaded, shut down app 51 int iReturn = 0; 52 53 if( pWolapi ) 54 { 55 // We have returned from a game started through ww online. 56 57 // Start theme up again. 58 Theme.Play_Song( THEME_INTRO ); 59 60 // Verify that we are still connected. If we aren't, kill WolapiObject and start over. 61 // (This will likely occur during the game, if connection is lost. Ensure that it is done here.) 62 pWolapi->pChat->PumpMessages(); // Causes OnNetStatus() call if no longer connected. 63 if( pWolapi->bConnectionDown ) 64 { 65 //debugprint( "Re-entering WOL_Main(), pWolapi->bConnectionDown is true. Deleting old WolapiObject...\n" ); 66 WWMessageBox().Process( TXT_WOL_WOLAPIREINIT ); 67 // Kill wolapi. 68 pWolapi->UnsetupCOMStuff(); 69 delete pWolapi; 70 pWolapi = NULL; 71 } 72 } 73 74 if( !pWolapi ) 75 { 76 // Start up wolapi. 77 pWolapi = new WolapiObject; 78 if( !pWolapi->bSetupCOMStuff() ) 79 { 80 // Things are really bad if this happens. A COM call failed. 81 82 // We first assume that their wolapi.dll failed to register during wolsetup.exe, part of the patch process. 83 // This happens if they have an outdated oleaut32.dll, such as the one that comes with original 84 // version of Windows 95. 85 86 // debugprint( "bSetupCOMStuff failed. Attemping to reregister wolapi.dll...\n" ); 87 // Attempt to re-register wolapi.dll... 88 if( ReregisterWolapiDLL() ) 89 { 90 if( !pWolapi->bSetupCOMStuff() ) 91 { 92 // Still failed after reregistering seemed to work. 93 HandleDLLFail(); 94 return 0; 95 } 96 } 97 else 98 { 99 HandleDLLFail(); 100 return 0; 101 } 102 } 103 pWolapi->PrepareButtonsAndIcons(); 104 // Undocumented hack needed for patch downloading, per Neal. 105 pWolapi->pChat->SetAttributeValue( "RegPath", Game_Registry_Key() ); 106 // (Not that anything's really "documented".) 107 } 108 109 pWolapi->bInGame = false; 110 111 int iLoginResult = WOL_Login_Dialog( pWolapi ); 112 if( iLoginResult == 1 ) 113 { 114 pWolapi->SetOptionDefaults(); 115 bool bKeepGoing = true; 116 while( bKeepGoing ) 117 { 118 bool bCreator; 119 switch( WOL_Chat_Dialog( pWolapi ) ) 120 { 121 case -1: 122 bKeepGoing = false; 123 break; 124 case 1: 125 // User created game channel. 126 bCreator = true; 127 break; 128 case 2: 129 // User joined game channel. 130 bCreator = false; 131 break; 132 } 133 if( bKeepGoing ) 134 { 135 WOL_GameSetupDialog GSupDlg( pWolapi, bCreator ); 136 switch( GSupDlg.Run() ) 137 { 138 case RESULT_WOLGSUP_LOGOUT: 139 // User logged out. 140 bKeepGoing = false; 141 break; 142 case RESULT_WOLGSUP_BACKTOCHAT: 143 case RESULT_WOLGSUP_HOSTLEFT: 144 case RESULT_WOLGSUP_RULESMISMATCH: 145 // Return to chat. 146 break; 147 case RESULT_WOLGSUP_STARTGAMEHOST: 148 // Proceed with game. 149 bKeepGoing = false; 150 iReturn = 1; 151 pWolapi->bGameServer = true; 152 break; 153 case RESULT_WOLGSUP_STARTGAME: 154 // Proceed with game. 155 bKeepGoing = false; 156 iReturn = 1; 157 pWolapi->bGameServer = false; 158 break; 159 case RESULT_WOLGSUP_FATALERROR: 160 // debugprint( "RESULT_WOLGSUP_FATALERROR from game setup dialog.\n" ); 161 // Fatal( "RESULT_WOLGSUP_FATALERROR from game setup dialog.\n" ); 162 if( pWolapi->pChatSink->bConnected ) 163 pWolapi->Logout(); 164 bKeepGoing = false; 165 break; 166 } 167 } 168 } 169 } 170 171 if( iReturn != 1 ) 172 { 173 // Kill wolapi. 174 pWolapi->UnsetupCOMStuff(); 175 delete pWolapi; 176 pWolapi = NULL; 177 } 178 else 179 { 180 pWolapi->bInGame = true; 181 pWolapi->bConnectionDown = false; 182 } 183 184 if( iLoginResult == -1 ) 185 { 186 WWMessageBox().Process( TXT_WOL_DOWNLOADEXITWARNING ); 187 iReturn = -1; 188 } 189 190 return iReturn; 191 } 192 193 //*********************************************************************************************** 194 bool ReregisterWolapiDLL() 195 { 196 // Attempt to reregister wolapi.dll. 197 // Returns true if we think we succeeded. 198 HKEY hKey; 199 char szInstallPath[ _MAX_PATH ]; 200 if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Westwood\\WOLAPI", 0, KEY_READ, &hKey ) == ERROR_SUCCESS ) 201 { 202 DWORD dwBufSize = _MAX_PATH; 203 if( ::RegQueryValueEx( hKey, "InstallPath", 0, NULL, (LPBYTE)szInstallPath, &dwBufSize ) == ERROR_SUCCESS ) 204 { 205 WIN32_FIND_DATA wfd; 206 HANDLE handle = FindFirstFile( szInstallPath, &wfd ); 207 if( handle == INVALID_HANDLE_VALUE ) 208 { 209 // File is not there. 210 FindClose( handle ); 211 ::RegCloseKey( hKey ); 212 return false; 213 } 214 // debugprint( "Found dll -> %s\n", szInstallPath ); 215 // Get the DLL to register itself. 216 HINSTANCE hLib = LoadLibrary( szInstallPath ); 217 if( !hLib ) 218 { 219 // debugprint( "LoadLibrary failed, GetLastError is %i\n", GetLastError() ); 220 ::RegCloseKey( hKey ); 221 return false; 222 } 223 FARPROC lpDllRegisterFunction = GetProcAddress( hLib, "DllRegisterServer" ); 224 if( !lpDllRegisterFunction ) 225 { 226 ::RegCloseKey( hKey ); 227 return false; 228 } 229 if( lpDllRegisterFunction() != S_OK ) 230 { 231 ::RegCloseKey( hKey ); 232 return false; 233 } 234 // There is a bug in wolapi.dll that makes the following delay necessary. 235 // Something about Neal's extra threads only getting half-way set up before they get deleted. 236 // (The extra threads shouldn't really be created in this case, anyway...) 237 ::Sleep( 1000 ); 238 FreeLibrary( hLib ); 239 FindClose( handle ); 240 } 241 else 242 { 243 ::RegCloseKey( hKey ); 244 return false; 245 } 246 ::RegCloseKey( hKey ); 247 } 248 else 249 { 250 return false; 251 } 252 return true; 253 } 254 255 //*********************************************************************************************** 256 void HandleDLLFail() 257 { 258 // The DLL failed to load. Either we failed to reregister it, or we think we succeeded at this but it 259 // still is not working. Show an error message and delete pWolapi. 260 // We show either "call tech support" or "download IE3", depending on whether oleaut32.dll looks out of date. 261 262 char szPath[ _MAX_PATH + 1 ]; 263 ::GetSystemDirectory( szPath, _MAX_PATH ); 264 if( *szPath && szPath[ strlen( szPath ) - 1 ] != '\\' ) 265 strcat( szPath, "\\" ); 266 267 strcat( szPath, "oleaut32.dll" ); 268 269 WIN32_FIND_DATA wfd; 270 HANDLE handle = FindFirstFile( szPath, &wfd ); 271 272 // debugprint( "HandleDLLFail(): filesize of oleaut32 is %i\n", wfd.nFileSizeLow ); 273 if( handle != INVALID_HANDLE_VALUE && wfd.nFileSizeLow <= 232720 ) 274 WWMessageBox().Process( TXT_WOL_DLLERROR_GETIE3 ); 275 else 276 WWMessageBox().Process( TXT_WOL_DLLERROR_CALLUS ); 277 278 FindClose( handle ); 279 280 delete pWolapi; 281 pWolapi = NULL; 282 } 283 284 #endif