WOL_MAIN.CPP 8.1 KB

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