home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1997-10-05 | 60.5 KB | 1,593 lines
/*++ **************************************************************************************************** ******** search for $MODIFY - this will point to parts of the code that need modification ******** ******** search for $ADDGAME - code needed to be modified to add a game ******** **************************************************************************************************** Copyright (c) 1996 Microsoft Corp. File Name: Setup.c (AppInstall) Abstract: This is the interpreted script for use with InstallShield3, that is to be used to install applications from the disk to the HPC. Author: James Chen (jamesch) Feb 15/96 Slight modifications by Neil Enns (t-neile) July 96 Added multiple-component installation: Anthony Daniels, July 15th, 1996 Adapted gamepack for "hot" builds: Ido Ben-Shachar (idobs) August 20/96 Whoa, we have too many bugs. Revamped multiple-component installation: Ido Ben-Shachar (idobs) 10/15/96 --*/ /*** application-specific constants ***/ // installation information #define SZ_COMPANY_NAME "Microsoft" // $MODIFY #define SZ_PRODUCT_NAME "Microsoft Windows CE PowerToys" // $MODIFY #define SZ_PRODUCT_VERSION "1.0" // $MODIFY #define SZ_PRODUCT_KEY_1 "cascade.exe" // $MODIFY - this must match your main executable name #define SZ_PRODUCT_KEY_2 "mute.exe" // $MODIFY - this must match your main executable name #define SZ_PRODUCT_KEY_3 "ppaint.exe" // $MODIFY - this must match your main executable name #define SZ_PRODUCT_SUBF_1 "Cascade" // $MODIFY - this must match your main executable name #define SZ_PRODUCT_SUBF_2 "Mute" // $MODIFY - this must match your main executable name #define SZ_PRODUCT_SUBF_3 "Ppaint" // $MODIFY - this must match your main executable name #define SZ_ICON_FILE_1 "cascade.ico" // Icon file for use in HPC Manager // BUGBUG: ido #define SZ_ICON_FILE_2 "mute.ico" // Icon file for use in HPC Manager // BUGBUG: ido #define SZ_ICON_FILE_3 "ppaint.ico" // Icon file for use in HPC Manager // BUGBUG: ido // default values #define SZ_BITMAP_BACKGROUND "pegpage.bmp" #define SZ_BITMAP_DIALOG "dlg.bmp" #define SZ_SOURCE_FILE "data.z" // $MODIFY - compressed source file #define SZ_LICENSE_TEXT "license.txt" // $MODIFY - the license agreement #define SZ_DEFAULT_DESKTOP_LOCATION "\\Program Files\\HPC Explorer\\HPC Applications\\PowerToys" // $MODIFY #define SZ_INSTALL_SUBDIR "\\HPC Applications\\PowerToys" // $MODIFY #define SZ_DEST_DIR_PEGASUS "\\Program Files\\Accessories" // $MODIFY - default dest dir on the HPC // unintall information #define SZ_DEINSTALL_KEY "PowerToys" // $MODIFY // Uninstall key on DESKTOP side #define SZ_UNINSTALL_NAME "PowerToys v1.0 (Remove Only)" // $MODIFY Uninstall name on DESKTOP side // Load filename to send to PegLoad //#define SZ_PEGLOAD_APPNAME "Blackjack" // $MODIFY - your app's 'home' registry key on the HPC //#define SZ_PEGLOAD_LOADFILE "blackjack.load" // $MODIFY - your app's .LOAD file // BUGBUG: ido // the HPC Manager name #define SZ_MINERVA_NAME "HPC Explorer" // to find the load file data for PPCLOAD.DLL, look in the registry for the path for Minerva #define SZ_REGKEY_MINERVA_LOCATION "\\Software\\Microsoft\\Pegasus" // in HKEY_LOCAL_MACHINE #define SZ_REGVAL_MINERVA_LOCATION "InstalledDir" #define SZ_PEGLOAD_DLL "ppcload.dll" #define szPRIVATE_HELPER_DLL "delval.dll" // main helper DLL with assorted functions // variables for the remote control start menu item on the PC #define szREMOTE_CONTROL_FOLDER "Handheld PC Remote Control" // remote control folder name #define szREMOTE_CONTROL_EXE "\\Rcontrol\\remhpc.exe" // remote control helper app #define szREMOTE_CONTROL_DOC "\\Rcontrol\\remhpc.doc" // remote control doc #define szREMOTE_CONTROL_FOLDER_EXE "Handheld PC Remote Control" // remote control name #define szREMOTE_CONTROL_FOLDER_DOC "Readme" // remote control doc name // hard disk space required #define cEXTRA_SPACE_REQUIRED 205824 // $MODIFY - extra space needed during the decompression to the desktop, in bytes // error codes returned to appinstall program - taken from PEGLOAD\ERR.H #define LOAD_SUCCESS 0 #define LOAD_OUTOFSTORAGE 1 // out of memory on the Pegasus #define LOAD_CANCELLEDBYUSER 2 // loading cancelled by the user #define LOAD_INVALID_PARAMETER 3 // invalid parameter in the command line parameters #define LOAD_FAILED 4 // generic load failure #define LOAD_FAILEDCANTCLEANUP 5 // load failure, and cannot clean-up what was done to the Pegasus #define LOAD_DISCONNECTED 6 // disconnection in communications #define LOAD_CANT_CREATE_DIR 7 // cannot create the destination directory #define LOAD_REG_ERROR 8 // cannot create the registry entry #define LOAD_ERROR 9 // Unknown error // Dialog titles #define SZ_TITLE_LICENSE "Software License Agreement" // Dialog strings #define SZ_MSG_LICENSE "Please read the following license agreement. Use the scroll bar to view the rest of this agreement." #define SZ_MSG_AGREEMENT "Do you accept all the terms of the preceeding license agreement? If so, click on the Yes push button. If you select No, Setup will exit." declare #include "sddialog.h" // include script dialog definitions /*** local variables to main program ***/ HWND g_hwnd; NUMBER nTotalFileSize; // total file size of the application NUMBER nResult; // result of a function call STRING szDestDirDesktop; // destination directory on the desktop STRING szDestDirPegasus; // destination directory on the Pegasus STRING szUserName; // register the user's name STRING szUserCompany; // register the user's company STRING szUninstLogFile; // uninstall logfile created by InstallShield STRING szFileSet; // the file set used for copying the files STRING szPegasusCPU; // string specifying Pegasus CPU type STRING szPathname; // path to the license agreement file STRING g_szDllFilename; // ppcload.dll filename STRING g_szDllFilename1; // ppcload.dll filename // List of file extensions used in all the components except those ending with the CPU type. LIST g_listFileExtensions; // Information about the components: LIST g_listComponentNames, // The names that appear in the selection box g_listComponentSizes, // Sizes of each component g_listComponentDirectories, // Directories of the components in the compressed data file. g_listComponentsToInstall, // Boolean list of which components to install (0 or 1 for each element) g_listComponentPPCLoadFile, // .load filename for each component g_listComponentUninstallName; // Name to display in add/remove programs on the HPC /*** function declarations ***/ prototype InitializeVariables(); prototype InitializeComponentVars(); prototype CleanUpComponentVars(); prototype StripDoubleQuotes( BYREF STRING ); prototype SetupScreen(); prototype SetupWelcome(); prototype DoSystemTest( BYREF STRING ); prototype CheckForConflicts(); prototype HWND USER.GetActiveWindow(); prototype HWND USER.FindWindowEx( HWND, HWND, STRING, NUMBER ); // NOTE - the 4rd parameter of FindWindowEx is actually a LPSTR - however, InstallShield does not pass in // a NULL string properly - and so, we will always pass 0 for the 3rd parameter to represent NULL prototype CalculateComponentSizes(); prototype NGetComponentFileSize( STRING, STRING ); prototype NComponentSelection (STRING); prototype NGetTotalFileSize( STRING ); prototype NRegisterUser( BYREF STRING, BYREF STRING ); prototype NGetDestDesktop( BYREF STRING ); prototype FCheckEnoughSpace( NUMBER, STRING ); prototype NGetDestPegasus( BYREF STRING ); prototype NGetCopyConfirmation( NUMBER, STRING, STRING ); prototype CreateUninstallInfo( BYREF STRING, STRING ); prototype SetupFileTransfer( BYREF STRING, STRING, STRING ); prototype DoFileTransfer( STRING ); prototype FinishSetup( NUMBER, STRING, STRING, STRING, STRING, STRING ); // FinishSetup also uses USER.GetActiveWindow() prototype BOOL PPCLoad.Load_PegCpuType( POINTER ); // entry function to init LOAD in ppcload.dll prototype NUMBER PPCLoad.Load_Init(); // entry function to init LOAD in PPCLOAD.DLL prototype NUMBER PPCLoad.Load_PegFreeSpace(); // entry function to init LOAD in PPCLOAD.DLL prototype BOOL PPCLoad.Load_AlreadyInstalled( STRING ); // entry function to init LOAD in PPCLOAD.DLL prototype NUMBER PPCLoad.Load( HWND, STRING ); // entry function to call LOAD in PPCLOAD.DLL prototype PPCLoad.Load_Exit(); // entry function to exit LOAD in PPCLOAD.DLL prototype NUMBER PPCLOAD.Load_RegisterFileInfo( STRING, STRING, STRING, NUMBER); // Register icons with PegMan // get the Windows desktop/startup directories prototype BOOL delval.FGetDesktopDirectory( HWND, STRING ); prototype BOOL delval.FGetStartupDirectory( HWND, STRING ); STRING szFOLDER_DESKTOP[ 260 ]; // desktop folder name (of size MAX_PATH) STRING szFOLDER_STARTUP[ 260 ]; // startup folder name (of size MAX_PATH) prototype CleanUp(); prototype InstallFilter(); /*** main program ***/ program StartProgram: // initialize all variables and lists InitializeVariables(); // initialize variables for the components InitializeComponentVars(); // set up the initial screen and bitmap SetupScreen(); CheckForConflicts(); // create the welcome dialog SetupWelcomePart: SetupWelcome(); // test the system requirements DoSystemTest( szPegasusCPU ); // Now that the CPU type has been determined (szPegasusCPU), calculate the sizes of the components CalculateComponentSizes(); // license agreement LicenseDlg: szPathname = SUPPORTDIR ^ SZ_LICENSE_TEXT; nResult = SdLicense( SZ_TITLE_LICENSE, SZ_MSG_LICENSE, SZ_MSG_AGREEMENT, szPathname ); if ( BACK = nResult ) then goto SetupWelcomePart; endif; // register the user name and company RegisterUserPart: if ( NRegisterUser( szUserName, szUserCompany ) = BACK ) then goto LicenseDlg; endif; // get the destination directory on the desktop GetDestDesktopPart: if ( NGetDestDesktop( szDestDirDesktop ) = BACK ) then goto RegisterUserPart; endif; // get the destination directory on the Pegasus /* Not doin' this in V1 GetDestPegasusPart: if ( NGetDestPegasus( szDestDirPegasus ) = BACK ) then goto GetDestDesktopPart; endif; */ ComponentSelectionPart: if ( NComponentSelection (szDestDirDesktop) = BACK) then goto GetDestDesktopPart; endif; // Hey, now that we chose components, we can finally do this... // calculate the total file size. nTotalFileSize = NGetTotalFileSize( szPegasusCPU ); // check space requirements on desktop if ( FCheckEnoughSpace( nTotalFileSize, szDestDirDesktop ) = FALSE ) then goto ComponentSelectionPart; endif; /* I hate this. Maybe if the dialog wern't so *ugly* and intimidating... // confirm copy selection if ( NGetCopyConfirmation( nTotalFileSize, szDestDirDesktop, szDestDirPegasus ) = BACK ) then goto GetDestPegasusPart; endif; */ // prepare de-installation information for the desktop CreateUninstallInfo( szUninstLogFile, szDestDirDesktop ); // prepare files to transfer SetupFileTransfer( szFileSet, szDestDirDesktop, szPegasusCPU ); // perform file transfer DoFileTransfer( szFileSet ); // The paint application needs a special bitmap filter installed InstallFilter(); // finish setup by using PPCLOAD.DLL to load the files to the Pegasus, and offer to read README file FinishSetup( nTotalFileSize, szDestDirDesktop, szDestDirPegasus, szPegasusCPU, szUserName, szUserCompany ); // perform cleanup of dynamically-allocated lists CleanUp(); exit; /*++ InstallFilter: - install 2bp->bmp filter Arguments: None Return Value: None --*/ function InstallFilter() NUMBER nErr; STRING szPaintDir; STRING szMinervaLocation; NUMBER fInstallPaint; NUMBER nvRegType; NUMBER nvSize; begin // Let's only install the filter if the paint application is being installed... ListGetFirstString(g_listComponentDirectories, szPaintDir); // $MODIFY: Note that this isn't necessarily the first component in the list! ListGetFirstItem(g_listComponentsToInstall, fInstallPaint); if (1 = fInstallPaint) then nErr = 0; // no errors so far // Find out where minerva lives RegDBSetDefaultRoot( HKEY_LOCAL_MACHINE ); nErr = nErr + RegDBGetKeyValueEx("\\SOFTWARE\\Microsoft\\Pegasus", "InstalledDir", nvRegType, szMinervaLocation, nvSize); // Let's copy bmp.dll to a safer place, like the minerva directory! SRCDIR = szDestDirDesktop ^ szPaintDir; TARGETDIR = szMinervaLocation; nErr = nErr + CopyFile("bmp.dll", "bmp.dll"); // set default root nErr = nErr + RegDBSetDefaultRoot( HKEY_LOCAL_MACHINE ); nErr = nErr + RegDBCreateKeyEx("\\SOFTWARE\\Microsoft\\Pegasus\\Filters\\.2bp", ""); nErr = nErr + RegDBCreateKeyEx("\\SOFTWARE\\Microsoft\\Pegasus\\Filters\\.2bp\\InstalledFilters", ""); nErr = nErr + RegDBSetKeyValueEx("\\SOFTWARE\\Microsoft\\Pegasus\\Filters\\.2bp", "DefaultExport", REGDB_STRING, "{8BC519B4-F935-11cf-9335-00AA006EC3AB}", -1); nErr = nErr + RegDBSetKeyValueEx("\\SOFTWARE\\Microsoft\\Pegasus\\Filters\\.2bp\\InstalledFilters", "{8BC519B4-F935-11cf-9335-00AA006EC3AB}", REGDB_STRING, "", -1); // set default root nErr = nErr + RegDBSetDefaultRoot( HKEY_CLASSES_ROOT ); nErr = nErr + RegDBCreateKeyEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}", ""); nErr = nErr + RegDBCreateKeyEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\DefaultIcon", ""); nErr = nErr + RegDBCreateKeyEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\InProcServer32", ""); nErr = nErr + RegDBCreateKeyEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\PegasusFilter", ""); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}", "", REGDB_STRING, "Bitmap Image", -1); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\DefaultIcon", "", REGDB_STRING, szMinervaLocation ^ "\\" ^ "bmp.dll,-1000", -1); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\InProcServer32", "", REGDB_STRING, szMinervaLocation ^ "\\" ^ "bmp.dll", -1); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\InProcServer32", "ThreadingModel", REGDB_STRING, "Apartment", -1); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\PegasusFilter", "Description", REGDB_STRING, "Convert from Pocket Bitmap to Bitmap", -1); nErr = nErr + RegDBSetKeyValueEx("\\CLSID\\{8BC519B4-F935-11cf-9335-00AA006EC3AB}\\PegasusFilter", "NewExtension", REGDB_STRING, "bmp", -1); // if any registry setting failed, put up a warning box if ( 0 != nErr ) then SetDialogTitle( DLG_MSG_WARNING, "Registry Settings Failed" ); MessageBox( "Setup could not install bitmap converter for the Paint Application.", WARNING ); endif; endif; end; /*++ NComponentSelection: - Allows the user to select the games they want to install. Sets a boolean flag for each game based on whether it is selected here or not. Arguments: Return value: NEXT or BACK. --*/ function NComponentSelection ( szDestDir ) NUMBER nBackOrNext, nGameSize, nListResult, nInstall; STRING szTitle, szMessage, szComponents, svGameName; LIST listComponents; begin // Set up the parts of the component selection dialog. szTitle = "Microsoft Windows CE PowerToys Installation!"; // $MODIFY szMessage = "Select the components you wish to install"; szComponents = "Components"; // $MODIFY // Put the components into the list, getting there names, sizes and // whether to have them selected initially. nListResult = ListGetFirstItem (g_listComponentSizes, nGameSize); nListResult = ListGetFirstItem (g_listComponentsToInstall, nInstall); nListResult = ListGetFirstString (g_listComponentNames, svGameName); while (END_OF_LIST != nListResult) ComponentAddItem (szComponents, svGameName, nGameSize, nInstall); nListResult = ListGetNextItem (g_listComponentSizes, nGameSize); nListResult = ListGetNextItem (g_listComponentsToInstall, nInstall); nListResult = ListGetNextString (g_listComponentNames, svGameName); endwhile; // Display the components dialog. nBackOrNext = SdComponentDialog (szTitle, szMessage, szDestDir, szComponents); // Now work out which components the user selected and update the global // variable g_listComponentsToInstall. listComponents = ListCreate (STRINGLIST); ComponentListItems (szComponents, listComponents); nListResult = ListGetFirstItem (g_listComponentsToInstall, nInstall); nListResult = ListGetFirstString (listComponents, svGameName); while (END_OF_LIST != nListResult ) if (TRUE = ComponentIsItemSelected (szComponents, svGameName)) then ListSetCurrentItem (g_listComponentsToInstall, 1); else ListSetCurrentItem (g_listComponentsToInstall, 0); endif; nListResult = ListGetNextItem (g_listComponentsToInstall, nInstall); nListResult = ListGetNextString (listComponents, svGameName); endwhile; // Let's do our duty to keep things clean, and free up some variables! ListDestroy(listComponents); return nBackOrNext; end; /*++ CalculateComponentSizes: - figures out the sizes of all the components Arguments: None Return Value: None --*/ function CalculateComponentSizes() STRING szDir; NUMBER nComponentSize; NUMBER nListResult; NUMBER nRetErr; begin nRetErr = 0; // no errors so far // First, we have to destroy the bogus list of component sizes we created earlier. It was simply a placeholder // so that Cleanup() could destroy a list, and so that this function could be called multiple times (being // able to destroy the old list). ListDestroy(g_listComponentSizes); // Now create the new list g_listComponentSizes = ListCreate(NUMBERLIST); if (LIST_NULL = g_listComponentSizes) then nRetErr = nRetErr - 1; endif; // Now cycle through the components calculating their sizes nListResult = ListGetFirstString(g_listComponentDirectories, szDir); while (END_OF_LIST != nListResult) // Get size nComponentSize = NGetComponentFileSize(szPegasusCPU, szDir); // Add it to list of component sizes nRetErr = nRetErr + ListAddItem (g_listComponentSizes, nComponentSize, AFTER); nListResult = ListGetNextString(g_listComponentDirectories, szDir); endwhile; // Check for errors... if ( nRetErr < 0 ) then MessageBox ("Memory low. Unable to create string list.", SEVERE); exit; // bail endif; end; /*++ InitializeComponentVars: - initialize all variables for components - create any dynamically-allocated lists, which will be destroyed in the "CleanUp" function Arguments: None Return Value: None --*/ function InitializeComponentVars() NUMBER nRetErr; NUMBER i; begin nRetErr = 0; // no errors yet // We maintain a list of file extensions that should be decompressed from the games.z file to the desktop. // This list does NOT contain the CPU type defined in szPegasusCPU. g_listFileExtensions = ListCreate(STRINGLIST); if (LIST_NULL = g_listFileExtensions) then nRetErr = nRetErr - 1; endif; // Now populate this list... nRetErr = nRetErr + ListAddString (g_listFileExtensions, "load", AFTER); // needed for each component //nRetErr = nRetErr + ListAddString (g_listFileExtensions, "unload", AFTER); // needed for each component to make uninstall clean // BUGBUG: ido put this back! nRetErr = nRetErr + ListAddString (g_listFileExtensions, "wav", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "htc", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "htp", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "2bp", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "txt", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "dll", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "ico", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "exe", AFTER); nRetErr = nRetErr + ListAddString (g_listFileExtensions, "doc", AFTER); // $ADDGAME - add more file extensions here // First, initialize the lists we need. We'll populate them later. g_listComponentNames = ListCreate(STRINGLIST); if (LIST_NULL = g_listComponentNames) then nRetErr = nRetErr - 1; endif; g_listComponentSizes = ListCreate(NUMBERLIST); if (LIST_NULL = g_listComponentSizes) then nRetErr = nRetErr - 1; endif; g_listComponentDirectories = ListCreate(STRINGLIST); if (LIST_NULL = g_listComponentDirectories) then nRetErr = nRetErr - 1; endif; g_listComponentsToInstall = ListCreate(NUMBERLIST); if (LIST_NULL = g_listComponentsToInstall) then nRetErr = nRetErr - 1; endif; g_listComponentPPCLoadFile = ListCreate(STRINGLIST); if (LIST_NULL = g_listComponentPPCLoadFile) then nRetErr = nRetErr - 1; endif; g_listComponentUninstallName = ListCreate(STRINGLIST); if (LIST_NULL = g_listComponentUninstallName) then nRetErr = nRetErr - 1; endif; // These are the names that appear in the component-selection dialog box: nRetErr = nRetErr + ListAddString (g_listComponentNames, "Paint Program for Windows CE", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Cascading Menus", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Control Panel Annunciators", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Mute", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Remote Control for Windows CE", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Sound Scheme: Analog", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Sound Scheme: Metallic", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Sound Scheme: Organic", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentNames, "Bitmap Tiles", AFTER); // $ADDGAME - add more names here // Here are the component sizes. However, since we have not yet determined the CPU // type of this machine, we can't do this calculation now. Therefore, we fill // the list now with bogus data so that it can be destroyed before the real list is // created later. for i = 1 to ListCount(g_listComponentNames) nRetErr = nRetErr + ListAddItem (g_listComponentSizes, 1, AFTER); endfor; // These are the names of the directories in which each game has been compressed in the games.z file. nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Ppaint", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Cascade", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Annun", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Mute", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Rcontrol", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Sound1", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Sound2", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Sound3", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentDirectories, "Wall", AFTER); // $ADDGAME - add more directory names here // This is a boolean list of which components to install. The system maintains this automatically. for i = 1 to ListCount(g_listComponentNames) nRetErr = nRetErr + ListAddItem (g_listComponentsToInstall, 1, AFTER); endfor; // This is a list of the .load filenames to send to PPCLoad.DLL nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Ppaint.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Cascade.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Annunciator.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Mute.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "RemoteControl.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Analog.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Metallic.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Organic.load", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentPPCLoadFile, "Wallpaper.load", AFTER); // $ADDGAME - add more .load files here // This is a list of names users will see when they try to uninstall components nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Ppaint", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Cascade", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Annunciator", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Mute", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "RemoteControl", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Analog", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Metallic", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Organic", AFTER); nRetErr = nRetErr + ListAddString (g_listComponentUninstallName, "Wallpaper", AFTER); // $ADDGAME - add more uninstall names here // Check for errors... if ( nRetErr < 0 ) then MessageBox ("Memory low. Unable to create string lists.", SEVERE); exit; // bail endif; end; /*++ CleanUpComponentVars: - destroy lists created for components Arguments: None Return Value: None --*/ function CleanUpComponentVars() begin // We need to destroy the file extensions list we created ListDestroy(g_listFileExtensions); // We need to destroy the component lists we created ListDestroy(g_listComponentNames); ListDestroy(g_listComponentSizes); ListDestroy(g_listComponentDirectories); ListDestroy(g_listComponentsToInstall); ListDestroy(g_listComponentPPCLoadFile); ListDestroy(g_listComponentUninstallName); end; /*++ InitializeGlobals: - initialize all variables global to all functions - create any dynamically-allocated lists, which will be destroyed in the "CleanUp" function Arguments: None Return Value: None --*/ function InitializeVariables() STRING szMinervaLocation; STRING szTemp; NUMBER nvRegType; NUMBER nvSize; STRING szInstDir; begin g_szDllFilename = SUPPORTDIR ^ SZ_PEGLOAD_DLL; // BUGBUG: Note we are using a local version of this! g_szDllFilename1 = SUPPORTDIR ^ szPRIVATE_HELPER_DLL; // BUGBUG: Note we are using a local version of this! if ( UseDLL( g_szDllFilename ) < 0 ) then MessageBox( "Cannot load or find PPCLOAD.DLL, which is required for installation.\nPlease ensure PPCLOAD.DLL is available in the current path.", SEVERE ); exit; endif; // load our private helper DLL if ( UseDLL( g_szDllFilename1 ) < 0 ) then MessageBox( "Cannot load or find DELVAL.DLL, which is required for installation.\nPlease ensure DELVAL.DLL is available in the current path.", SEVERE ); exit; endif; nTotalFileSize = 0; // get the InstallShield-system variables if ( !FGetDesktopDirectory( g_hwnd, szFOLDER_DESKTOP ) ) then szFOLDER_DESKTOP = WINDIR ^ "desktop"; // set the error case to our best guess endif; if ( !FGetStartupDirectory( g_hwnd, szFOLDER_STARTUP ) ) then szFOLDER_STARTUP = WINDIR ^ "start menu\\programs\\startup"; // set the error case to our best guess endif; // set the default destination directories // For the desktop location we first have to figure out if the HPC Explorer has been installed yet, since // we want to use its install path. RegDBSetDefaultRoot( HKEY_LOCAL_MACHINE ); if ( 0 > RegDBGetKeyValueEx("\\SOFTWARE\\Microsoft\\Pegasus", "InstalledDir", nvRegType, szMinervaLocation, nvSize)) then // Hasn't been installed yet, so we can't run setup. MessageBox( "Setup cannot find a version of HPC Explorer on this computer.\n\n" + "Please make sure HPC Explorer is installed and then run Setup again.", SEVERE ); CleanUp(); else // Check to see if the registry value is legal. If it isn't, use a default. if ( ( GetDisk( szMinervaLocation, szTemp ) = 0 ) && ( "" != szTemp ) ) then szDestDirDesktop = szMinervaLocation ^ SZ_INSTALL_SUBDIR; else szDestDirDesktop = TARGETDISK ^ SZ_DEFAULT_DESKTOP_LOCATION; endif; endif; szDestDirPegasus = SZ_DEST_DIR_PEGASUS; // get the user name and company RegDBSetDefaultRoot( HKEY_CURRENT_USER ); if ( 0 > RegDBGetKeyValueEx("\\SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", "DefName", nvRegType, szUserName, nvSize) ) then szUserName = ""; endif; if ( 0 > RegDBGetKeyValueEx("\\SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", "DefCompany", nvRegType, szUserCompany, nvSize) ) then szUserCompany = ""; endif; szUninstLogFile = ""; // initialize the file set szFileSet = "General"; // initialize the Pegasus CPU szPegasusCPU = ""; end; /*++ StripDoubleQuotes: - to strip out all double-quotes from a string Arguments: szText - IN/OUT - text string to be stripped of double quotes Return Value: None Notes: We need to strip out double-quotes, because we use double-quotes to delimit strings passed to PPCLoad::Load(). If we don't do this, PPCLoad::Load() will not read the parameters correctly, and will report an error --*/ function StripDoubleQuotes( szText ) NUMBER nPos; STRING szTemp1, szTemp2; begin nPos = StrFind( szText, "\"" ); while ( nPos >= 0 ) StrSub( szTemp1, szText, 0, nPos ); StrSub( szTemp2, szText, nPos + 1, StrLength( szText ) - nPos - 1 ); szText = szTemp1 + szTemp2; nPos = StrFind( szText, "\"" ); endwhile; end; /*++ SetupScreen: - draw the background screen - draw the main splash bitmap Arguments: None Return Value: None --*/ function SetupScreen() begin // set the title of all 'yes/no' dialogs SetDialogTitle( DLG_ASK_YESNO, SZ_PRODUCT_NAME); SetDialogTitle( DLG_MSG_INFORMATION, SZ_PRODUCT_NAME); SetDialogTitle( DLG_MSG_WARNING, SZ_PRODUCT_NAME); SetDialogTitle( DLG_MSG_SEVERE, SZ_PRODUCT_NAME); // disable the main background window Disable( BACKGROUND ); // set the installation info, which is required for registry entries InstallationInfo( SZ_COMPANY_NAME, SZ_PRODUCT_NAME, SZ_PRODUCT_VERSION, SZ_PRODUCT_KEY_1 ); // start up full screen Enable( FULLWINDOWMODE ); // use individuall filename resolution on progress indicator Enable( INDVFILESTATUS ); // use 256 color bitmap Enable( BITMAP256COLORS ); // use the standard blue background SetColor( BACKGROUND, BK_BLUE ); // gradient blue background // set the caption SetTitle( SZ_PRODUCT_NAME, 0, BACKGROUNDCAPTION ); // caption bar text SetTitle( SZ_PRODUCT_NAME, 28, WHITE ); // caption bar text // get the background window g_hwnd = GetActiveWindow(); // maximize the window ShowWindow( g_hwnd, SW_MAXIMIZE ); // re-enable the background window Enable( BACKGROUND ); // enable the dialog cache to eliminate screen flashing between dialogs Enable( DIALOGCACHE ); // set the bitmap for each dialog box DialogSetInfo( DLG_INFO_ALTIMAGE, "@" + SUPPORTDIR ^ SZ_BITMAP_DIALOG, TRUE ); // IShield docs says "@" is necessary end; /*++ SetupWelcome: - display the welcome dialog Arguments: None Return Value: None --*/ function SetupWelcome() begin // disable back button dialog Disable( BACKBUTTON ); // set product name in welcome dialog SdProductName( SZ_PRODUCT_NAME ); // show welcome dialog SdWelcome( SZ_PRODUCT_NAME, "Welcome to %P Setup. Setup will copy the PowerToys to your desktop computer first, and then install it on your HPC." ); // $MODIFY // re-enable the back button in the welcome dialog Enable( BACKBUTTON ); end; /*++ DoSystemTest: - determine if Minerva has been installed - check for minimum hard drive space - determine the operating system (for operating system-specific functionality) Arguments: OUT: szPegasusCPU - the Pegasus CPU type Return Value: None --*/ function DoSystemTest( szPegasusCPU ) POINTER psz; begin // we want to pass 'szPegasusCPU' by reference - this is how it's done in InstallShield psz = AddressString( szPegasusCPU ); // get the CPU type from PegLoad if ( !Load_PegCpuType( psz ) ) then // CPU not supported MessageBox( "Setup does not recognize the HPC CPU type, or the HPC Explorer has not been run yet.\n\n" + "Please refer to the documentation for more details.", SEVERE ); CleanUp(); endif; // at this point, 'szPegasusCPU' will have the correct string end; /*++ CheckForConflicts: - determine if a copy of this setup is running - determine if PegMan is currently running - check for any other active programs that might conflict with setup Arguments: None Return Value: None --*/ function CheckForConflicts() HWND hwnd, hwndNext; STRING szConflicts; STRING szWarning; begin szConflicts = ""; // first, get the active window hwnd = GetActiveWindow(); // now check if another instance of this Setup is running hwndNext = FindWindowEx( 0, hwnd, "InstallShield_Win", 0 ); if ( hwndNext && (hwndNext != hwnd) ) then // there are problems when closing this window and restoring the other one - so we will just warn the user szConflicts = szConflicts + "\nInstallShield Setup"; endif; // check if Minerva is currently running /* We don't have to do this. commented out to fix bug 13657 hwnd = FindWindowEx( 0, 0, "PegMgrClass", 0 ); if ( hwnd ) then szConflicts = szConflicts + "\n" + SZ_COMPANY_NAME + " " + SZ_MINERVA_NAME; endif; */ // BUGBUG - now check for other programs here // print out an error message if conflicts are encountered if ( szConflicts != "" ) then szWarning = SZ_PRODUCT_NAME + " Setup has determined that the following application(s) are running:\n" + szConflicts + "\n\nWe recommend that you close these application(s) before continuing. " + "Continue with setup?"; if ( NO = AskYesNo( szWarning, NO ) ) then CleanUp(); endif; endif; end; /*++ NGetComponentFileSize: - calculates the size of a component given the directory in the compressed file that contains that component. Arguments: IN: szPegasusCPU - the Pegasus CPU type IN: szComponentDirectory - dir in the compressed file containing the component Return Value: The total file size of the component --*/ function NGetComponentFileSize( szPegasusCPU, szComponentDirectory ) NUMBER nvSize; // file size STRING svInfo; NUMBER nComponentSize; // total component size STRING szFileExtension; NUMBER nListResult; // used to traverse a list begin // Initialize component size nComponentSize = 0; // We calculate the component size by adding the following: // 1) The CPU-specific files (exe's and dll's) // 2) The files ending in extensions specified in g_listFileExtensions // Get CPU specific size CompressInfo( SZ_SOURCE_FILE, szComponentDirectory + "\\*." + szPegasusCPU, COMP_INFO_ORIGSIZE | INCLUDE_SUBDIR, nvSize, svInfo ); nComponentSize = nComponentSize + nvSize; // Now get the file sizes of the files specified in g_listFileExtensions nListResult = ListGetFirstString (g_listFileExtensions, szFileExtension); while (END_OF_LIST != nListResult) CompressInfo( SZ_SOURCE_FILE, szComponentDirectory + "\\*." + szFileExtension, COMP_INFO_ORIGSIZE | INCLUDE_SUBDIR, nvSize, svInfo ); nComponentSize = nComponentSize + nvSize; nListResult = ListGetNextString (g_listFileExtensions, szFileExtension); endwhile; return nComponentSize; end; /*++ NGetTotalFileSize: - calculate the total file size of all the components that the user has selected to install. Arguments: IN: szPegasusCPU - the Pegasus CPU type Return Value: The total file size --*/ function NGetTotalFileSize( szPegasusCPU ) NUMBER nTotalSize; NUMBER nInstallComponent, nComponentSize; NUMBER nListResult; // used to traverse a list begin nTotalSize = 0; // Cycle through all the components to see which is installed and get their sizes. nListResult = ListGetFirstItem (g_listComponentsToInstall, nInstallComponent); ListGetFirstItem (g_listComponentSizes, nComponentSize); while (END_OF_LIST != nListResult) if (nInstallComponent) then // are we installing this component? nTotalSize = nTotalSize + nComponentSize; endif; nListResult = ListGetNextItem (g_listComponentsToInstall, nInstallComponent); ListGetNextItem (g_listComponentSizes, nComponentSize); endwhile; return nTotalSize; end; /*++ NRegisterUser: - get and save the user and company name Arguments: OUT: szUserName - the user's name OUT: szUserCompany - the user's company Return Value: BACK - go back to last dialog NEXT - continue to next dialog --*/ function NRegisterUser( szUserName, szUserCompany ) STRING szMsg; NUMBER nResult; BOOL fNameEntered; begin // InstallShield's "SdRegisterUser" dialog will disable the NEXT button unless both // fields are non-empty. Instead, we will allow for blanks szMsg = "Enter your name and company information below."; fNameEntered = FALSE; while ( !fNameEntered ) nResult = SdShowDlgEdit2( SZ_PRODUCT_NAME, szMsg, "N&ame:", "&Company:", szUserName, szUserCompany ); if ( (BACK = nResult) || (szUserName != "") ) then // exit the loop fNameEntered = TRUE; else MessageBox( "You must enter a name to continue.", WARNING ); endif; endwhile; // bugbug - do something with the user name/company return nResult; end; /*++ NGetDestDesktop: - ask for the destination directory on the desktop - create the directory if it does not exist Arguments: OUT: szDestDirDesktop - the destination directory on the desktop Return Value: BACK - go back to last dialog NEXT - continue to next dialog --*/ function NGetDestDesktop( szDestDirDesktop ) BOOL fValidPath; // is the destination directory a valid path? NUMBER nRetErr; begin fValidPath = FALSE; while ( !fValidPath ) nRetErr = AskDestPath( "Select Destination Directory on the Desktop", "Setup will install " + SZ_PRODUCT_NAME + " in the following destination directory " + "on the Desktop.\n\n" + "To install to this directory, click Next.\n\n" + "To install to a different directory, click the Browse button.", szDestDirDesktop, 0 ); if ( nRetErr < 0 ) then MessageBox( "Directory creation error. Please check your target location and try again.", SEVERE ); CleanUp(); elseif ( nRetErr = BACK ) then // fake a valid path to exit the loop fValidPath = TRUE; elseif ( nRetErr = NEXT ) then // check for valid path - the above dialog does not always check, it seems if ( ExistsDir( szDestDirDesktop ) = NOTEXISTS ) then if ( YES = AskYesNo( "The directory:\n\n'" + szDestDirDesktop + "'\n\ndoes not exist. Do you want the directory to be created?", YES ) ) then // create the new directory if ( CreateDir( szDestDirDesktop ) < 0 ) then MessageBox( "Cannot create directory:\n\n'" + szDestDirDesktop + "'\n\nPlease select a different directory.", WARNING ); else fValidPath = TRUE; endif; endif; else fValidPath = TRUE; endif; endif; endwhile; return nRetErr; end; /*++ FCheckEnoughSpace: - check if there is enough hard drive space for the selected components - calls 'NGetSelectionSize' to determine the total file size of the selected components Arguments: IN: nTotalFileSize - total file size IN: szDestDirDesktop - destination directory on desktop Return Value: TRUE - enough space FALSE - not enough space --*/ function FCheckEnoughSpace( nTotalFileSize, szDestDirDesktop ) NUMBER nTotalWithExtra; // total size with extra space required NUMBER nDiskSpace; // total remaining disk space STRING szMsg; begin nTotalWithExtra = nTotalFileSize + cEXTRA_SPACE_REQUIRED; // check if target disk has enough space nDiskSpace = GetDiskSpace( szDestDirDesktop ); if ( nDiskSpace < nTotalWithExtra ) then Sprintf( szMsg, "There is not enough disk space available to install the\n" + SZ_PRODUCT_NAME + "installation files in the following location:\n\n" + "'" + szDestDirDesktop + "'\n\nSetup requires at least %ld bytes free. Continue anyway?", nTotalWithExtra ); if ( NO = AskYesNo( szMsg, NO ) ) then return FALSE; endif; endif; return TRUE; // enough space, or user want to continue anyways end; /*++ NGetDestPegasus: - ask for the destination directory on the Pegasus Arguments: OUT: szDestDirPegasus - the destination directory on the Pegasus Return Value: BACK - go back to last dialog NEXT - continue to next dialog NOTE: We cannot determine if the path is valid on the Pegasus. The path will be created when PPCLOAD.DLL is called, and it will fail if it cannot create the directory, or there is not enough space on the Pegasus. --*/ function NGetDestPegasus( szDestDirPegasus ) NUMBER nRetErr; STRING szTempDir; begin // set the dialog title SetDialogTitle( DLG_ASK_TEXT, "Select Destination Directory on the HPC."); szTempDir = szDestDirPegasus; // ask for the destination directory on the Pegasus nRetErr = AskText( "Setup will install " + SZ_PRODUCT_NAME + " in the following destination directory " + "on the HPC." + "To install to this directory, click Next.", szTempDir, szDestDirPegasus ); if ( NEXT = nRetErr ) then // strip the drive letter if it was included GetDir( szDestDirPegasus, szDestDirPegasus ); // PPCLOAD.DLL requires that the path be absolute - since there is no such thing as relative paths on the Pegasus // So, instead of elaborate checks to ensure an initial backslash ("\") at the beginning of the path, // we will use InstallShield's built-in functions... szTempDir = "C:" ^ szDestDirPegasus; // create a dummy drive letter GetDir( szTempDir, szDestDirPegasus ); // get the pathname, which will include the initial backslash // strip out double-quotes StripDoubleQuotes( szDestDirPegasus ); else // the BACK button was pressed szDestDirPegasus = szTempDir; endif; return nRetErr; end; /*++ NGetCopyConfirmation: - display the components selected, the destination directory, and the destination folder - ask for user confirmation Arguments: IN: nTotalFileSize - total file size IN: szDestDirDesktop - destination directory on desktop IN: szDestDirPegasus - destination directory on Pegasus Return Value: BACK - go to previous dialog NEXT - go to next dialog --*/ function NGetCopyConfirmation( nTotalFileSize, szDestDirDesktop, szDestDirPegasus) LIST listInfo; // list to contain the displayed info NUMBER nRetErr; STRING szFileSize; begin nRetErr = 0; // all list errors are less than zero listInfo = ListCreate( STRINGLIST ); if ( listInfo = LIST_NULL ) then // forget the confirmation if there was an error return NEXT; endif; // show total size NumToStr( szFileSize, nTotalFileSize ); nRetErr = nRetErr + ListAddString( listInfo, "Total File Size:", AFTER ); nRetErr = nRetErr + ListAddString( listInfo, "\t" + szFileSize + " bytes", AFTER ); // show destination directory on desktop nRetErr = nRetErr + ListAddString( listInfo, "", AFTER ); nRetErr = nRetErr + ListAddString( listInfo, "Desktop Destination Directory:", AFTER ); nRetErr = nRetErr + ListAddString( listInfo, "\t" + szDestDirDesktop, AFTER ); // show destination directory on Pegasus nRetErr = nRetErr + ListAddString( listInfo, "", AFTER ); nRetErr = nRetErr + ListAddString( listInfo, "Pegasus Destination Directory:", AFTER ); nRetErr = nRetErr + ListAddString( listInfo, "\t" + szDestDirPegasus, AFTER ); // bypass copy confirmation if there were any errors if ( nRetErr < 0 ) then ListDestroy( listInfo ); return NEXT; else // show copy confirmation dialog nRetErr = SdStartCopy( "Start Copying Files", "Setup is ready to start copying files. If you want " + "to change any settings, click Back. If you are satisfied with the settings, " + "click Next to begin copying files.", listInfo ); ListDestroy( listInfo ); endif; return nRetErr; end; /*++ CreateUninstallInfo: - create the uninstallation information for the desktop required by InstallShield3 Arguments: OUT: szUninstLogFile - log file to store uninstall info IN: szDestDirDesktop - destination directory on desktop Return Value: None --*/ function CreateUninstallInfo( szUninstLogFile, szDestDirDesktop ) begin DeinstallStart( szDestDirDesktop, szUninstLogFile, SZ_DEINSTALL_KEY, 0 ); RegDBSetItem( REGDB_UNINSTALL_NAME, SZ_UNINSTALL_NAME ); end; /*++ SetupFileTransfer: - create the "File Set", to prepare a log of which files that need to be uncompressed and copied Arguments: OUT: szFileSet - the "File Set", a log of files to be copied IN: szDestDirDesktop - destination directory on the desktop IN: szPegasusCPU - Pegasus CPU type Return Value: None --*/ function SetupFileTransfer( szFileSet, szDestDirDesktop, szPegasusCPU ) NUMBER nvSize; // file size STRING svInfo; NUMBER nRetErr; // all error codes are less than zero NUMBER nExist; // checks to see if file extensions used for particular component NUMBER nListResult; // used to traverse a list STRING szComponentDir; NUMBER nInstall; STRING szFileExtension; begin // set the default target TARGETDIR = szDestDirDesktop; // define the file set to be copied to the user's machine FileSetBeginDefine( szFileSet ); // copy over all the files for the Pegasus CPU type SetStatusWindow( -1, "Copying files to the desktop PC..." ); nRetErr = 0; // copy file to desktop for each component nListResult = ListGetFirstString(g_listComponentDirectories, szComponentDir); nListResult = ListGetFirstItem(g_listComponentsToInstall, nInstall); while (END_OF_LIST != nListResult) if (nInstall) then // Set the target directory on the desktop (different for each component) TARGETDIR = szDestDirDesktop ^ szComponentDir; // Get CPU-specific files first nRetErr = nRetErr + CompressGet( SZ_SOURCE_FILE, szComponentDir + "\\*." + szPegasusCPU, COMP_NORMAL | INCLUDE_SUBDIR ); // Now let's get the non-CPU-specific files nListResult = ListGetFirstString (g_listFileExtensions, szFileExtension); while (END_OF_LIST != nListResult) // See if there are any files of this type to get for the component!! nExist = CompressInfo( SZ_SOURCE_FILE, szComponentDir + "\\" + "*." + szFileExtension, COMP_INFO_ORIGSIZE | INCLUDE_SUBDIR, nvSize, svInfo ); if (0 = nExist) then nRetErr = nRetErr + CompressGet( SZ_SOURCE_FILE, szComponentDir + "\\*." + szFileExtension, COMP_NORMAL | INCLUDE_SUBDIR ); endif; nListResult = ListGetNextString (g_listFileExtensions, szFileExtension); endwhile; endif; nListResult = ListGetNextString(g_listComponentDirectories, szComponentDir); nListResult = ListGetNextItem(g_listComponentsToInstall, nInstall); endwhile; if ( nRetErr < 0 ) then MessageBox( "Error copying files.", WARNING ); endif; FileSetEndDefine( szFileSet ); end; /*++ DoFileTransfer: - perform the actual file copying, using the previously created "File Set" Arguments: IN: szFileSet - the "File Set", a log of files to be copied Return Value: None --*/ function DoFileTransfer( szFileSet ) NUMBER nRetErr; STRING szError; begin // set up progress indicator and information gauge. Enable( STATUS ); Disable( DIALOGCACHE ); StatusUpdate( ON, 100 ); // Perform the file set transfer nRetErr = FileSetPerformEz( szFileSet, 0 ); switch ( nRetErr ) case FS_DONE: // the transfer was completed successfully case FS_OUTOFSPACE: // out of disk space MessageBox("Setup ran out of disk space on " + TARGETDIR + " while copying files.\n\n" + "Please free some space on the target location and run setup again.", SEVERE); CleanUp(); case FS_CREATEDIR: // create directory error MessageBox( "Unable to create a directory under\n\n'" + TARGETDIR + "'\n\n" + "Please check write access to this directory.", SEVERE ); CleanUp(); default: // group all other errors under default label NumToStr( szError, nRetErr ); MessageBox( "General file transfer error. " + "Please check your target location and try again.\n\n"+ "Error Number: " + szError, SEVERE ); CleanUp(); endswitch; Disable( STATUS ); end; /*++ FinishSetup: - to display the finished-setup dialog - ask the user to view the 'readme' file Arguments: IN: nTotalFileSize - total file size IN: szDestDirDesktop - destination directory on desktop IN: szDestDirPegasus - destination directory on Pegasus IN: szPegasusCPU - Pegasus CPU type IN: szUserName - register user's name IN: szUserCompany - register user's company Return Value: None --*/ function FinishSetup( nTotalFileSize, szDestDirDesktop, szDestDirPegasus, szPegasusCPU, szUserName, szUserCompany ) STRING szMsg1; STRING szMsg2; STRING szReadmeMsg; BOOL fTemp; BOOL fTemp2; NUMBER nFileHandle; NUMBER nRetErr; STRING szErrCode; BOOL fRetryDownload; HWND hwndMine; // window handle to this app STRING szDllFilename; // PPCLOAD.DLL filename - to load the program onto Pegasus STRING szCmdLine; NUMBER nPegFreeSpace; STRING szAppName, szComponentDir, szLoadFile, szUninstall NUMBER nComponentSize, nInstall; NUMBER nListResult, nInstallResult; STRING szReadmeFile; STRING szTemp; STRING szPathname; STRING szFolderDir; begin // So far no errors... nInstallResult = 1; // strip all double quotes for strings (we already do this for szDestDirPegasus) StripDoubleQuotes( szPegasusCPU ); StripDoubleQuotes( szUserName ); StripDoubleQuotes( szUserCompany ); // get the current window handle // this must be done before launching the readme file, because it won't find our window handler! hwndMine = GetActiveWindow(); szMsg1 = SZ_PRODUCT_NAME + " Setup has finished uncompressing the installation files to your desktop computer. " + "The program files will now be copied to your HPC.\n\nPlease ensure that your " + "HPC is connected and turned on."; szMsg2 = "Click Finish to start downloading to the HPC."; // show the finish dialog MessageBeep (0); SdFinish( "HPC Downloading", szMsg1, szMsg2, "", "", fTemp, fTemp2 ); SdShowMsg("Starting download to the HPC. Please make sure the HPC is connected.", TRUE ); // initialize PPCLOAD.DLL nRetErr = Load_Init(); if ( nRetErr != 0 ) then MessageBox( "Setup could not start communications with the HPC.\n\nPlease check all connections and press OK to try again.", WARNING ); // try a second time nRetErr = Load_Init(); if ( nRetErr != 0 ) then MessageBox( "Setup could not start communications with the HPC.\n\nPlease reboot the HPC and try installing again.", SEVERE ); CleanUp(); endif; endif; SdShowMsg("", FALSE); // check if enough space nPegFreeSpace = Load_PegFreeSpace(); // SprintfBox( WARNING, "Free Space", "Required: %d Free on Pegasus: %d", nTotalFileSize, nPegFreeSpace ); if ( nPegFreeSpace < nTotalFileSize ) then // add some extra space szMsg1 = "There is not enough free storage memory on the HPC to install\n" + SZ_PRODUCT_NAME + ".\n\n" + "Please delete some files from the HPC or increase the\namount of storage memory available.\n\n" + "Continue installation? (not recommended)"; if ( NO = AskYesNo( szMsg1, NO ) ) then Load_Exit(); MessageBox( "Download stopped. Please increase the amount of storage memory\n" + "available on the HPC and run Setup again.", INFORMATION ); CleanUp(); endif; endif; // Hey, let's grab the first file to install nListResult = ListGetFirstString (g_listComponentNames, szAppName); nListResult = ListGetFirstString (g_listComponentPPCLoadFile, szLoadFile); nListResult = ListGetFirstString (g_listComponentUninstallName, szUninstall); nListResult = ListGetFirstItem (g_listComponentsToInstall, nInstall); // 8/30/96 idobs: Bugfix. Should pass component size to pccload, not total gamepack size. nListResult = ListGetFirstItem (g_listComponentSizes, nComponentSize); nListResult = ListGetFirstString (g_listComponentDirectories, szComponentDir); // Ok, time to install each component now... while (END_OF_LIST != nListResult) if (nInstall) then // build the LOAD.DLL command line: // <cpuType> <appName> <installDirectory> <totalBytesToCopy> <userName> <userCompany> <appLoadFile.load> Sprintf( szCmdLine, "\"%s\" \"%s\" \"%s\" %d \"%s\" \"%s\" \"%s\"", szPegasusCPU, szUninstall, SZ_DEST_DIR_PEGASUS, nComponentSize, szUserName, szUserCompany, szDestDirDesktop ^ szComponentDir ^ szLoadFile); // MessageBox( szCmdLine, WARNING ); // write the command line to a batch file /* if ( 0 = CreateFile( nFileHandle, szDestDirDesktop, "setup.bat" ) ) then szMsg1 = "load " + szCmdLine; WriteLine( nFileHandle, szMsg1 ); CloseFile( nFileHandle ); endif; */ // check if the app already exists /* We will no longer do this. It's confusing, and really isn't a serious problem. This comment rseolves bug 13681, part 4. Yes, that's right. A single bug with 4 parts. if ( Load_AlreadyInstalled( SZ_PPCLOAD_APPNAME ) ) then szMsg1 = SZ_PRODUCT_NAME + " is already installed. You will lose the memory taken\n" + "by the older installation if you do not remove it first (using 'Remove Programs'\n" + "on the HPC).\n\n" + "Continue installation?"; if ( NO = AskYesNo( szMsg1, NO ) ) then Load_Exit(); MessageBox( "Download stopped.", INFORMATION ); CleanUp(); endif; endif; */ // use LOAD.DLL to download the app to Pegasus nRetErr = Load( hwndMine, szCmdLine ); // BUGBUG - must handle error code correctly if ( nRetErr != LOAD_SUCCESS ) then // we are not handling all the possible error cases - just the ones we need the user to know switch ( nRetErr ) case LOAD_OUTOFSTORAGE: szErrCode = "There is not enough free storage memory on the HPC to install " + SZ_PRODUCT_NAME + ".\n" + "Please remove some files from the HPC or increase the\namount of storage memory available and run Setup again."; case LOAD_CANCELLEDBYUSER: szErrCode = "Application installation cancelled."; case LOAD_INVALID_PARAMETER: szErrCode = "The application installation received an invalid parameter.\n\nPlease run Setup again and ensure that all the information entered during Setup is correct."; case LOAD_DISCONNECTED: szErrCode = "Connection has been dropped.\n\nPlease check that the serial cable is connected to the desktop and the device, and DCC Manager is running."; case LOAD_CANT_CREATE_DIR: szErrCode = "A file on the HPC has the same name as the installed directory.\n\nPlease run Setup again, and choose a different installation directory."; default: szErrCode = "An unknown error occurred during the application installation.\n\nPlease ensure both the desktop and HPC are connected."; endswitch; MessageBox( szErrCode, SEVERE ); nListResult = END_OF_LIST; // Hey, we need to stop installing more components! nInstallResult = 0; // Didn't complete installation endif; endif; // Get the next component if (END_OF_LIST != nListResult) then nListResult = ListGetNextString (g_listComponentNames, szAppName); nListResult = ListGetNextString (g_listComponentPPCLoadFile, szLoadFile); nListResult = ListGetNextString (g_listComponentUninstallName, szUninstall); nListResult = ListGetNextItem (g_listComponentsToInstall, nInstall); // 8/30/96 idobs: Bug fix. Should pass component size to pccload, not total gamepack size. nListResult = ListGetNextItem (g_listComponentSizes, nComponentSize); nListResult = ListGetNextString (g_listComponentDirectories, szComponentDir); endif; endwhile; // Only tell user setup is complete if it worked! if (nInstallResult) then MessageBox( "Setup complete. To run the PowerToys, select one from Start->Program Files->Accessories.", INFORMATION ); // $MODIFY szReadmeFile = SUPPORTDIR ^ "README.TXT"; LongPathToShortPath( szReadmeFile ); LaunchAppAndWait( "NOTEPAD.EXE " + szReadmeFile, "", NOWAIT); Delay(2); endif; // tim - make sure the icons for each exe transfered is updated here Load_RegisterFileInfo(SZ_PRODUCT_KEY_1, szDestDirDesktop ^ SZ_PRODUCT_SUBF_1 ^ SZ_ICON_FILE_1, "Application", 0); // BUGBUG ido Load_RegisterFileInfo(SZ_PRODUCT_KEY_2, szDestDirDesktop ^ SZ_PRODUCT_SUBF_2 ^ SZ_ICON_FILE_2, "Application", 0); // BUGBUG ido Load_RegisterFileInfo(SZ_PRODUCT_KEY_3, szDestDirDesktop ^ SZ_PRODUCT_SUBF_3 ^ SZ_ICON_FILE_3, "Application", 0); // BUGBUG ido szTemp = szFOLDER_STARTUP; // "c:\windows\start menu\programs\startup\" StrRemoveLastSlash( szTemp ); // "c:\windows\start menu\programs\startup" ParsePath( szFolderDir, szTemp, PATH ); // Because "szTemp" does not end with a backslash, ParsePath() will think that the last string // at the end of the path is a filename, so it will remove that string szFolderDir = szFolderDir ^ szREMOTE_CONTROL_FOLDER; // append our "HPC Explorer" name to the end of "c:\windows\start menu\programs" LongPathToShortPath( szFolderDir ); szTemp = szDestDirDesktop ^ szREMOTE_CONTROL_DOC; LongPathToQuote(szTemp, TRUE); AddFolderIcon( szFolderDir, szREMOTE_CONTROL_FOLDER_DOC, szTemp, "", "", 0, "", REPLACE); szTemp = szDestDirDesktop ^ szREMOTE_CONTROL_EXE; LongPathToQuote(szTemp, TRUE); AddFolderIcon( szFolderDir, szREMOTE_CONTROL_FOLDER_EXE, szTemp, "", "", 0, "", REPLACE); // uninitialize PPCLOAD.DLL Load_Exit(); CleanUp(); end; /*++ CleanUp: - to de-allocate any dynamically-allocated lists - called before the program exits from normal execution or due to an error Arguments: None Return Value: None --*/ function CleanUp() begin // Clean up variables used for components! CleanUpComponentVars(); UnUseDLL( g_szDllFilename ); // release the DLL from memory UnUseDLL( g_szDllFilename1 ); // release the DLL from memory exit; end; // required for all dialogs #include "sddialog.rul"