WOL_MAIN.CPP 8.0 KB

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