Installer.cpp 108 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664
  1. /*
  2. ** Command & Conquer Renegade(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. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Installer *
  23. * *
  24. * $Archive:: /Commando/Code/Installer/Installer.cpp $*
  25. * *
  26. * $Author:: Ian_l $*
  27. * *
  28. * $Modtime:: 1/17/02 7:43p $*
  29. * *
  30. * $Revision:: 18 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. // Include files.
  36. #include "Installer.h"
  37. #include "Argv.h"
  38. #include "AssetMgr.h"
  39. #include "AssetStatus.h"
  40. #include "AudibleSound.h"
  41. #include "BINKMovie.h"
  42. #include "CardSelectionDialog.h"
  43. #include "CodeControl.h"
  44. #include "CopyDialog.h"
  45. #include "DialogMgr.h"
  46. #include "DirectoryDialog.h"
  47. #include "DX8Wrapper.h"
  48. #include "ErrorHandler.h"
  49. #include "FinalDialog.h"
  50. #include "FolderDialog.h"
  51. #include "Ini.h"
  52. #include "LicenseDialog.h"
  53. #include "MixFile.h"
  54. #include "Msgloop.h"
  55. #include "Registry.h"
  56. #include "ReviewDialog.h"
  57. #include "SafeTimer.h"
  58. #include "SerialDialog.h"
  59. #include "Timer.h"
  60. #include "TransitionDialog.h"
  61. #include "Translator.h"
  62. #include "Utilities.h"
  63. #include "WelcomeDialog.h"
  64. #include "WhatToInstallDialog.h"
  65. #include "Ww3D.h"
  66. #include "Wwmath.h"
  67. #include "WOL1Dialog.h"
  68. #include "WOL2Dialog.h"
  69. #include <io.h>
  70. #include <objbase.h>
  71. #include <shlobj.h>
  72. #include <intshcut.h>
  73. // Section names and entry names for IDS_GAME_INI_FILENAME.
  74. #define INI_CD_LABEL_SECTION "CDLabel"
  75. #define INI_SUBDIRECTORY_SECTION "SubDirectories"
  76. #define INI_FILES_SECTION "Files"
  77. #define INI_VOLUME_LABEL_ENTRY "VolumeLabel"
  78. #define INI_SUBDIRECTORY_ENTRY_PREFIX "Dir"
  79. #define INI_TOTAL_DISK_SPACE_NEEDED_ENTRY "TotalDiskSpaceNeeded"
  80. #define INI_NUM_FILES_ENTRY "NumFiles"
  81. // Section names and entry names for IDS_WOLAPI_INI_FILENAME.
  82. #define INI_WOLAPI_SECTION "Wolapi"
  83. #define INI_WOLREGISTER_SECTION "Register"
  84. #define INI_WOLBROWSER_SECTION "Browser"
  85. #define INI_VERSION_MAJOR_ENTRY "Major"
  86. #define INI_VERSION_MINOR_ENTRY "Minor"
  87. // Section names and entry names for IDS_SETUP_INI_FILENAME.
  88. #define INI_SETUP_SECTION "Setup"
  89. #define INI_LANGUAGE_ENTRY "Language"
  90. #define INI_SKU_ENTRY "SKU"
  91. #define INI_CAN_USE_IGR_SETTNGS_ENTRY "CanUseIGRSettings"
  92. // Miscellaneous.
  93. #define ENCRYPTION_STRING_LENGTH 128
  94. #define INSTALLER_NOMINAL_BYTE_COUNT 0x40000
  95. // Registry access.
  96. #define APPLICATION_SUB_KEY_NAME "Software\\Westwood\\Renegade"
  97. #define APPLICATION_SUB_KEY_NAME_RENDER "Software\\Westwood\\Renegade\\Render"
  98. #define APPLICATION_SUB_KEY_NAME_OPTIONS "Software\\Westwood\\Renegade\\Options"
  99. // Macros.
  100. #define END_DIALOG(dialog) \
  101. if (dialog != NULL) { \
  102. dialog->End_Dialog(); \
  103. }
  104. #define REGISTER_DIALOG(dialogclass, dialog, args) \
  105. if (dialog == NULL) { \
  106. dialog = NEW_REF (dialogclass, args); \
  107. dialog->Start_Dialog(); \
  108. } else { \
  109. DialogMgrClass::Register_Dialog (dialog); \
  110. }
  111. #define UNREGISTER_DIALOG(dialog) \
  112. DialogMgrClass::UnRegister_Dialog (dialog);
  113. #define DO_CANCEL \
  114. CancelApplication = true; \
  115. PostQuitMessage (0);
  116. // Foward declarations.
  117. void WWDebug_Message_Callback (DebugType type, const char *message);
  118. void WWAssert_Callback (const char *message);
  119. // Prototypes.
  120. bool CALLBACK Default_On_Command (DialogBaseClass *dialog, int ctrl_id, int mesage_id, DWORD param);
  121. // Singleton.
  122. InstallerClass _Installer;
  123. // Type definitions.
  124. typedef HRESULT (*DLLREGISTERSERVER)(void);
  125. typedef HRESULT (*DLLUNREGISTERSERVER)(void);
  126. /***********************************************************************************************
  127. * InstallerClass::InstallerClass -- *
  128. * *
  129. * INPUT: *
  130. * *
  131. * OUTPUT: *
  132. * *
  133. * WARNINGS: *
  134. * *
  135. * HISTORY: *
  136. * 08/22/01 IML : Created. *
  137. *=============================================================================================*/
  138. InstallerClass::InstallerClass()
  139. : SetupIni (NULL),
  140. GameIni (NULL),
  141. WOLIni (NULL),
  142. AssetManager (NULL),
  143. FreshGameInstall (true),
  144. FreshWOLInstall (true),
  145. TargetWOLOlder (true),
  146. WwmathInitialized (false),
  147. DialogMgrInitialized (false),
  148. AudioSystem (NULL),
  149. TransitionMusic (NULL),
  150. InstallMusic (NULL),
  151. UIInput (NULL),
  152. CancelIntroduction (false),
  153. CancelApplication (false),
  154. WelcomeDialog (NULL),
  155. NDADialog (NULL),
  156. LicenseDialog (NULL),
  157. SerialDialog (NULL),
  158. WhatToInstallDialog (NULL),
  159. GameDirectoryDialog (NULL),
  160. GameFolderDialog (NULL),
  161. WOLDirectoryDialog (NULL),
  162. WOLFolderDialog (NULL),
  163. ReviewDialog (NULL),
  164. CopyDialog (NULL),
  165. WOL1Dialog (NULL),
  166. WOL2Dialog (NULL),
  167. FinalDialog (NULL),
  168. GameFileCount (0),
  169. GameSize (0),
  170. WOLFileCount (0),
  171. WOLSize (0),
  172. CardSelectionDialog (NULL),
  173. ProgEndAction (ACTION_NONE)
  174. {
  175. SetupIni = new INIClass;
  176. GameIni = new INIClass;
  177. WOLIni = new INIClass;
  178. }
  179. /***********************************************************************************************
  180. * InstallerClass::~InstallerClass -- *
  181. * *
  182. * INPUT: *
  183. * *
  184. * OUTPUT: *
  185. * *
  186. * WARNINGS: *
  187. * *
  188. * HISTORY: *
  189. * 08/22/01 IML : Created. *
  190. *=============================================================================================*/
  191. InstallerClass::~InstallerClass()
  192. {
  193. delete WOLIni;
  194. delete GameIni;
  195. delete SetupIni;
  196. }
  197. /***********************************************************************************************
  198. * InstallerClass::Install -- *
  199. * *
  200. * INPUT: *
  201. * *
  202. * OUTPUT: *
  203. * *
  204. * WARNINGS: *
  205. * *
  206. * HISTORY: *
  207. * 08/22/01 IML : Created. *
  208. *=============================================================================================*/
  209. void InstallerClass::Install (MixFileFactoryClass *mixfilefactory)
  210. {
  211. try {
  212. const Vector3 black (0.0f, 0.0f, 0.0f);
  213. MixFileFactory = mixfilefactory;
  214. // Install debug callbacks.
  215. WWDebug_Install_Message_Handler (WWDebug_Message_Callback);
  216. WWDebug_Install_Assert_Handler (WWAssert_Callback);
  217. // Check that the source data for the install is present.
  218. if (Check_Source()) {
  219. const char *intromoviename = "InstallMovie.bik";
  220. const int playouttime = 2000;
  221. bool cancelapplication = false;
  222. int time;
  223. Check_Existing_Install();
  224. Initialize();
  225. // If the user has more than one video card, run the video card selection dialog.
  226. CardSelectionDialog = NEW_REF (CardSelectionDialogClass, (false));
  227. while (CardSelectionDialog->Get_Card_Count() > 1) {
  228. int cardselection;
  229. CardSelectionDialog->Start_Dialog();
  230. while (CardSelectionDialog->Is_Running()) {
  231. DialogMgrClass::On_Frame_Update();
  232. WW3D::Begin_Render (true, true, black);
  233. if (GameInFocus) {
  234. DialogMgrClass::Render();
  235. } else {
  236. Sleep (50);
  237. }
  238. WW3D::End_Render();
  239. Windows_Message_Handler();
  240. }
  241. cardselection = CardSelectionDialog->Get_Card_Selection();
  242. cancelapplication = CardSelectionDialog->Cancel_Application();
  243. if (cancelapplication) break;
  244. // NOTE: Must release all dialogs before attempting initialization.
  245. REF_PTR_RELEASE (CardSelectionDialog);
  246. WW3D_Shutdown();
  247. if (WW3D_Initialize (cardselection)) break;
  248. // Re-initialize with the default video card and driver and inform the user
  249. // that their selected card would not initialize.
  250. WW3D_Shutdown();
  251. WW3D_Initialize();
  252. CardSelectionDialog = NEW_REF (CardSelectionDialogClass, (true));
  253. }
  254. REF_PTR_RELEASE (CardSelectionDialog);
  255. // Does the user wish to exit?
  256. if (!cancelapplication) {
  257. if (!Beta_Test()) {
  258. // Play BINK intro movie.
  259. BINKMovie::Init();
  260. BINKMovie::Play (intromoviename);
  261. while (!BINKMovie::Is_Complete()) {
  262. if (CancelIntroduction) {
  263. BINKMovie::Stop();
  264. break;
  265. }
  266. BINKMovie::Update();
  267. WW3D::Begin_Render (false, false, black);
  268. if (GameInFocus) {
  269. BINKMovie::Render();
  270. } else {
  271. Sleep (50);
  272. }
  273. WW3D::End_Render();
  274. Windows_Message_Handler();
  275. }
  276. BINKMovie::Shutdown();
  277. // For artistic reasons, end the movie on a black frame.
  278. WW3D::Begin_Render (true, true, black);
  279. WW3D::End_Render();
  280. // If the user cancelled during the intro movie, then don't bother with the transition.
  281. if (!CancelIntroduction) {
  282. TransitionDialogClass *transition;
  283. // Create the transition animation.
  284. transition = NEW_REF (TransitionDialogClass, ());
  285. transition->Start_Dialog();
  286. // Start the transition music.
  287. if (TransitionMusic != NULL) TransitionMusic->Play();
  288. TTimerClass <SafeTimerClass> timer;
  289. // Play.
  290. while (true) {
  291. DialogMgrClass::On_Frame_Update();
  292. // Has the dialog 'played out'?
  293. // NOTE: Wait for both video and audio to finish.
  294. if (!transition->Is_Running()) {
  295. if (TransitionMusic != NULL) {
  296. if (!TransitionMusic->Is_Playing()) break;
  297. } else {
  298. break;
  299. }
  300. }
  301. WW3D::Begin_Render (true, true, black);
  302. if (GameInFocus) {
  303. DialogMgrClass::Render();
  304. if (TransitionMusic != NULL) {
  305. if (TransitionMusic->Get_State() == AudibleSoundClass::STATE_PAUSED) TransitionMusic->Resume();
  306. }
  307. if (!timer.Is_Active()) timer.Start();
  308. } else {
  309. if (TransitionMusic != NULL) {
  310. if (TransitionMusic->Get_State() == AudibleSoundClass::STATE_PLAYING) TransitionMusic->Pause();
  311. }
  312. if (timer.Is_Active()) timer.Stop();
  313. Sleep (50);
  314. }
  315. WW3D::End_Render();
  316. WW3D::Sync (timer.Value());
  317. WWAudioClass::Get_Instance()->On_Frame_Update();
  318. Windows_Message_Handler();
  319. // Has the user cancelled the transition?
  320. if (CancelIntroduction) {
  321. transition->End_Dialog();
  322. if (TransitionMusic != NULL) TransitionMusic->Stop();
  323. break;
  324. }
  325. }
  326. REF_PTR_RELEASE (transition);
  327. }
  328. }
  329. // Set the command handler for all subsequent dialogs.
  330. DialogBaseClass::Set_Default_Command_Handler (Default_On_Command);
  331. // Put up the first dialog.
  332. Default_On_Command (NULL, 0, 0, 0);
  333. // Start the install music.
  334. if (InstallMusic != NULL) InstallMusic->Play();
  335. TTimerClass <SafeTimerClass> timer;
  336. // Run dialog loop.
  337. while (!CancelApplication) {
  338. DialogMgrClass::On_Frame_Update();
  339. WW3D::Begin_Render (true, true, black);
  340. if (GameInFocus) {
  341. DialogMgrClass::Render();
  342. if (InstallMusic != NULL) {
  343. if (InstallMusic->Get_State() == AudibleSoundClass::STATE_PAUSED) InstallMusic->Resume();
  344. }
  345. if (!timer.Is_Active()) timer.Start();
  346. } else {
  347. if (InstallMusic != NULL) {
  348. if (InstallMusic->Get_State() == AudibleSoundClass::STATE_PLAYING) InstallMusic->Pause();
  349. }
  350. if (timer.Is_Active()) timer.Stop();
  351. Sleep (50);
  352. }
  353. WW3D::End_Render();
  354. WW3D::Sync (timer.Value());
  355. WWAudioClass::Get_Instance()->On_Frame_Update();
  356. Windows_Message_Handler();
  357. }
  358. // Before shutting down, allow a short time for sound effects to 'play out'.
  359. time = timer.Value();
  360. while (timer.Value() < time + playouttime) {
  361. WW3D::Sync (timer.Value());
  362. WWAudioClass::Get_Instance()->On_Frame_Update();
  363. Windows_Message_Handler();
  364. }
  365. // Clear the frame buffer.
  366. WW3D::Begin_Render (true, true, black);
  367. WW3D::End_Render();
  368. }
  369. Shutdown();
  370. }
  371. }
  372. catch (const WideStringClass &errormessage) {
  373. Shutdown();
  374. throw (errormessage);
  375. }
  376. }
  377. /***********************************************************************************************
  378. * InstallerClass::Check_Source -- *
  379. * *
  380. * INPUT: *
  381. * *
  382. * OUTPUT: *
  383. * *
  384. * WARNINGS: *
  385. * *
  386. * HISTORY: *
  387. * 08/22/01 IML : Created. *
  388. *=============================================================================================*/
  389. bool InstallerClass::Check_Source()
  390. {
  391. ArgvClass commandlineparser (false, true);
  392. // Use the simple file factory to read INI files from the current working directory.
  393. _TheFileFactory = _TheSimpleFileFactory;
  394. #if PERMIT_INSTALL_FROM_NETWORK
  395. if (!commandlineparser.Find ("-N")) {
  396. #else
  397. if (true) {
  398. #endif
  399. char sourcedriveletter;
  400. // Prompt for a CD with correct volume label.
  401. if (Prompt_Install_CD (RxWideStringClass (IDS_INSTALL_CD_VOLUME_NAME), sourcedriveletter)) {
  402. char sourcedrive [] = "?:";
  403. sourcedrive [0] = tolower (sourcedriveletter);
  404. SourceGamePath = sourcedrive;
  405. SourceWOLPath = sourcedrive;
  406. } else {
  407. // No CD found.
  408. return (false);
  409. }
  410. } else {
  411. #if PERMIT_INSTALL_FROM_NETWORK
  412. Get_Current_Directory (SourceGamePath);
  413. Remove_Trailing_Name (SourceGamePath);
  414. SourceWOLPath = SourceGamePath;
  415. #endif
  416. }
  417. // Initialize the game and WOL source paths.
  418. SourceGamePath += L"\\";
  419. SourceGamePath += RxWideStringClass (IDS_GAME_DIRECTORY_NAME);
  420. SourceWOLPath += L"\\";
  421. SourceWOLPath += RxWideStringClass (IDS_WOL_DIRECTORY_NAME);
  422. // Look in the current directory for Setup.ini file.
  423. if (!SetupIni->Is_Loaded()) {
  424. if (!SetupIni->Load (RxStringClass (IDS_SETUP_INI_FILENAME))) FATAL_APP_ERROR (IDS_INI_FILE_NOT_FOUND_OR_LOADED);
  425. }
  426. // Look in the current directory for <product name>.ini file.
  427. if (!GameIni->Is_Loaded()) {
  428. if (!GameIni->Load (RxStringClass (IDS_GAME_INI_FILENAME))) FATAL_APP_ERROR (IDS_INI_FILE_NOT_FOUND_OR_LOADED);
  429. }
  430. // Look in the WOL source directory for WOLAPI.ini file.
  431. if (!WOLIni->Is_Loaded()) {
  432. WideStringClass wolinipathname;
  433. StringClass multibytewolinipathname;
  434. wolinipathname = SourceWOLPath;
  435. wolinipathname += L"\\";
  436. wolinipathname += RxWideStringClass (IDS_WOL_INI_FILENAME);
  437. multibytewolinipathname = wolinipathname;
  438. if (!WOLIni->Load (multibytewolinipathname)) FATAL_APP_ERROR (IDS_INI_FILE_NOT_FOUND_OR_LOADED);
  439. }
  440. // Count no. and total file size of contents of game directory.
  441. Count_Source_Files (SourceGamePath, GameFileCount, GameSize);
  442. // Add game file count and size contained in CAB files.
  443. // WARNING: Only values < 2Gb will be reported correctly due to 32-bit limit on INIClass::Get_Int().
  444. // However, result is returned in 64-bits so that all callers are ready to handle >= 2Gb when the need arises.
  445. GameFileCount += GameIni->Get_Int (INI_FILES_SECTION, INI_NUM_FILES_ENTRY);
  446. GameSize += GameIni->Get_Int (INI_FILES_SECTION, INI_TOTAL_DISK_SPACE_NEEDED_ENTRY);
  447. // Count no. and total file size of contents of WOL directory.
  448. // NOTE: WOL directory does not contain CAB files.
  449. Count_Source_Files (SourceWOLPath, WOLFileCount, WOLSize);
  450. // Return success.
  451. return (true);
  452. }
  453. /***********************************************************************************************
  454. * InstallerClass::Count_Source_Files -- *
  455. * *
  456. * INPUT: *
  457. * *
  458. * OUTPUT: *
  459. * *
  460. * WARNINGS: *
  461. * *
  462. * HISTORY: *
  463. * 08/22/01 IML : Created. *
  464. *=============================================================================================*/
  465. void InstallerClass::Count_Source_Files (const WideStringClass &sourcepath, unsigned &filecount, __int64 &filesize)
  466. {
  467. const WCHAR *wildcardname = L"*.*";
  468. WideStringClass sourcepathname (sourcepath);
  469. StringClass multibytesourcewolpath;
  470. WIN32_FIND_DATA finddata;
  471. HANDLE handle;
  472. bool done = false;
  473. sourcepathname += L"\\";
  474. sourcepathname += wildcardname;
  475. multibytesourcewolpath = sourcepathname;
  476. handle = FindFirstFile (multibytesourcewolpath, &finddata);
  477. if (handle != INVALID_HANDLE_VALUE) {
  478. while (!done) {
  479. WideStringClass filename (finddata.cFileName);
  480. if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  481. // Filter out system diretories.
  482. if (filename [0] != L'.') {
  483. WideStringClass subsourcepath;
  484. // Recurse on subdirectory..
  485. subsourcepath = sourcepath;
  486. subsourcepath += L"\\";
  487. subsourcepath += filename;
  488. Count_Source_Files (subsourcepath, filecount, filesize);
  489. }
  490. } else {
  491. const WCHAR *cabextension = L".cab";
  492. WCHAR extension [_MAX_EXT];
  493. // Filter out CAB files.
  494. _wsplitpath (filename, NULL, NULL, NULL, extension);
  495. if (_wcsicmp (cabextension, extension) != 0) {
  496. filecount++;
  497. filesize += (finddata.nFileSizeHigh * ((__int64) MAXDWORD) + 1) + finddata.nFileSizeLow;
  498. }
  499. }
  500. if (done = FindNextFile (handle, &finddata) == 0) {
  501. if (GetLastError() != ERROR_NO_MORE_FILES) FATAL_SYSTEM_ERROR;
  502. }
  503. }
  504. if (!FindClose (handle)) FATAL_SYSTEM_ERROR;
  505. }
  506. }
  507. /***********************************************************************************************
  508. * InstallerClass::Check_Existing_Install -- *
  509. * *
  510. * INPUT: *
  511. * *
  512. * OUTPUT: *
  513. * *
  514. * WARNINGS: *
  515. * *
  516. * HISTORY: *
  517. * 08/22/01 IML : Created. *
  518. *=============================================================================================*/
  519. void InstallerClass::Check_Existing_Install()
  520. {
  521. WideStringClass pathname;
  522. StringClass multibytepathname;
  523. WIN32_FIND_DATA finddata;
  524. HANDLE handle;
  525. bool fresh;
  526. bool older;
  527. // Check for existence of target game .exe.
  528. fresh = true;
  529. if (_RegistryManager.Get_Target_Game_Pathname (pathname)) {
  530. multibytepathname = pathname;
  531. handle = FindFirstFile (multibytepathname, &finddata);
  532. if (handle != INVALID_HANDLE_VALUE) {
  533. FindClose (handle);
  534. fresh = false;
  535. }
  536. }
  537. FreshGameInstall = fresh;
  538. // Iterate over all WOL components. Install is a fresh install if one or more components are
  539. // missing from the user's system. The target is deemed older that the source if one or more
  540. // target version nos. is older than source.
  541. const char *sectionname [RegistryManagerClass::COMPONENT_COUNT] = {INI_WOLAPI_SECTION, INI_WOLREGISTER_SECTION, INI_WOLBROWSER_SECTION};
  542. fresh = false;
  543. older = false;
  544. for (int c = RegistryManagerClass::COMPONENT_FIRST; c < RegistryManagerClass::COMPONENT_COUNT; c++) {
  545. WideStringClass pathname;
  546. StringClass multibytepathname;
  547. WIN32_FIND_DATA finddata;
  548. HANDLE handle;
  549. DWORD major, minor, sourceversion, targetversion;
  550. // Check for existence of target .exe.
  551. if (!_RegistryManager.Get_Target_WOL_Pathname ((RegistryManagerClass::WOLComponentEnum) c, pathname)) {
  552. fresh = true;
  553. older = true;
  554. break;
  555. }
  556. multibytepathname = pathname;
  557. handle = FindFirstFile (multibytepathname, &finddata);
  558. if (handle == INVALID_HANDLE_VALUE) {
  559. fresh = true;
  560. older = true;
  561. break;
  562. }
  563. FindClose (handle);
  564. // Compare source and target versions.
  565. if (!_RegistryManager.Get_Target_WOL_Version ((RegistryManagerClass::WOLComponentEnum) c, targetversion)) {
  566. older = true;
  567. break;
  568. }
  569. major = WOLIni->Get_Int (sectionname [c], INI_VERSION_MAJOR_ENTRY, 0x1);
  570. minor = WOLIni->Get_Int (sectionname [c], INI_VERSION_MINOR_ENTRY, 0x0);
  571. sourceversion = (major << 16) + minor;
  572. if (sourceversion > targetversion) {
  573. older = true;
  574. break;
  575. }
  576. }
  577. FreshWOLInstall = fresh;
  578. TargetWOLOlder = older;
  579. }
  580. /***********************************************************************************************
  581. * InstallerClass::Initialize -- *
  582. * *
  583. * INPUT: *
  584. * *
  585. * OUTPUT: *
  586. * *
  587. * WARNINGS: *
  588. * *
  589. * HISTORY: *
  590. * 08/22/01 IML : Created. *
  591. *=============================================================================================*/
  592. void InstallerClass::Initialize()
  593. {
  594. const char *transitionmusicfilename = "TransitionMusic.mp3";
  595. const char *installmusicfilename = "InstallMusic.mp3";
  596. // All subsequent file factory access uses the mix file.
  597. _TheFileFactory = MixFileFactory;
  598. // Initialize WW systems.
  599. WWMath::Init();
  600. WwmathInitialized = true;
  601. if (!WW3D_Initialize()) FATAL_APP_ERROR (IDS_CANNOT_INITIALIZE_ANY_D3D_DEVICE);
  602. // Initialize the music.
  603. AudioSystem = new WWAudioClass();
  604. WWAudioClass::Get_Instance()->Initialize();
  605. WWAudioClass::Get_Instance()->Set_File_Factory (_TheFileFactory);
  606. TransitionMusic = WWAudioClass::Get_Instance()->Create_Sound_Effect (transitionmusicfilename);
  607. if (TransitionMusic != NULL) {
  608. TransitionMusic->Set_Type (AudibleSoundClass::TYPE_MUSIC);
  609. }
  610. InstallMusic = WWAudioClass::Get_Instance()->Create_Sound_Effect (installmusicfilename);
  611. if (InstallMusic != NULL) {
  612. InstallMusic->Set_Type (AudibleSoundClass::TYPE_MUSIC);
  613. InstallMusic->Set_Loop_Count (0);
  614. }
  615. }
  616. /***********************************************************************************************
  617. * InstallerClass::Shutdown -- *
  618. * *
  619. * INPUT: *
  620. * *
  621. * OUTPUT: *
  622. * *
  623. * WARNINGS: *
  624. * *
  625. * HISTORY: *
  626. * 08/22/01 IML : Created. *
  627. *=============================================================================================*/
  628. void InstallerClass::Shutdown()
  629. {
  630. // Close any open dialogs.
  631. END_DIALOG (WelcomeDialog)
  632. REF_PTR_RELEASE (WelcomeDialog)
  633. END_DIALOG (NDADialog)
  634. REF_PTR_RELEASE (NDADialog)
  635. END_DIALOG (LicenseDialog)
  636. REF_PTR_RELEASE (LicenseDialog)
  637. END_DIALOG (SerialDialog)
  638. REF_PTR_RELEASE (SerialDialog)
  639. END_DIALOG (WhatToInstallDialog)
  640. REF_PTR_RELEASE (WhatToInstallDialog)
  641. END_DIALOG (GameDirectoryDialog)
  642. REF_PTR_RELEASE (GameDirectoryDialog)
  643. END_DIALOG (GameFolderDialog)
  644. REF_PTR_RELEASE (GameFolderDialog)
  645. END_DIALOG (WOLDirectoryDialog)
  646. REF_PTR_RELEASE (WOLDirectoryDialog)
  647. END_DIALOG (WOLFolderDialog)
  648. REF_PTR_RELEASE (WOLFolderDialog)
  649. END_DIALOG (ReviewDialog)
  650. REF_PTR_RELEASE (ReviewDialog)
  651. END_DIALOG (CopyDialog)
  652. REF_PTR_RELEASE (CopyDialog)
  653. END_DIALOG (WOL1Dialog)
  654. REF_PTR_RELEASE (WOL1Dialog)
  655. END_DIALOG (WOL2Dialog)
  656. REF_PTR_RELEASE (WOL2Dialog)
  657. END_DIALOG (FinalDialog)
  658. REF_PTR_RELEASE (FinalDialog)
  659. END_DIALOG (CardSelectionDialog)
  660. REF_PTR_RELEASE (CardSelectionDialog)
  661. // Shutdown the music.
  662. if (TransitionMusic != NULL) {
  663. TransitionMusic->Stop();
  664. TransitionMusic->Release_Ref();
  665. }
  666. if (InstallMusic != NULL) {
  667. InstallMusic->Stop();
  668. InstallMusic->Release_Ref();
  669. }
  670. if (AudioSystem != NULL) {
  671. WWAudioClass::Get_Instance()->Shutdown();
  672. delete AudioSystem;
  673. }
  674. // Shutdown WW systems.
  675. WW3D_Shutdown();
  676. if (WwmathInitialized) WWMath::Shutdown();
  677. }
  678. /***********************************************************************************************
  679. * InstallerClass::WW3D_Initialize -- *
  680. * *
  681. * INPUT: *
  682. * *
  683. * OUTPUT: *
  684. * *
  685. * WARNINGS: *
  686. * *
  687. * HISTORY: *
  688. * 08/22/01 IML : Created. *
  689. *=============================================================================================*/
  690. bool InstallerClass::WW3D_Initialize (int cardselection)
  691. {
  692. const char *stylemgrini = "StyleMgr.ini";
  693. bool windowedmode;
  694. // Initialize WW3D.
  695. AssetManager = new WW3DAssetManager;
  696. AssetManager->Set_WW3D_Load_On_Demand (true);
  697. WW3D::Init (MainWindow);
  698. WW3D::Enable_Sorting (true);
  699. WW3D::Set_Thumbnail_Enabled (false);
  700. AssetStatusClass::Peek_Instance()->Enable_Reporting (false);
  701. // All subsequent file factory access uses the mix file.
  702. _TheFileFactory = MixFileFactory;
  703. ArgvClass commandlineparser (false, true);
  704. windowedmode = (commandlineparser.Find ("-W") != NULL);
  705. // For each available video card...
  706. for (int d = 0; d < WW3D::Get_Render_Device_Count(); d++) {
  707. // Does this card index match the supplied card index or should we try all cards until success?
  708. if ((cardselection == -1) || (cardselection == d)) {
  709. // Set the card index and whether windowed mode in the registry.
  710. WW3D::Registry_Save_Render_Device (APPLICATION_SUB_KEY_NAME_RENDER, d, -1, -1, -1, 0, -1);
  711. // Configure video for the user.
  712. Auto_Configure();
  713. // Set UV bias according to registry.
  714. RegistryClass optionsregistry (APPLICATION_SUB_KEY_NAME_OPTIONS);
  715. if (optionsregistry.Is_Valid()) {
  716. WW3D::Set_Screen_UV_Bias (optionsregistry.Get_Int ("ScreenUVBias", 1) != 0);
  717. }
  718. // Override the windowed mode.
  719. RegistryClass renderregistry (APPLICATION_SUB_KEY_NAME_RENDER);
  720. if (optionsregistry.Is_Valid()) {
  721. renderregistry.Set_Int ("RenderDeviceWindowed", windowedmode ? 1 : 0);
  722. }
  723. // Attempt to initialize the device.
  724. if (WW3D::Registry_Load_Render_Device (APPLICATION_SUB_KEY_NAME_RENDER, true) == WW3D_ERROR_OK) {
  725. // Clear frame buffers.
  726. for (int frame = 0; frame < 3; frame++) {
  727. WW3D::Begin_Render (true, true, Vector3 (0.0f,0.0f,0.0f));
  728. WW3D::End_Render();
  729. }
  730. // Success! Initialize dialog system.
  731. DialogMgrClass::Initialize (stylemgrini);
  732. DialogMgrInitialized = true;
  733. UIInput = NEW_REF (InstallerUIInputClass, ());
  734. UIInput->InitIME (MainWindow);
  735. DialogMgrClass::Install_Input (UIInput);
  736. return (true);
  737. }
  738. }
  739. }
  740. // Failure.
  741. return (false);
  742. }
  743. /***********************************************************************************************
  744. * InstallerClass::WW3D_Shutdown -- *
  745. * *
  746. * INPUT: *
  747. * *
  748. * OUTPUT: *
  749. * *
  750. * WARNINGS: *
  751. * *
  752. * HISTORY: *
  753. * 08/22/01 IML : Created. *
  754. *=============================================================================================*/
  755. void InstallerClass::WW3D_Shutdown()
  756. {
  757. // Clear frame buffers.
  758. for (int frame = 0; frame < 3; frame++) {
  759. WW3D::Begin_Render (true, true, Vector3 (0.0f,0.0f,0.0f));
  760. WW3D::End_Render();
  761. }
  762. // Shutdown WW3D (if previously initialized).
  763. REF_PTR_RELEASE (UIInput);
  764. if (DialogMgrInitialized) DialogMgrClass::Shutdown();
  765. if (WW3D::Is_Initted()) WW3D::Shutdown();
  766. if (AssetManager != NULL) {
  767. AssetManager->Free_Assets();
  768. delete AssetManager;
  769. }
  770. }
  771. /***********************************************************************************************
  772. * InstallerClass::Auto_Configure -- *
  773. * *
  774. * INPUT: *
  775. * *
  776. * OUTPUT: *
  777. * *
  778. * WARNINGS: *
  779. * *
  780. * HISTORY: *
  781. * 08/22/01 IML : Created. *
  782. *=============================================================================================*/
  783. void InstallerClass::Auto_Configure()
  784. {
  785. PROCESS_INFORMATION processinfo;
  786. STARTUPINFO startupinfo;
  787. memset (&startupinfo, 0, sizeof (STARTUPINFO));
  788. startupinfo.cb = sizeof (STARTUPINFO);
  789. // Start the child process.
  790. if (CreateProcess (NULL, // Address of module name
  791. "WWConfig.exe -autoconfig", // Address of command line
  792. NULL, // Address of process security attributes
  793. NULL, // Address of thread security attributes
  794. FALSE, // Does new process inherit handles?
  795. 0, // Creation flags
  796. NULL, // Address of new environment block
  797. NULL, // Address of current directory name
  798. &startupinfo, // Address of STARTUPINFO
  799. &processinfo)) { // Address of PROCESS_INFORMATION
  800. // Wait until child process exits.
  801. WaitForSingleObject (processinfo.hProcess, INFINITE);
  802. // Close process and thread handles.
  803. CloseHandle (processinfo.hProcess);
  804. CloseHandle (processinfo.hThread);
  805. }
  806. }
  807. /***********************************************************************************************
  808. * InstallerClass::Install_* -- *
  809. * *
  810. * INPUT: *
  811. * *
  812. * OUTPUT: *
  813. * *
  814. * WARNINGS: *
  815. * *
  816. * HISTORY: *
  817. * 08/22/01 IML : Created. *
  818. *=============================================================================================*/
  819. bool InstallerClass::Install_Game()
  820. {
  821. WWASSERT (WhatToInstallDialog != NULL);
  822. return (WhatToInstallDialog->Install_Game());
  823. }
  824. bool InstallerClass::Install_WOL()
  825. {
  826. WWASSERT (WhatToInstallDialog != NULL);
  827. return (WhatToInstallDialog->Install_WOL());
  828. }
  829. bool InstallerClass::Install_Game_Shortcut()
  830. {
  831. WWASSERT (WhatToInstallDialog != NULL);
  832. return (WhatToInstallDialog->Install_Game() && WhatToInstallDialog->Install_Game_Shortcut());
  833. }
  834. /***********************************************************************************************
  835. * InstallerClass::Get_Target_* -- *
  836. * *
  837. * INPUT: *
  838. * *
  839. * OUTPUT: *
  840. * *
  841. * WARNINGS: *
  842. * *
  843. * HISTORY: *
  844. * 08/22/01 IML : Created. *
  845. *=============================================================================================*/
  846. const WCHAR *InstallerClass::Get_Target_Game_Path (WideStringClass &path)
  847. {
  848. WWASSERT (GameDirectoryDialog != NULL);
  849. return (GameDirectoryDialog->Get_Path (path));
  850. }
  851. const WCHAR *InstallerClass::Get_Target_WOL_Path (WideStringClass &path)
  852. {
  853. WWASSERT (WOLDirectoryDialog != NULL);
  854. return (WOLDirectoryDialog->Get_Path (path));
  855. }
  856. const WCHAR *InstallerClass::Get_Target_Game_Folder (WideStringClass &folder)
  857. {
  858. WWASSERT (GameFolderDialog != NULL);
  859. return (GameFolderDialog->Get_Folder (folder));
  860. }
  861. const WCHAR *InstallerClass::Get_Target_WOL_Folder (WideStringClass &folder)
  862. {
  863. WWASSERT (WOLFolderDialog != NULL);
  864. return (WOLFolderDialog->Get_Folder (folder));
  865. }
  866. /***********************************************************************************************
  867. * InstallerClass::Get_Target_Sub_Path -- *
  868. * *
  869. * INPUT: *
  870. * *
  871. * OUTPUT: *
  872. * *
  873. * WARNINGS: *
  874. * *
  875. * HISTORY: *
  876. * 08/22/01 IML : Created. *
  877. *=============================================================================================*/
  878. bool InstallerClass::Get_Target_Sub_Path (unsigned index, WideStringClass &subpath)
  879. {
  880. StringClass multibytesubdirectoryname, entryname;
  881. WideStringClass subdirectoryname, targetpath;
  882. char numberstring [MAX_NUMBER_STRING_LENGTH];
  883. entryname = INI_SUBDIRECTORY_ENTRY_PREFIX;
  884. entryname += ltoa (index, numberstring, 10);
  885. GameIni->Get_String (multibytesubdirectoryname, INI_SUBDIRECTORY_SECTION, entryname);
  886. subdirectoryname = multibytesubdirectoryname;
  887. if (subdirectoryname.Get_Length() > 0) {
  888. subpath = Get_Target_Game_Path (targetpath);
  889. subpath += L"\\";
  890. subpath += subdirectoryname;
  891. return (true);
  892. } else {
  893. return (false);
  894. }
  895. }
  896. /***********************************************************************************************
  897. * InstallerClass::Get_Game_Size -- *
  898. * *
  899. * INPUT: *
  900. * *
  901. * OUTPUT: *
  902. * *
  903. * WARNINGS: *
  904. * *
  905. * HISTORY: *
  906. * 08/22/01 IML : Created. *
  907. *=============================================================================================*/
  908. __int64 InstallerClass::Get_Game_Size (bool ondisk)
  909. {
  910. __int64 bytecount = 0;
  911. if (Install_Game()) {
  912. bytecount = GameSize;
  913. if (ondisk) {
  914. // Account for cluster padding.
  915. bytecount += Cluster_Padding (GameFileCount);
  916. // Account for any .key (Encryption) and .wsu (Uninstall log) files that will be created by the Installer.
  917. bytecount += INSTALLER_NOMINAL_BYTE_COUNT;
  918. }
  919. }
  920. return (bytecount);
  921. }
  922. /***********************************************************************************************
  923. * InstallerClass::Get_WOL_Size -- *
  924. * *
  925. * INPUT: *
  926. * *
  927. * OUTPUT: *
  928. * *
  929. * WARNINGS: *
  930. * *
  931. * HISTORY: *
  932. * 08/22/01 IML : Created. *
  933. *=============================================================================================*/
  934. __int64 InstallerClass::Get_WOL_Size (bool ondisk)
  935. {
  936. __int64 bytecount = 0;
  937. if (Install_WOL()) {
  938. bytecount = WOLSize;
  939. if (ondisk) {
  940. // Account for cluster padding.
  941. bytecount += Cluster_Padding (WOLFileCount);
  942. // Account for any .key (Encryption) and .wsu (Uninstall log) files that will be created by the Installer.
  943. bytecount += INSTALLER_NOMINAL_BYTE_COUNT;
  944. }
  945. }
  946. return (bytecount);
  947. }
  948. /***********************************************************************************************
  949. * InstallerClass::Get_Total_Size -- *
  950. * *
  951. * INPUT: *
  952. * *
  953. * OUTPUT: *
  954. * *
  955. * WARNINGS: *
  956. * *
  957. * HISTORY: *
  958. * 08/22/01 IML : Created. *
  959. *=============================================================================================*/
  960. __int64 InstallerClass::Get_Total_Size (bool ondisk)
  961. {
  962. return (Get_Game_Size (ondisk) + Get_WOL_Size (ondisk));
  963. }
  964. /***********************************************************************************************
  965. * InstallerClass::Get_WOL_Space_Available -- *
  966. * *
  967. * INPUT: *
  968. * *
  969. * OUTPUT: *
  970. * *
  971. * WARNINGS: *
  972. * *
  973. * HISTORY: *
  974. * 08/22/01 IML : Created. *
  975. *=============================================================================================*/
  976. bool InstallerClass::Get_WOL_Space_Available (const WideStringClass &path, __int64 &diskspace)
  977. {
  978. WideStringClass targetgamepath, targetwolpath;
  979. // If the game is to be installed on the same drive, subtract game space needed from disk space available.
  980. if (Get_Disk_Space_Available (path, diskspace)) {
  981. if (Install_Game() && (Get_Target_Game_Path (targetgamepath) [0] == Get_Target_WOL_Path (targetwolpath) [0])) {
  982. diskspace -= Get_Game_Size (true);
  983. WWASSERT (diskspace >= 0);
  984. }
  985. return (true);
  986. }
  987. return (false);
  988. }
  989. /***********************************************************************************************
  990. * InstallerClass:Get_Serial_Number: -- *
  991. * *
  992. * INPUT: *
  993. * *
  994. * OUTPUT: *
  995. * *
  996. * WARNINGS: *
  997. * *
  998. * HISTORY: *
  999. * 08/22/01 IML : Created. *
  1000. *=============================================================================================*/
  1001. const char *InstallerClass::Get_Serial_Number (StringClass &serialnumber)
  1002. {
  1003. bool valid;
  1004. WWASSERT (SerialDialog != NULL);
  1005. valid = SerialDialog->Get_Serial_Number (serialnumber);
  1006. WWASSERT (valid);
  1007. return (serialnumber);
  1008. }
  1009. /***********************************************************************************************
  1010. * InstallerClass::Dialog_Callback -- *
  1011. * *
  1012. * INPUT: *
  1013. * *
  1014. * OUTPUT: *
  1015. * *
  1016. * WARNINGS: *
  1017. * *
  1018. * HISTORY: *
  1019. * 08/22/01 IML : Created. *
  1020. *=============================================================================================*/
  1021. void InstallerClass::Dialog_Callback (DialogBaseClass *dialog, int ctrl_id, int message_id, DWORD param)
  1022. {
  1023. InstallMenuDialogClass *installmenudialog = (InstallMenuDialogClass*) dialog;
  1024. // If no dialog is currently active display the welcome dialog.
  1025. if (installmenudialog == NULL) {
  1026. REGISTER_DIALOG (WelcomeDialogClass, WelcomeDialog, ())
  1027. } else {
  1028. // Is the current dialog the Welcome dialog?
  1029. if (installmenudialog->As_WelcomeDialogClass()) {
  1030. switch (ctrl_id) {
  1031. case IDCANCEL:
  1032. DO_CANCEL
  1033. UNREGISTER_DIALOG (dialog)
  1034. return;
  1035. case IDOK:
  1036. UNREGISTER_DIALOG (dialog)
  1037. if (!Beta_Test()) {
  1038. REGISTER_DIALOG (LicenseDialogClass, LicenseDialog, ())
  1039. } else {
  1040. REGISTER_DIALOG (NDADialogClass, NDADialog, ())
  1041. }
  1042. return;
  1043. }
  1044. }
  1045. // Is the current dialog the NDA agreement?
  1046. if (installmenudialog->As_NDADialogClass()) {
  1047. switch (ctrl_id) {
  1048. case IDCANCEL:
  1049. DO_CANCEL
  1050. UNREGISTER_DIALOG (dialog)
  1051. return;
  1052. case IDOK:
  1053. UNREGISTER_DIALOG (dialog)
  1054. REGISTER_DIALOG (LicenseDialogClass, LicenseDialog, ())
  1055. return;
  1056. case IDC_BUTTON_BACK:
  1057. UNREGISTER_DIALOG (dialog)
  1058. REGISTER_DIALOG (WelcomeDialogClass, WelcomeDialog, ())
  1059. return;
  1060. }
  1061. }
  1062. // Is the current dialog the License dialog?
  1063. if (installmenudialog->As_LicenseDialogClass()) {
  1064. switch (ctrl_id) {
  1065. case IDCANCEL:
  1066. DO_CANCEL
  1067. UNREGISTER_DIALOG (dialog)
  1068. return;
  1069. case IDOK:
  1070. UNREGISTER_DIALOG (dialog)
  1071. REGISTER_DIALOG (SerialDialogClass, SerialDialog, ())
  1072. return;
  1073. case IDC_BUTTON_BACK:
  1074. UNREGISTER_DIALOG (dialog)
  1075. if (!Beta_Test()) {
  1076. REGISTER_DIALOG (WelcomeDialogClass, WelcomeDialog, ())
  1077. } else {
  1078. REGISTER_DIALOG (NDADialogClass, NDADialog, ())
  1079. }
  1080. return;
  1081. }
  1082. }
  1083. // Is the current dialog the Serial dialog?
  1084. if (installmenudialog->As_SerialDialogClass()) {
  1085. switch (ctrl_id) {
  1086. case IDCANCEL:
  1087. DO_CANCEL
  1088. UNREGISTER_DIALOG (dialog)
  1089. return;
  1090. case IDOK:
  1091. UNREGISTER_DIALOG (dialog)
  1092. REGISTER_DIALOG (WhatToInstallDialogClass, WhatToInstallDialog, ())
  1093. return;
  1094. case IDC_BUTTON_BACK:
  1095. UNREGISTER_DIALOG (dialog)
  1096. REGISTER_DIALOG (LicenseDialogClass, LicenseDialog, ())
  1097. return;
  1098. }
  1099. }
  1100. // Is the current dialog the What To Install dialog?
  1101. if (installmenudialog->As_WhatToInstallDialogClass()) {
  1102. switch (ctrl_id) {
  1103. case IDCANCEL:
  1104. DO_CANCEL
  1105. UNREGISTER_DIALOG (dialog)
  1106. return;
  1107. case IDOK:
  1108. UNREGISTER_DIALOG (dialog)
  1109. // Does the user want to install the game? If not skip to WOL dialogs.
  1110. if (Install_Game()) {
  1111. REGISTER_DIALOG (GameDirectoryDialogClass, GameDirectoryDialog, ())
  1112. } else {
  1113. REGISTER_DIALOG (WOLDirectoryDialogClass, WOLDirectoryDialog, ())
  1114. }
  1115. return;
  1116. case IDC_BUTTON_BACK:
  1117. UNREGISTER_DIALOG (dialog)
  1118. REGISTER_DIALOG (SerialDialogClass, SerialDialog, ())
  1119. return;
  1120. }
  1121. }
  1122. // Is the current dialog the Game Directory dialog?
  1123. if (installmenudialog->As_GameDirectoryDialogClass()) {
  1124. switch (ctrl_id) {
  1125. case IDCANCEL:
  1126. DO_CANCEL
  1127. UNREGISTER_DIALOG (dialog)
  1128. return;
  1129. case IDOK:
  1130. UNREGISTER_DIALOG (dialog)
  1131. REGISTER_DIALOG (GameFolderDialogClass, GameFolderDialog, ())
  1132. return;
  1133. case IDC_BUTTON_BACK:
  1134. UNREGISTER_DIALOG (dialog)
  1135. REGISTER_DIALOG (WhatToInstallDialogClass, WhatToInstallDialog, ())
  1136. return;
  1137. }
  1138. }
  1139. // Is the current dialog the Game Folder dialog?
  1140. if (installmenudialog->As_GameFolderDialogClass()) {
  1141. switch (ctrl_id) {
  1142. case IDCANCEL:
  1143. DO_CANCEL
  1144. UNREGISTER_DIALOG (dialog)
  1145. return;
  1146. case IDOK:
  1147. UNREGISTER_DIALOG (dialog)
  1148. // Does the user want to install WOL? If not skip to Review dialog.
  1149. if (Install_WOL()) {
  1150. REGISTER_DIALOG (WOLDirectoryDialogClass, WOLDirectoryDialog, ())
  1151. } else {
  1152. REGISTER_DIALOG (ReviewDialogClass, ReviewDialog, ())
  1153. }
  1154. return;
  1155. case IDC_BUTTON_BACK:
  1156. UNREGISTER_DIALOG (dialog)
  1157. REGISTER_DIALOG (GameDirectoryDialogClass, GameDirectoryDialog, ())
  1158. return;
  1159. }
  1160. }
  1161. // Is the current dialog the Online Directory dialog?
  1162. if (installmenudialog->As_WOLDirectoryDialogClass()) {
  1163. switch (ctrl_id) {
  1164. case IDCANCEL:
  1165. DO_CANCEL
  1166. UNREGISTER_DIALOG (dialog)
  1167. return;
  1168. case IDOK:
  1169. UNREGISTER_DIALOG (dialog)
  1170. REGISTER_DIALOG (WOLFolderDialogClass, WOLFolderDialog, ())
  1171. return;
  1172. case IDC_BUTTON_BACK:
  1173. UNREGISTER_DIALOG (dialog)
  1174. // Does the user want to install the game? If not skip to the What To Install dialog.
  1175. if (Install_Game()) {
  1176. REGISTER_DIALOG (GameFolderDialogClass, GameFolderDialog, ())
  1177. } else {
  1178. REGISTER_DIALOG (WhatToInstallDialogClass, WhatToInstallDialog, ())
  1179. }
  1180. return;
  1181. }
  1182. }
  1183. // Is the current dialog the Online Folder dialog?
  1184. if (installmenudialog->As_WOLFolderDialogClass()) {
  1185. switch (ctrl_id) {
  1186. case IDCANCEL:
  1187. DO_CANCEL
  1188. UNREGISTER_DIALOG (dialog)
  1189. return;
  1190. case IDOK:
  1191. UNREGISTER_DIALOG (dialog)
  1192. REGISTER_DIALOG (ReviewDialogClass, ReviewDialog, ())
  1193. return;
  1194. case IDC_BUTTON_BACK:
  1195. UNREGISTER_DIALOG (dialog)
  1196. REGISTER_DIALOG (WOLDirectoryDialogClass, WOLDirectoryDialog, ())
  1197. return;
  1198. }
  1199. }
  1200. // Is the current dialog the Review dialog?
  1201. if (installmenudialog->As_ReviewDialogClass()) {
  1202. switch (ctrl_id) {
  1203. case IDCANCEL:
  1204. DO_CANCEL
  1205. UNREGISTER_DIALOG (dialog)
  1206. return;
  1207. case IDOK:
  1208. UNREGISTER_DIALOG (dialog)
  1209. REGISTER_DIALOG (CopyDialogClass, CopyDialog, ())
  1210. return;
  1211. case IDC_BUTTON_BACK:
  1212. UNREGISTER_DIALOG (dialog)
  1213. // Does the user want to install WOL? If not skip to game folder.
  1214. if (Install_WOL()) {
  1215. REGISTER_DIALOG (WOLFolderDialogClass, WOLFolderDialog, ())
  1216. } else {
  1217. REGISTER_DIALOG (GameFolderDialogClass, GameFolderDialog, ())
  1218. }
  1219. return;
  1220. }
  1221. }
  1222. // Is the current dialog the Copy dialog.
  1223. if (installmenudialog->As_CopyDialogClass()) {
  1224. switch (ctrl_id) {
  1225. case IDCANCEL:
  1226. if (((CopyDialogClass*) installmenudialog->As_CopyDialogClass())->Was_Successful()) {
  1227. // Copying was successful - advance straight to final dialog.
  1228. UNREGISTER_DIALOG (dialog)
  1229. REGISTER_DIALOG (FinalDialogClass, FinalDialog, (false))
  1230. } else {
  1231. // Copying was not successful - cancel as normal.
  1232. DO_CANCEL
  1233. UNREGISTER_DIALOG (dialog)
  1234. }
  1235. return;
  1236. case IDOK:
  1237. UNREGISTER_DIALOG (dialog)
  1238. // Does the user have existing Westwood Online accounts?
  1239. if (Has_WOL_Account()) {
  1240. REGISTER_DIALOG (WOL1DialogClass, WOL1Dialog, ())
  1241. } else {
  1242. REGISTER_DIALOG (FinalDialogClass, FinalDialog, (false))
  1243. }
  1244. return;
  1245. }
  1246. }
  1247. // Is the current dialog the WOL1 dialog?
  1248. if (installmenudialog->As_WOL1DialogClass()) {
  1249. switch (ctrl_id) {
  1250. case IDC_BUTTON_YES:
  1251. UNREGISTER_DIALOG (dialog)
  1252. REGISTER_DIALOG (WOL2DialogClass, WOL2Dialog, ())
  1253. return;
  1254. case IDC_BUTTON_NO:
  1255. case IDCANCEL:
  1256. UNREGISTER_DIALOG (dialog)
  1257. REGISTER_DIALOG (FinalDialogClass, FinalDialog, (true))
  1258. return;
  1259. }
  1260. }
  1261. // Is the current dialog the WOL2 dialog?
  1262. if (installmenudialog->As_WOL2DialogClass()) {
  1263. switch (ctrl_id) {
  1264. case IDCANCEL:
  1265. case IDOK:
  1266. UNREGISTER_DIALOG (dialog)
  1267. REGISTER_DIALOG (FinalDialogClass, FinalDialog, (true))
  1268. return;
  1269. }
  1270. }
  1271. // Is the current dialog the Final dialog?
  1272. if (installmenudialog->As_FinalDialogClass()) {
  1273. switch (ctrl_id) {
  1274. case IDOK:
  1275. DO_CANCEL
  1276. UNREGISTER_DIALOG (dialog)
  1277. // Extract any information from dialogs that will be needed on program end.
  1278. if (Install_Game()) {
  1279. Get_Target_Game_Path (TargetGamePath);
  1280. if (FinalDialog->Run_Game()) {
  1281. ProgEndAction = ACTION_RUN_GAME;
  1282. } else {
  1283. if (FinalDialog->Display_Readme()) {
  1284. ProgEndAction = ACTION_DISPLAY_README;
  1285. }
  1286. }
  1287. }
  1288. return;
  1289. case IDC_BUTTON_BACK:
  1290. UNREGISTER_DIALOG (dialog)
  1291. // If WOL2Dialog exists return to it - otherwise return to WOL1Dialog.
  1292. if (WOL2Dialog != NULL) {
  1293. REGISTER_DIALOG (WOL2DialogClass, WOL2Dialog, ())
  1294. } else {
  1295. WWASSERT (WOL1Dialog != NULL);
  1296. REGISTER_DIALOG (WOL1DialogClass, WOL1Dialog, ())
  1297. }
  1298. return;
  1299. }
  1300. }
  1301. }
  1302. }
  1303. /***********************************************************************************************
  1304. * Default_On_Command -- Callback for all menu dialogs. *
  1305. * *
  1306. * INPUT: *
  1307. * *
  1308. * OUTPUT: *
  1309. * *
  1310. * WARNINGS: *
  1311. * *
  1312. * HISTORY: *
  1313. * 08/22/01 IML : Created. *
  1314. *=============================================================================================*/
  1315. bool CALLBACK Default_On_Command (DialogBaseClass *dialog, int ctrl_id, int message_id, DWORD param)
  1316. {
  1317. _Installer.Dialog_Callback (dialog, ctrl_id, message_id, param);
  1318. return (true);
  1319. }
  1320. /***********************************************************************************************
  1321. * WWDebug_Message_Callback -- WWDebug message callback to define the behavior of WWDEBUG_SAY()*
  1322. * *
  1323. * INPUT: *
  1324. * *
  1325. * OUTPUT: *
  1326. * *
  1327. * WARNINGS: *
  1328. * *
  1329. * HISTORY: *
  1330. * 08/22/01 IML : Created. *
  1331. *=============================================================================================*/
  1332. void WWDebug_Message_Callback (DebugType type, const char *message)
  1333. {
  1334. OutputDebugString (message);
  1335. }
  1336. /***********************************************************************************************
  1337. * WWAssert_Callback -- WWAssert callback to define the behavior of WWASSERT(). *
  1338. * *
  1339. * INPUT: *
  1340. * *
  1341. * OUTPUT: *
  1342. * *
  1343. * WARNINGS: *
  1344. * *
  1345. * HISTORY: *
  1346. * 08/22/01 IML : Created. *
  1347. *=============================================================================================*/
  1348. void WWAssert_Callback (const char *message)
  1349. {
  1350. OutputDebugString (message);
  1351. _asm int 0x03
  1352. }
  1353. /***********************************************************************************************
  1354. * InstallerClass::Can_Use_IGR_Settings -- *
  1355. * *
  1356. * INPUT: *
  1357. * *
  1358. * OUTPUT: *
  1359. * *
  1360. * WARNINGS: *
  1361. * *
  1362. * HISTORY: *
  1363. * 08/22/01 IML : Created. *
  1364. *=============================================================================================*/
  1365. bool InstallerClass::Can_Use_IGR_Settings()
  1366. {
  1367. return (SetupIni->Get_Hex (INI_SETUP_SECTION, INI_CAN_USE_IGR_SETTNGS_ENTRY, 0x0) > 0x0);
  1368. }
  1369. /***********************************************************************************************
  1370. * InstallerClass::Use_IGR_Settings -- *
  1371. * *
  1372. * INPUT: *
  1373. * *
  1374. * OUTPUT: *
  1375. * *
  1376. * WARNINGS: *
  1377. * *
  1378. * HISTORY: *
  1379. * 08/22/01 IML : Created. *
  1380. *=============================================================================================*/
  1381. bool InstallerClass::Use_IGR_Settings()
  1382. {
  1383. WWASSERT (WhatToInstallDialog != NULL);
  1384. return (WhatToInstallDialog->Use_IGR_Settings());
  1385. }
  1386. /***********************************************************************************************
  1387. * InstallerClass::Beta_Test -- *
  1388. * *
  1389. * INPUT: *
  1390. * *
  1391. * OUTPUT: *
  1392. * *
  1393. * WARNINGS: *
  1394. * *
  1395. * HISTORY: *
  1396. * 08/22/01 IML : Created. *
  1397. *=============================================================================================*/
  1398. bool InstallerClass::Beta_Test()
  1399. {
  1400. const char *ndafilename = "NDA.txt";
  1401. HANDLE handle;
  1402. WIN32_FIND_DATA finddata;
  1403. // Use existence of Beta NDA to indicate whether this is the Beta test version.
  1404. handle = FindFirstFile (ndafilename, &finddata);
  1405. if (handle != INVALID_HANDLE_VALUE) {
  1406. FindClose (handle);
  1407. return (true);
  1408. }
  1409. return (false);
  1410. }
  1411. /***********************************************************************************************
  1412. * InstallerClass::Update_Registry -- *
  1413. * *
  1414. * INPUT: *
  1415. * *
  1416. * OUTPUT: *
  1417. * *
  1418. * WARNINGS: *
  1419. * *
  1420. * HISTORY: *
  1421. * 08/22/01 IML : Created. *
  1422. *=============================================================================================*/
  1423. void InstallerClass::Update_Registry()
  1424. {
  1425. if (Install_Game()) {
  1426. WideStringClass installpathname, folderpath, shortcutpathname;
  1427. StringClass serialnumber, encryptedserialnumber;
  1428. DWORD languageid, sku, version;
  1429. WideStringClass pathname, gamefolder, gamepath;
  1430. DWORD major, minor;
  1431. Get_Target_Game_Path (installpathname);
  1432. installpathname += L"\\";
  1433. installpathname += RxWideStringClass (IDS_GAME_EXECUTABLE_FILENAME);
  1434. _RegistryManager.Get_Folder_Path (folderpath);
  1435. folderpath += L"\\";
  1436. folderpath += Get_Target_Game_Folder (gamefolder);
  1437. folderpath += L"\\";
  1438. folderpath += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1439. _RegistryManager.Get_Desktop_Path (shortcutpathname);
  1440. shortcutpathname += L"\\";
  1441. shortcutpathname += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1442. shortcutpathname += L".lnk";
  1443. languageid = SetupIni->Get_Hex (INI_SETUP_SECTION, INI_LANGUAGE_ENTRY, 0x0);
  1444. // Create encryption file in target directory.
  1445. Get_Target_Game_Path (pathname);
  1446. pathname += L"\\";
  1447. pathname += RxWideStringClass (IDS_SERIAL_ENCRYPTION_FILENAME);
  1448. Create_Encryption_File (pathname);
  1449. // Encrypt the serial no.
  1450. Encrypt (Get_Serial_Number (serialnumber), pathname, encryptedserialnumber);
  1451. sku = SetupIni->Get_Int (INI_SETUP_SECTION, INI_SKU_ENTRY, 0x0);
  1452. major = SetupIni->Get_Int (INI_SETUP_SECTION, INI_VERSION_MAJOR_ENTRY, 0x1);
  1453. minor = SetupIni->Get_Int (INI_SETUP_SECTION, INI_VERSION_MINOR_ENTRY, 0x0);
  1454. version = (major << 16) + minor;
  1455. _RegistryManager.Register_Game (TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME),
  1456. installpathname,
  1457. folderpath,
  1458. shortcutpathname,
  1459. languageid,
  1460. encryptedserialnumber,
  1461. sku,
  1462. version);
  1463. }
  1464. if (Install_WOL()) {
  1465. WideStringClass folderpath, wolapipathname, wolregisterpathname, wolbrowserpathname;
  1466. DWORD sku, version;
  1467. WideStringClass WOLfolder;
  1468. DWORD major, minor;
  1469. _RegistryManager.Get_Folder_Path (folderpath);
  1470. folderpath += L"\\";
  1471. folderpath += Get_Target_WOL_Folder (WOLfolder);
  1472. folderpath += L"\\";
  1473. folderpath += TxWideStringClass (IDS_WOL_PRODUCT_NAME, IDS_RESOURCE_WOL_PRODUCT_NAME);
  1474. Get_Target_WOL_Path (wolapipathname);
  1475. wolapipathname += L"\\";
  1476. wolapipathname += RxWideStringClass (IDS_WOLAPI_DLL_FILENAME);
  1477. sku = atol (RxStringClass (IDS_WOLAPI_SKU));
  1478. major = WOLIni->Get_Int (INI_WOLAPI_SECTION, INI_VERSION_MAJOR_ENTRY, 0x1);
  1479. minor = WOLIni->Get_Int (INI_WOLAPI_SECTION, INI_VERSION_MINOR_ENTRY, 0x0);
  1480. version = (major << 16) + minor;
  1481. _RegistryManager.Register_WOLAPI (folderpath,
  1482. wolapipathname,
  1483. TxWideStringClass (IDS_WOL_PRODUCT_NAME, IDS_RESOURCE_WOL_PRODUCT_NAME),
  1484. sku,
  1485. version,
  1486. Use_IGR_Settings());
  1487. Get_Target_WOL_Path (wolregisterpathname);
  1488. wolregisterpathname += L"\\";
  1489. wolregisterpathname += RxWideStringClass (IDS_INTERNET_REGISTRATION_FILENAME);
  1490. sku = atol (RxStringClass (IDS_WOLREGISTER_SKU));
  1491. major = WOLIni->Get_Int (INI_WOLREGISTER_SECTION, INI_VERSION_MAJOR_ENTRY, 0x1);
  1492. minor = WOLIni->Get_Int (INI_WOLREGISTER_SECTION, INI_VERSION_MINOR_ENTRY, 0x0);
  1493. version = (major << 16) + minor;
  1494. _RegistryManager.Register_WOLRegister (folderpath,
  1495. wolregisterpathname,
  1496. TxWideStringClass (IDS_WOLREGISTER_NAME, IDS_RESOURCE_WOLREGISTER_NAME),
  1497. sku,
  1498. version);
  1499. Get_Target_WOL_Path (wolbrowserpathname);
  1500. wolbrowserpathname += "\\";
  1501. wolbrowserpathname += RxWideStringClass (IDS_WOLBROWSER_DLL_FILENAME);
  1502. major = WOLIni->Get_Int (INI_WOLBROWSER_SECTION, INI_VERSION_MAJOR_ENTRY, 0x1);
  1503. minor = WOLIni->Get_Int (INI_WOLBROWSER_SECTION, INI_VERSION_MINOR_ENTRY, 0x0);
  1504. version = (major << 16) + minor;
  1505. _RegistryManager.Register_WOLBrowser (wolbrowserpathname,
  1506. TxWideStringClass (IDS_WOLBROWSER_NAME, IDS_RESOURCE_WOLBROWSER_NAME),
  1507. version);
  1508. // Now register the DLL's.
  1509. Register_COM_Server (wolapipathname);
  1510. Register_COM_Server (wolbrowserpathname);
  1511. }
  1512. // Update WOLAPI.
  1513. _RegistryManager.Update_WOLAPI();
  1514. }
  1515. /***********************************************************************************************
  1516. * InstallerClass::Create_Links -- *
  1517. * *
  1518. * INPUT: *
  1519. * *
  1520. * OUTPUT: *
  1521. * *
  1522. * WARNINGS: *
  1523. * *
  1524. * HISTORY: *
  1525. * 08/22/01 IML : Created. *
  1526. *=============================================================================================*/
  1527. void InstallerClass::Create_Links()
  1528. {
  1529. if (CoInitialize (NULL) != S_OK) FATAL_APP_ERROR (IDS_COM_ERROR);
  1530. if (Install_Game()) {
  1531. WideStringClass folderpath, gamefolder, gamepathname, readmepathname;
  1532. WideStringClass readmeiconpathname, uninstallpathname, internetpathname, wwconfigpathname;
  1533. WideStringClass grabpatches ("GrabPatches");
  1534. // Create subdirectory in folder path for menu item links.
  1535. _RegistryManager.Get_Folder_Path (folderpath);
  1536. folderpath += L"\\";
  1537. folderpath += Get_Target_Game_Folder (gamefolder);
  1538. folderpath += L"\\";
  1539. folderpath += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1540. Create_Directory (folderpath);
  1541. // Create Renegade menu item.
  1542. Get_Target_Game_Path (gamepathname);
  1543. gamepathname += L"\\";
  1544. gamepathname += RxWideStringClass (IDS_GAME_EXECUTABLE_FILENAME);
  1545. Create_File_Link (folderpath, TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME), gamepathname, gamepathname);
  1546. // Create Auto Update menu item.
  1547. Create_File_Link (folderpath, TxWideStringClass (IDS_AUTO_UPDATE_TITLE, IDS_RESOURCE_AUTO_UPDATE_TITLE), gamepathname, gamepathname, &grabpatches);
  1548. // Create Readme menu item.
  1549. Get_Target_Game_Path (readmepathname);
  1550. readmepathname += L"\\";
  1551. readmepathname += RxWideStringClass (IDS_WORD_README_FILENAME);
  1552. Get_Target_Game_Path (readmeiconpathname);
  1553. readmeiconpathname += L"\\";
  1554. readmeiconpathname += RxWideStringClass (IDS_README_ICON_FILENAME);
  1555. Create_File_Link (folderpath, TxWideStringClass (IDS_README_TITLE, IDS_RESOURCE_README_TITLE), readmepathname, readmeiconpathname);
  1556. // Create Uninstall menu item.
  1557. Get_Target_Game_Path (uninstallpathname);
  1558. uninstallpathname += L"\\";
  1559. uninstallpathname += RxWideStringClass (IDS_GAME_UNINSTALL_FILENAME);
  1560. Create_File_Link (folderpath, TxWideStringClass (IDS_GAME_UNINSTALL_TITLE, IDS_RESOURCE_GAME_UNINSTALL_TITLE), uninstallpathname, uninstallpathname);
  1561. // Create Internet Registration menu item.
  1562. Get_Target_Game_Path (internetpathname);
  1563. internetpathname += L"\\";
  1564. internetpathname += RxWideStringClass (IDS_INTERNET_REGISTRATION_FILENAME);
  1565. Create_File_Link (folderpath, TxWideStringClass (IDS_INTERNET_REGISTRATION_TITLE, IDS_RESOURCE_INTERNET_REGISTRATION_TITLE), internetpathname, internetpathname);
  1566. // Create GameSpy Arcade menu item.
  1567. // LOCALIZATION NOTE: The French have decided not to include this link.
  1568. if (SetupIni->Get_Hex (INI_SETUP_SECTION, INI_LANGUAGE_ENTRY, 0x0) != 0x3) {
  1569. Create_URL_Link (folderpath, TxWideStringClass (IDS_PLAY_ONLINE_WITH_GAMESPY, IDS_RESOURCE_PLAY_ONLINE_WITH_GAMESPY), L"http://www.gamespyarcade.com/features/launch.asp?svcname=ccrenegade&distID=391");
  1570. }
  1571. // Create link to WWConfig.
  1572. Get_Target_Game_Path (wwconfigpathname);
  1573. wwconfigpathname += L"\\";
  1574. wwconfigpathname += RxWideStringClass (IDS_WWCONFIG_FILENAME);
  1575. Create_File_Link (folderpath, TxWideStringClass (IDS_WWCONFIG_TITLE, IDS_RESOURCE_WWCONFIG_TITLE), wwconfigpathname, wwconfigpathname);
  1576. // Create desktop icon (if requested).
  1577. if (Install_Game_Shortcut()) {
  1578. WideStringClass shortcutpath;
  1579. _RegistryManager.Get_Desktop_Path (shortcutpath);
  1580. Create_File_Link (shortcutpath, TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME), gamepathname, gamepathname);
  1581. }
  1582. }
  1583. if (Install_WOL()) {
  1584. WideStringClass folderpath, wolfolder, registerpathname, registericonpathname, uninstallpathname;
  1585. // Create subdirectory in folder path for menu item links.
  1586. _RegistryManager.Get_Folder_Path (folderpath);
  1587. folderpath += L"\\";
  1588. folderpath += Get_Target_WOL_Folder (wolfolder);
  1589. folderpath += L"\\";
  1590. folderpath += TxWideStringClass (IDS_WOL_PRODUCT_NAME, IDS_RESOURCE_WOL_PRODUCT_NAME);
  1591. Create_Directory (folderpath);
  1592. // Create Internet Registration menu item.
  1593. Get_Target_WOL_Path (registerpathname);
  1594. registerpathname += L"\\";
  1595. registerpathname += RxWideStringClass (IDS_INTERNET_REGISTRATION_FILENAME);
  1596. Create_File_Link (folderpath, TxWideStringClass (IDS_INTERNET_REGISTRATION_TITLE, IDS_RESOURCE_INTERNET_REGISTRATION_TITLE), registerpathname, registerpathname);
  1597. // Create Uninstall Registration menu item.
  1598. Get_Target_WOL_Path (uninstallpathname);
  1599. uninstallpathname += L"\\";
  1600. uninstallpathname += RxWideStringClass (IDS_WOL_UNINSTALL_FILENAME);
  1601. Create_File_Link (folderpath, TxWideStringClass (IDS_WOL_UNINSTALL_TITLE, IDS_RESOURCE_WOL_UNINSTALL_TITLE), uninstallpathname, uninstallpathname);
  1602. }
  1603. CoUninitialize();
  1604. }
  1605. /***********************************************************************************************
  1606. * InstallerClass::Create_File_Link -- *
  1607. * *
  1608. * INPUT: *
  1609. * *
  1610. * OUTPUT: *
  1611. * *
  1612. * WARNINGS: *
  1613. * *
  1614. * HISTORY: *
  1615. * 08/22/01 IML : Created. *
  1616. *=============================================================================================*/
  1617. bool InstallerClass::Create_File_Link (const WideStringClass &linkpath, const WideStringClass &title, const WideStringClass &targetpathname, const WideStringClass &iconpathname, const WideStringClass *arguments)
  1618. {
  1619. WideStringClass linkpathname, trimmedtitle, targetpath;
  1620. StringClass multibytelinkpathname, multibytetargetpath, multibytetitle, multibytetargetpathname, multibyteiconpathname;
  1621. IShellLink *psl;
  1622. IPersistFile *ppf;
  1623. bool success;
  1624. // The title is used in a pathname so it should be freed of any leading or trailing whitespace.
  1625. trimmedtitle = title;
  1626. trimmedtitle.Trim();
  1627. linkpathname = linkpath;
  1628. linkpathname += L"\\";
  1629. linkpathname += trimmedtitle;
  1630. linkpathname += L".lnk";
  1631. targetpath = targetpathname;
  1632. Remove_Trailing_Name (targetpath);
  1633. multibytelinkpathname = linkpathname;
  1634. multibytetargetpath = targetpath;
  1635. multibytetitle = trimmedtitle;
  1636. multibytetargetpathname = targetpathname;
  1637. multibyteiconpathname = iconpathname;
  1638. // Remove previous icon (if it exists).
  1639. DeleteFile (multibytelinkpathname);
  1640. success = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &psl) == S_OK;
  1641. if (success) {
  1642. try {
  1643. if (psl->SetPath (multibytetargetpathname) != NOERROR) throw (IDS_COM_ERROR);
  1644. if (psl->SetDescription (multibytetitle) != NOERROR) throw (IDS_COM_ERROR);
  1645. if (psl->SetIconLocation (multibyteiconpathname, 0) != NOERROR) throw (IDS_COM_ERROR);
  1646. if (arguments != NULL) {
  1647. StringClass multibytearguments (*arguments);
  1648. if (psl->SetArguments (multibytearguments) != NOERROR) throw (IDS_COM_ERROR);
  1649. }
  1650. if (psl->SetWorkingDirectory (multibytetargetpath) != NOERROR) throw (IDS_COM_ERROR);
  1651. if (psl->SetShowCmd (SW_NORMAL) != NOERROR) throw (IDS_COM_ERROR);
  1652. if (psl->SetHotkey (0) != NOERROR) throw (IDS_COM_ERROR);
  1653. if (psl->QueryInterface (IID_IPersistFile, (void**) &ppf) == S_OK) {
  1654. success = ppf->Save (linkpathname, TRUE) == S_OK;
  1655. ppf->Release();
  1656. }
  1657. } catch (...) {
  1658. success = false;
  1659. }
  1660. psl->Release();
  1661. }
  1662. return (success);
  1663. }
  1664. /***********************************************************************************************
  1665. * InstallerClass::Create_URL_Link -- *
  1666. * *
  1667. * INPUT: *
  1668. * *
  1669. * OUTPUT: *
  1670. * *
  1671. * WARNINGS: *
  1672. * *
  1673. * HISTORY: *
  1674. * 08/22/01 IML : Created. *
  1675. *=============================================================================================*/
  1676. bool InstallerClass::Create_URL_Link (const WideStringClass &linkpath, const WideStringClass &title, const WideStringClass &url)
  1677. {
  1678. WideStringClass trimmedtitle, linkpathname;
  1679. StringClass multibytelinkpathname, multibyteurl;
  1680. IUniformResourceLocator *purl;
  1681. IPersistFile *ppf;
  1682. bool success;
  1683. // The title is used in a pathname so it should be freed of any leading or trailing whitespace.
  1684. trimmedtitle = title;
  1685. trimmedtitle.Trim();
  1686. linkpathname = linkpath;
  1687. linkpathname += L"\\";
  1688. linkpathname += trimmedtitle;
  1689. linkpathname += L".url";
  1690. multibytelinkpathname = linkpathname;
  1691. multibyteurl = url;
  1692. // Remove previous icon (if it exists).
  1693. DeleteFile (multibytelinkpathname);
  1694. // Create an IUniformResourceLocator object
  1695. success = CoCreateInstance (CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (void**) &purl) == S_OK;
  1696. if (success) {
  1697. success = purl->SetURL (multibyteurl, 0) == S_OK;
  1698. if (success) {
  1699. success = purl->QueryInterface (IID_IPersistFile, (void**) &ppf) == S_OK;
  1700. if (success) {
  1701. success = ppf->Save (linkpathname, TRUE) == S_OK;
  1702. ppf->Release();
  1703. }
  1704. }
  1705. purl->Release();
  1706. }
  1707. return (success);
  1708. }
  1709. /***********************************************************************************************
  1710. * InstallerClass::Has_WOL_Account -- *
  1711. * *
  1712. * INPUT: *
  1713. * *
  1714. * OUTPUT: *
  1715. * *
  1716. * WARNINGS: *
  1717. * *
  1718. * HISTORY: *
  1719. * 08/22/01 IML : Created. *
  1720. *=============================================================================================*/
  1721. bool InstallerClass::Has_WOL_Account()
  1722. {
  1723. WideStringClass name, password;
  1724. return (_RegistryManager.Get_WOL_Account (0, name, password));
  1725. }
  1726. /***********************************************************************************************
  1727. * InstallerClass::Get_WOL_Account -- *
  1728. * *
  1729. * INPUT: *
  1730. * *
  1731. * OUTPUT: *
  1732. * *
  1733. * WARNINGS: *
  1734. * *
  1735. * HISTORY: *
  1736. * 08/22/01 IML : Created. *
  1737. *=============================================================================================*/
  1738. bool InstallerClass::Get_WOL_Account (unsigned index, WideStringClass &name, WideStringClass &password)
  1739. {
  1740. return (_RegistryManager.Get_WOL_Account (index, name, password));
  1741. }
  1742. /***********************************************************************************************
  1743. * InstallerClass::Log -- *
  1744. * *
  1745. * INPUT: *
  1746. * *
  1747. * OUTPUT: *
  1748. * *
  1749. * WARNINGS: *
  1750. * *
  1751. * HISTORY: *
  1752. * 08/22/01 IML : Created. *
  1753. *=============================================================================================*/
  1754. void InstallerClass::Log (const WideStringClass &pathname, __int64 size)
  1755. {
  1756. WideStringClass path;
  1757. if (Install_Game()) {
  1758. // Does the start of the pathname match either the game or WOL target path?
  1759. if (wcsstr (pathname, Get_Target_Game_Path (path)) != NULL) {
  1760. if (size == -1) {
  1761. WideStringClass subdirectoryname (((WideStringClass) pathname).Peek_Buffer() + path.Get_Length() + 1);
  1762. GameSubdirectories.Add (subdirectoryname);
  1763. } else {
  1764. FileLogClass filelog;
  1765. filelog.RelativePathname = ((WideStringClass) pathname).Peek_Buffer() + path.Get_Length() + 1;
  1766. filelog.Size = size;
  1767. GameFiles.Add (filelog);
  1768. }
  1769. return;
  1770. }
  1771. }
  1772. if (Install_WOL()) {
  1773. if (wcsstr (pathname, Get_Target_WOL_Path (path)) != NULL) {
  1774. FileLogClass filelog;
  1775. // NOTE: Logging WOL subdirectories is not supported.
  1776. WWASSERT (size != -1);
  1777. filelog.RelativePathname = ((WideStringClass) pathname).Peek_Buffer() + path.Get_Length() + 1;
  1778. filelog.Size = size;
  1779. WOLFiles.Add (filelog);
  1780. }
  1781. }
  1782. }
  1783. /***********************************************************************************************
  1784. * InstallerClass::Create_Uninstall_Logs -- *
  1785. * *
  1786. * INPUT: *
  1787. * *
  1788. * OUTPUT: *
  1789. * *
  1790. * WARNINGS: *
  1791. * *
  1792. * HISTORY: *
  1793. * 08/22/01 IML : Created. *
  1794. *=============================================================================================*/
  1795. void InstallerClass::Create_Uninstall_Logs()
  1796. {
  1797. if (Install_Game()) {
  1798. Create_Game_Uninstall_Log();
  1799. }
  1800. if (Install_WOL()) {
  1801. Create_WOL_Uninstall_Log();
  1802. }
  1803. }
  1804. /***********************************************************************************************
  1805. * InstallerClass::Create_Game_Uninstall_Log -- *
  1806. * *
  1807. * INPUT: *
  1808. * *
  1809. * OUTPUT: *
  1810. * *
  1811. * WARNINGS: *
  1812. * *
  1813. * HISTORY: *
  1814. * 08/22/01 IML : Created. *
  1815. *=============================================================================================*/
  1816. void InstallerClass::Create_Game_Uninstall_Log()
  1817. {
  1818. WideStringClass log;
  1819. WideStringClass installpathname, folderpath, gamefolder, shortcutpath;
  1820. WideStringClass s;
  1821. WideStringClass logfilepathname;
  1822. WideStringClass gamefilepathname;
  1823. HANDLE handle;
  1824. int i;
  1825. DWORD byteswritten;
  1826. StringClass multibytelogfilepathname, multibytelog;
  1827. __int64 totalfilesize;
  1828. _RegistryManager.Get_Folder_Path (folderpath);
  1829. _RegistryManager.Get_Desktop_Path (shortcutpath);
  1830. // Log temporary files that will/may be created by the game.
  1831. Get_Target_Game_Path (gamefilepathname);
  1832. gamefilepathname += L"\\";
  1833. gamefilepathname += L"commands.txt";
  1834. Log (gamefilepathname, 0);
  1835. Get_Target_Game_Path (gamefilepathname);
  1836. gamefilepathname += L"\\";
  1837. gamefilepathname += L"_logfile.txt";
  1838. Log (gamefilepathname, 0);
  1839. Get_Target_Game_Path (gamefilepathname);
  1840. gamefilepathname += L"\\";
  1841. gamefilepathname += L"_asserts.txt";
  1842. Log (gamefilepathname, 0);
  1843. Get_Target_Game_Path (gamefilepathname);
  1844. gamefilepathname += L"\\";
  1845. gamefilepathname += L"_except.txt";
  1846. Log (gamefilepathname, 0);
  1847. Get_Target_Game_Path (gamefilepathname);
  1848. gamefilepathname += L"\\";
  1849. gamefilepathname += L"sysinfo.txt";
  1850. Log (gamefilepathname, 0);
  1851. Get_Target_Game_Path (gamefilepathname);
  1852. gamefilepathname += L"\\";
  1853. gamefilepathname += L"history.txt";
  1854. Log (gamefilepathname, 0);
  1855. Get_Target_Game_Path (gamefilepathname);
  1856. gamefilepathname += L"\\";
  1857. gamefilepathname += L"asset_report.txt";
  1858. Log (gamefilepathname, 0);
  1859. // Create log pathname and log this file so it gets written to the uninstall log.
  1860. // NOTE: File size is not important - substitute zero.
  1861. Get_Target_Game_Path (logfilepathname);
  1862. logfilepathname += L"\\";
  1863. logfilepathname += RxWideStringClass (IDS_GAME_UNINSTALL_LOG_FILENAME);
  1864. Log (logfilepathname, 0);
  1865. // Build the log.
  1866. log += L"[Product]\n";
  1867. log += L"Name=";
  1868. log += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1869. log += L"\n";
  1870. log += L"FullName=";
  1871. log += TxWideStringClass (IDS_VERBOSE_GAME_PRODUCT_NAME, IDS_RESOURCE_VERBOSE_GAME_PRODUCT_NAME);
  1872. log += L"\n";
  1873. log += L"Key=";
  1874. log += RxWideStringClass (IDS_GAME_PRODUCT_KEY);
  1875. log += L"\n";
  1876. log += L"Exe=";
  1877. log += Get_Target_Game_Path (installpathname);
  1878. log += L"\\";
  1879. log += RxWideStringClass (IDS_GAME_EXECUTABLE_FILENAME);
  1880. log += L"\n\n";
  1881. log += L"[Icons]\n";
  1882. log += L"LNK=";
  1883. log += folderpath;
  1884. log += L"\\";
  1885. log += Get_Target_Game_Folder (gamefolder);
  1886. log += L"\\";
  1887. log += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1888. log += L"\n";
  1889. log += L"Desktop=";
  1890. log += shortcutpath;
  1891. log += L"\\";
  1892. log += TxWideStringClass (IDS_GAME_PRODUCT_NAME, IDS_RESOURCE_GAME_PRODUCT_NAME);
  1893. log += L".lnk";
  1894. log += L"\n\n";
  1895. // Append subdirectory information.
  1896. log += L"[SubDirectories]\n";
  1897. for (i = 0; i < GameSubdirectories.Count(); i++) {
  1898. s.Format (L"Dir%d=%s\n", i, GameSubdirectories [i]);
  1899. log += s;
  1900. }
  1901. s.Format (L"NumFiles=%u\n\n", GameSubdirectories.Count());
  1902. log += s;
  1903. // Append relative pathname information.
  1904. log += L"[Files]\n";
  1905. for (i = 0; i < GameFiles.Count(); i++) {
  1906. s.Format (L"F:%d=%s\n", i, GameFiles [i].RelativePathname);
  1907. log += s;
  1908. }
  1909. s.Format (L"NumFiles=%u\n\n", GameFiles.Count());
  1910. log += s;
  1911. // Append relative file size information.
  1912. log += L"[FileSizes]\n";
  1913. totalfilesize = 0;
  1914. for (i = 0; i < GameFiles.Count(); i++) {
  1915. s.Format (L"S:%d=%I64d\n", i, GameFiles [i].Size);
  1916. log += s;
  1917. totalfilesize += GameFiles [i].Size;
  1918. }
  1919. s.Format (L"Total=%I64d\n", totalfilesize);
  1920. log += s;
  1921. // Write the log file.
  1922. // NOTE: Convert strings from wide to multibyte.
  1923. multibytelogfilepathname = logfilepathname;
  1924. handle = CreateFile (multibytelogfilepathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1925. if (handle == INVALID_HANDLE_VALUE) FATAL_SYSTEM_ERROR;
  1926. multibytelog = log;
  1927. if (!WriteFile (handle, multibytelog.Peek_Buffer(), multibytelog.Get_Length() * sizeof (TCHAR), &byteswritten, NULL)) FATAL_SYSTEM_ERROR;
  1928. if (!CloseHandle (handle)) FATAL_SYSTEM_ERROR;
  1929. }
  1930. /***********************************************************************************************
  1931. * InstallerClass::Create_WOL_Uninstall_Log -- *
  1932. * *
  1933. * INPUT: *
  1934. * *
  1935. * OUTPUT: *
  1936. * *
  1937. * WARNINGS: *
  1938. * *
  1939. * HISTORY: *
  1940. * 08/22/01 IML : Created. *
  1941. *=============================================================================================*/
  1942. void InstallerClass::Create_WOL_Uninstall_Log()
  1943. {
  1944. WideStringClass log;
  1945. WideStringClass s;
  1946. WideStringClass logfilepathname;
  1947. HANDLE handle;
  1948. int i;
  1949. DWORD byteswritten;
  1950. StringClass multibytelogfilepathname, multibytelog;
  1951. // Create log pathname and log this file so it gets written to the uninstall log.
  1952. // NOTE: File size is not important - substitute zero.
  1953. Get_Target_WOL_Path (logfilepathname);
  1954. logfilepathname += L"\\";
  1955. logfilepathname += RxWideStringClass (IDS_WOL_UNINSTALL_LOG_FILENAME);
  1956. Log (logfilepathname, 0);
  1957. // Append relative pathname information.
  1958. for (i = 0; i < WOLFiles.Count(); i++) {
  1959. s.Format (L"%s\n", WOLFiles [i].RelativePathname);
  1960. log += s;
  1961. }
  1962. // Write the log file.
  1963. multibytelogfilepathname = logfilepathname;
  1964. handle = CreateFile (multibytelogfilepathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1965. if (handle == INVALID_HANDLE_VALUE) FATAL_SYSTEM_ERROR;
  1966. multibytelog = log;
  1967. if (!WriteFile (handle, multibytelog.Peek_Buffer(), multibytelog.Get_Length() * sizeof (TCHAR), &byteswritten, NULL)) FATAL_SYSTEM_ERROR;
  1968. if (!CloseHandle (handle)) FATAL_SYSTEM_ERROR;
  1969. }
  1970. /***********************************************************************************************
  1971. * InstallerClass::Create_Encryption_File -- *
  1972. * *
  1973. * INPUT: *
  1974. * *
  1975. * OUTPUT: *
  1976. * *
  1977. * WARNINGS: *
  1978. * *
  1979. * HISTORY: *
  1980. * 08/22/01 IML : Created. *
  1981. *=============================================================================================*/
  1982. void InstallerClass::Create_Encryption_File (const WideStringClass &pathname)
  1983. {
  1984. StringClass multibytepathname (pathname);
  1985. char stringbuffer [ENCRYPTION_STRING_LENGTH];
  1986. HANDLE handle;
  1987. DWORD byteswritten;
  1988. handle = CreateFile (multibytepathname, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
  1989. if (handle == INVALID_HANDLE_VALUE) FATAL_SYSTEM_ERROR;
  1990. // Seed the random no. generator.
  1991. srand (timeGetTime());
  1992. for (unsigned i = 0; i < ENCRYPTION_STRING_LENGTH; i++) {
  1993. char digit;
  1994. digit = rand() % 10;
  1995. stringbuffer [i] = digit + '0';
  1996. }
  1997. if (!WriteFile (handle, stringbuffer, sizeof (stringbuffer), &byteswritten, NULL)) FATAL_SYSTEM_ERROR;
  1998. if (!CloseHandle (handle)) FATAL_SYSTEM_ERROR;
  1999. // Log the file so it gets written to the uninstall log.
  2000. // NOTE: File size is not important - substitute zero.
  2001. Log (pathname, 0);
  2002. }
  2003. /***********************************************************************************************
  2004. * InstallerClass::Encrypt -- *
  2005. * *
  2006. * INPUT: *
  2007. * *
  2008. * OUTPUT: *
  2009. * *
  2010. * WARNINGS: *
  2011. * *
  2012. * HISTORY: *
  2013. * 08/22/01 IML : Created. *
  2014. *=============================================================================================*/
  2015. void InstallerClass::Encrypt (const char *number, const WideStringClass &pathname, StringClass &encryptednumber)
  2016. {
  2017. StringClass multibytepathname (pathname);
  2018. char *s;
  2019. int numberlength;
  2020. HANDLE handle;
  2021. DWORD bytesread;
  2022. char stringbuffer [ENCRYPTION_STRING_LENGTH];
  2023. int p;
  2024. numberlength = strlen (number);
  2025. s = new char [numberlength + 1];
  2026. memcpy (s, number, numberlength + 1);
  2027. handle = CreateFile (multibytepathname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  2028. if (handle == INVALID_HANDLE_VALUE) FATAL_SYSTEM_ERROR;
  2029. if (!ReadFile (handle, stringbuffer, sizeof (stringbuffer), &bytesread, NULL)) FATAL_SYSTEM_ERROR;
  2030. p = 0;
  2031. for (unsigned i = 0; i < ENCRYPTION_STRING_LENGTH; i++) {
  2032. int t;
  2033. char c;
  2034. t = s [p] - '0';
  2035. t %= 10;
  2036. t += stringbuffer [i];
  2037. t %= 10;
  2038. c = t + '0';
  2039. s [p] = c;
  2040. p++;
  2041. if (p == numberlength) p = 0;
  2042. }
  2043. encryptednumber = s;
  2044. // Clean-up.
  2045. delete [] s;
  2046. }
  2047. /***********************************************************************************************
  2048. * InstallerClass::Register_COM_Server -- *
  2049. * *
  2050. * INPUT: *
  2051. * *
  2052. * OUTPUT: *
  2053. * *
  2054. * WARNINGS: *
  2055. * *
  2056. * HISTORY: *
  2057. * 08/22/01 IML : Created. *
  2058. *=============================================================================================*/
  2059. bool InstallerClass::Register_COM_Server (const WideStringClass &comdll)
  2060. {
  2061. StringClass multibytecomdll (comdll);
  2062. HMODULE module = LoadLibrary (multibytecomdll);
  2063. if (module) {
  2064. HRESULT hr = E_FAIL;
  2065. DLLREGISTERSERVER dllRegister = (DLLREGISTERSERVER) GetProcAddress (module, "DllRegisterServer");
  2066. if (dllRegister) {
  2067. hr = dllRegister();
  2068. }
  2069. FreeLibrary (module);
  2070. module = NULL;
  2071. return (SUCCEEDED (hr));
  2072. }
  2073. return (false);
  2074. }
  2075. /***********************************************************************************************
  2076. * InstallerClass::Finish -- *
  2077. * *
  2078. * INPUT: *
  2079. * *
  2080. * OUTPUT: *
  2081. * *
  2082. * WARNINGS: *
  2083. * *
  2084. * HISTORY: *
  2085. * 08/22/01 IML : Created. *
  2086. *=============================================================================================*/
  2087. void InstallerClass::On_Prog_End()
  2088. {
  2089. switch (ProgEndAction) {
  2090. case ACTION_NONE:
  2091. break;
  2092. case ACTION_RUN_GAME:
  2093. Run_Game();
  2094. break;
  2095. case ACTION_DISPLAY_README:
  2096. Display_Readme();
  2097. break;
  2098. }
  2099. }
  2100. /***********************************************************************************************
  2101. * InstallerClass::Run_Game -- *
  2102. * *
  2103. * INPUT: *
  2104. * *
  2105. * OUTPUT: *
  2106. * *
  2107. * WARNINGS: *
  2108. * *
  2109. * HISTORY: *
  2110. * 08/22/01 IML : Created. *
  2111. *=============================================================================================*/
  2112. void InstallerClass::Run_Game()
  2113. {
  2114. WideStringClass modulepathname;
  2115. StringClass multibytemodulepathname, multibytetargetgamepath;
  2116. PROCESS_INFORMATION processinfo;
  2117. STARTUPINFO startupinfo;
  2118. modulepathname = TargetGamePath;
  2119. modulepathname += L"\\";
  2120. modulepathname += RxWideStringClass (IDS_GAME_EXECUTABLE_FILENAME);
  2121. multibytemodulepathname = modulepathname;
  2122. multibytetargetgamepath = TargetGamePath;
  2123. memset (&startupinfo, 0, sizeof (STARTUPINFO));
  2124. startupinfo.cb = sizeof (STARTUPINFO);
  2125. if (!CreateProcess (multibytemodulepathname.Peek_Buffer(), // Address of module name
  2126. NULL, // Address of command line
  2127. NULL, // Address of process security attributes
  2128. NULL, // Address of thread security attributes
  2129. FALSE, // Does new process inherit handles?
  2130. CREATE_NEW_PROCESS_GROUP | NORMAL_PRIORITY_CLASS, // Creation flags
  2131. NULL, // Address of new environment block
  2132. multibytetargetgamepath.Peek_Buffer(), // Address of current directory name
  2133. &startupinfo, // Address of STARTUPINFO
  2134. &processinfo)) { // Address of PROCESS_INFORMATION
  2135. FATAL_SYSTEM_ERROR;
  2136. }
  2137. }
  2138. /***********************************************************************************************
  2139. * InstallerClass::Display_Readme -- *
  2140. * *
  2141. * INPUT: *
  2142. * *
  2143. * OUTPUT: *
  2144. * *
  2145. * WARNINGS: *
  2146. * *
  2147. * HISTORY: *
  2148. * 08/22/01 IML : Created. *
  2149. *=============================================================================================*/
  2150. void InstallerClass::Display_Readme()
  2151. {
  2152. const unsigned applicationcount = 3;
  2153. const WCHAR *winwordprogramname = L"WINWORD.EXE";
  2154. const WCHAR *wordprocessornames [applicationcount] = {L"Wordpad.exe", L"Notepad.exe", L"Write.exe"};
  2155. WideStringClass pathname;
  2156. WCHAR docapppathname [_MAX_PATH];
  2157. WCHAR *t;
  2158. unsigned i;
  2159. PROCESS_INFORMATION processinfo;
  2160. STARTUPINFO startupinfo;
  2161. WideStringClass commandline;
  2162. StringClass multibytecommandline;
  2163. BOOL success = false;
  2164. // See if Winword is the owner of .doc files.
  2165. _RegistryManager.Get_Document_Application_Pathname (pathname);
  2166. wcscpy (docapppathname, pathname);
  2167. _wcsupr (docapppathname);
  2168. t = wcsstr (docapppathname, winwordprogramname);
  2169. if (t != NULL) {
  2170. t += wcslen (winwordprogramname);
  2171. *t = L'\0';
  2172. // Launch Winword with the Readme.doc file.
  2173. commandline = docapppathname;
  2174. commandline += L" \"";
  2175. commandline += TargetGamePath;
  2176. commandline += L"\\";
  2177. commandline += RxWideStringClass (IDS_WORD_README_FILENAME);
  2178. commandline += L"\"";
  2179. memset (&startupinfo, 0, sizeof (STARTUPINFO));
  2180. startupinfo.cb = sizeof (STARTUPINFO);
  2181. multibytecommandline = commandline;
  2182. success = CreateProcess (NULL, // Address of module name
  2183. multibytecommandline.Peek_Buffer(), // Address of command line
  2184. NULL, // Address of process security attributes
  2185. NULL, // Address of thread security attributes
  2186. FALSE, // Does new process inherit handles?
  2187. CREATE_NEW_PROCESS_GROUP | NORMAL_PRIORITY_CLASS, // Creation flags
  2188. NULL, // Address of new environment block
  2189. NULL, // Address of current directory name
  2190. &startupinfo, // Address of STARTUPINFO
  2191. &processinfo); // Address of PROCESS_INFORMATION
  2192. }
  2193. // No success? Try to launch any of the common text processor applications with the Readme.txt file.
  2194. i = 0;
  2195. while ((!success) && (i < applicationcount)) {
  2196. commandline = wordprocessornames [i];
  2197. commandline += L" \"";
  2198. commandline += TargetGamePath;
  2199. commandline += L"\\";
  2200. commandline += RxWideStringClass (IDS_TEXT_README_FILENAME);
  2201. commandline += L"\"";
  2202. memset (&startupinfo, 0, sizeof (STARTUPINFO));
  2203. startupinfo.cb = sizeof (STARTUPINFO);
  2204. multibytecommandline = commandline;
  2205. success = CreateProcess (NULL, // Address of module name
  2206. multibytecommandline.Peek_Buffer(), // Address of command line
  2207. NULL, // Address of process security attributes
  2208. NULL, // Address of thread security attributes
  2209. FALSE, // Does new process inherit handles?
  2210. CREATE_NEW_PROCESS_GROUP | NORMAL_PRIORITY_CLASS, // Creation flags
  2211. NULL, // Address of new environment block
  2212. NULL, // Address of current directory name
  2213. &startupinfo, // Address of STARTUPINFO
  2214. &processinfo); // Address of PROCESS_INFORMATION
  2215. i++;
  2216. }
  2217. // If still no success, throw error.
  2218. if (!success) FATAL_SYSTEM_ERROR;
  2219. }
  2220. #undef END_DIALOG
  2221. #undef REGISTER_DIALOG
  2222. #undef UNREGISTER_DIALOG
  2223. #undef DO_CANCEL