home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Magazin 1995 December / CD_12_95.BIN / disk1 / wincake.ms_ / wincake.bin
Text File  |  1995-02-14  |  34KB  |  841 lines

  1. '**************************************************************************
  2. '* $Header:   G:/SRC/WCW/MSSETUP/VCS/WINCAKE.MSV   1.33   20 Dec 1994 16:16:28   PS  $
  3. '*
  4. '* DESCRIPTION: MS-Setup script for Wincake and Wcwdemo.
  5. '*
  6. '* $Log:   G:/SRC/WCW/MSSETUP/VCS/WINCAKE.MSV  $
  7. '*
  8. '*    Rev 1.33   20 Dec 1994 16:16:28   PS
  9. '* Final directory names for 3.01 RC1.
  10. '*
  11. '*    Rev 1.32   20 Dec 1994 12:53:50   PS
  12. '* Add VPIANO to Pro & Pro Demo.
  13. '*
  14. '*    Rev 1.31   13 Dec 1994 18:48:20   PS
  15. '* Added DEFAULT.INS, INS_NOT_OVERWRITTEN dialog.
  16. '*
  17. '*    Rev 1.30   01 Dec 1994 16:43:38   PS
  18. '* New, separate-product production method.  Many changes for 3.01 Beta B.
  19. '*
  20. '*    Rev 1.29   14 Nov 1994 19:31:14   PS
  21. '* Set dest directory for beta testers.
  22. '*
  23. '*    Rev 1.28   11 Nov 1994 19:06:48   PS
  24. '* CAKEXP.EXE.  Allow layout per product.
  25. '*
  26. '*    Rev 1.27   09 May 1994 13:19:02   GH
  27. '* Detect/require 80386 or higher, warn about no mouse.
  28. '*
  29. '*    Rev 1.26   28 Apr 1994 21:26:02   GH
  30. '* Use SRC.INS and MASTER.INS
  31. '*
  32. '*    Rev 1.25   25 Apr 1994 13:40:06   GH
  33. '* For CPW, changed DEST$ to C:\CPW30
  34. '*
  35. '*    Rev 1.24   15 Apr 1994 15:34:48   GH
  36. '* Changes for 2.5 Beta
  37. '*
  38. '*    Rev 1.23   17 Feb 1994 13:17:14   PS
  39. '* Associate .TPL files with us, too.
  40. '*
  41. '*    Rev 1.22   11 Jan 1994 13:47:38   CP
  42. '* Create a Home Studio Demo version.
  43. '*
  44. '*    Rev 1.21   08 Nov 1993 15:41:42   CP
  45. '* Change Lite name from WCWLITE to CAKEHS.
  46. '*
  47. '*    Rev 1.20   23 Aug 1993 14:06:06   CP
  48. '* Default installation directory for Demo is now C:\WCWDEMO to prevent
  49. '* nuking of previous installations.
  50. '*
  51. '*    Rev 1.19   24 May 1993 17:09:22   gwh
  52. '* Removed serial number item from user info prompt.
  53. '*
  54. '*    Rev 1.18   18 Apr 1993 17:50:40   gwh
  55. '* More refinements for user name, organization, serial number stamping.
  56. '*
  57. '*    Rev 1.17   01 Apr 1993 18:32:44   gwh
  58. '* Prompt user for Name, Organization, and Serial number.
  59. '* Stamp the .EXE resources for these items.
  60. '*
  61. '*    Rev 1.16   18 Mar 1993 14:06:42   pws
  62. '* No more need to clean up old DLL's in Windows sys dir (or TTSSEQ.INI).
  63. '* Also check for existence of TTSSEQ.INI in install dir before copying
  64. '* any TTSSEQ.INI found in Windows sys dir before copying new files.
  65. '*
  66. '*    Rev 1.15   05 Mar 1993 12:08:38   pws
  67. '* Fix support for multiple-disk installations, which had broken when
  68. '* we started determining which product we were by testing for the
  69. '* existence of name.EXE on the first diskette but it had been put
  70. '* on the second one.  Now determine which product we are by testing
  71. '* for existence of product-specific section in SETUP.INF file.
  72. '*
  73. '*    Rev 1.14   22 Dec 1992 13:17:36   pws
  74. '* Reflect changed dialog id's in BLDCUI\DIALOGS.H.
  75. '*
  76. '*    Rev 1.13   15 Dec 1992 14:47:18   pws
  77. '* Added CTL3D.DLL.
  78. '*
  79. '*    Rev 1.12   10 Nov 1992 12:37:56   pws
  80. '* Made more dialogs product-specific.
  81. '*
  82. '* ---
  83. '* See logfile for earlier revision comments
  84. '*
  85. '* Copyright (C) 1990- by Greg Hendershott.  All rights reserved.
  86. '**************************************************************************
  87.  
  88. '$INCLUDE 'setupapi.inc'
  89. '$INCLUDE 'msdetect.inc'
  90. '$INCLUDE 'msregdb.inc'
  91.  
  92. 'These should have all been in SETUPAPI.INC.
  93. 'Note that duplicate definitions are errors and so are commented out!
  94.  
  95. 'CONST MB_OK                            = &H0000
  96. CONST MB_OKCANCEL                       = &H0001
  97. CONST MB_ABORTRETRYIGNORE       = &H0002
  98. CONST MB_YESNOCANCEL            = &H0003
  99. CONST MB_YESNO                          = &H0004
  100. CONST MB_RETRYCANCEL            = &H0005
  101. CONST MB_TYPEMASK                       = &H000F
  102.  
  103. 'CONST MB_ICONHAND                      = &H0010
  104. CONST MB_ICONQUESTION           = &H0020
  105. CONST MB_ICONEXCLAMATION        = &H0030
  106. CONST MB_ICONASTERISK           = &H0040
  107. CONST MB_ICONMASK                       = &H00F0
  108.  
  109. CONST MB_ICONINFORMATION        = MB_ICONASTERISK
  110. CONST MB_ICONSTOP                       = MB_ICONHAND
  111.  
  112. CONST MB_DEFBUTTON1                     = &H0000
  113. CONST MB_DEFBUTTON2                     = &H0100
  114. CONST MB_DEFBUTTON3                     = &H0200
  115. CONST MB_DEFMASK                        = &H0F00
  116.  
  117. CONST MB_APPLMODAL                      = &H0000
  118. CONST MB_SYSTEMMODAL            = &H1000
  119. 'CONST MB_TASKMODAL                     = &H2000
  120.  
  121. CONST MB_NOFOCUS                        = &H8000
  122.  
  123. CONST IDOK                                      = 1
  124. CONST IDCANCEL                          = 2
  125. CONST IDABORT                           = 3
  126. CONST IDRETRY                           = 4
  127. CONST IDIGNORE                          = 5
  128. CONST IDYES                                     = 6
  129. CONST IDNO                                      = 7
  130.  
  131. 'Dialog ID's.  NOTE: THIS MUST MATCH BLDCUI\DIALOGS.H!
  132. CONST WELCOME_PR                        = 170
  133. CONST WELCOME_PD                        = 171
  134. CONST WELCOME_HS                        = 172
  135. CONST WELCOME_HD                        = 173
  136. CONST WELCOME_XP                        = 174
  137. CONST WELCOME_XD                        = 175
  138. CONST ASKQUIT                           = 200
  139. CONST DESTPATH                          = 300
  140. CONST USERINFO                          = 310
  141. CONST EXITFAILURE                       = 400
  142. CONST EXITQUIT_PR                       = 670
  143. CONST EXITQUIT_PD                       = 671
  144. CONST EXITQUIT_HS                       = 672
  145. CONST EXITQUIT_HD                       = 673
  146. CONST EXITQUIT_XP                       = 674
  147. CONST EXITQUIT_XD                       = 675
  148. CONST EXITSUCCESS_PR            = 770
  149. CONST EXITSUCCESS_PD            = 771
  150. CONST EXITSUCCESS_HS            = 772
  151. CONST EXITSUCCESS_HD            = 773
  152. CONST EXITSUCCESS_XP            = 774
  153. CONST EXITSUCCESS_XD            = 775
  154. CONST APPHELP_PR                        = 970
  155. CONST APPHELP_PD                        = 971
  156. CONST APPHELP_HS                        = 972
  157. CONST APPHELP_HD                        = 973
  158. CONST APPHELP_XP                        = 974
  159. CONST APPHELP_XD                        = 975
  160. CONST INI_NOT_OVERWRITTEN       = 1000
  161. CONST INS_NOT_OVERWRITTEN       = 1100
  162. CONST BADPATH                           = 6400
  163.  
  164. 'Bitmap ID.
  165. CONST LOGO = 1
  166.  
  167. GLOBAL COMPANY$
  168. GLOBAL PROGNAME$
  169. GLOBAL PRODUCTNAME$
  170. GLOBAL DEST$            'Default destination directory.
  171.  
  172. DECLARE FUNCTION MakePath (szDir$, szFile$) AS STRING
  173. DECLARE SUB MaybeAssociate (szExt$)
  174. DECLARE SUB SafeCopy(szShort$, szLong$)
  175. DECLARE FUNCTION ArgStr$ (Fmt$, Arg1$, Arg2$, Arg3$, Arg4$)
  176.  
  177. INIT:
  178. '======== beg LOCALIZATION ========
  179. 'These are the strings that need to be localized for different languages.
  180. 'Every one of them is located right here in this block.
  181.     CONST COMPANY_$ = "Twelve Tone Systems"
  182.     CONST PRODUCTNAME_PR_$ = "Cakewalk Professional"
  183.     CONST PRODUCTNAME_PD_$ = "Demoversion von Cakewalk Professional"
  184.     CONST PRODUCTNAME_HS_$ = "Cakewalk Home Studio"
  185.     CONST PRODUCTNAME_HD_$ = "Demoversion von Cakewalk Home Studio"
  186.     CONST PRODUCTNAME_XP_$ = "Cakewalk Express"
  187.     CONST PRODUCTNAME_XD_$ = "Demoversion von Cakewalk Express"
  188.     CONST PROGMANGROUPNAME_PR_$ = "Cakewalk Professional"
  189.     CONST PROGMANGROUPNAME_HS_$ = "Cakewalk Home Studio"
  190.     CONST PROGMANGROUPNAME_XP_$ = "Cakewalk Express"
  191.     CONST SETUP_$ = "Installation von"
  192.     CONST SetTitleFmt_$ = "\2 \1"
  193.     CONST setupMessage_$ = "Meldung zur Installation"
  194.     CONST setupProblem_$ = "Poblem bei der Installation"
  195.     CONST setupQuestion_$ = "Frage zur Installation"
  196.     CONST winVerFmt_$ = "Sie verwenden Windows Version \1. \2 ben÷tigt mindestens Windows \3."
  197.     CONST cpuFmt_$ = "\1 setzt mindestens einen 80386er oder schnelleren Rechner voraus."
  198.     CONST mouseFmt_$ = "Viele Funktionen unter \1 werden mit der Maus ausgefⁿhrt."
  199.     CONST errQuitFmt_$ = "Die Installation ist fehlgeschlagen. Wenden Sie sich an den technischen Support von \1."
  200.     CONST driveBase_$ = "A"     'drive letters start at this char
  201.     CONST dskSpcFmt_$ = "\1 ben÷tigt \2 KB mehr (insgesamt \3 KB) auf Laufwerk \4:. Schaffen Sie mehr Speicherplatz."
  202.     CONST userInfoNeedName_$ = "Zur Fortsetzung der Installation mⁿssen Sie Ihren Namen eingeben."
  203.     CONST assocConfirmFmt_$ = ".\1 ist zur Zeit \2 zugeordnet. Wollen Sie sie \3 zuordnen?"
  204.     CONST PRODUCTNAME_VP_$ = "Virtual Piano"
  205.     CONST instMustRestartWinFmt_$ = "\1 wurde installiert. Zur Verwendung des Programms mⁿssen Sie Windows neu starten."
  206. '======== end LOCALIZATION ========
  207.  
  208.         CUIDLL$ = "mscuistf.dll"                'Custom user interface dll
  209.         HELPPROC$ = "FHelpDlgProc"              'Help dialog procedure
  210.  
  211.         'Determine full SETUP.INF path+name (same name for all products).
  212.         szInf$ = GetSymbolValue("STF_SRCINFPATH")
  213.         IF szInf$ = "" THEN
  214.                 szInf$ = GetSymbolValue("STF_CWDDIR") + "SETUP.INF"
  215.         END IF
  216.         ReadInfFile szInf$
  217.  
  218.         'Determine which product we are by seeing which .EXE name reference key
  219.         'is defined.  In DSKLAYT we specified a reference key for the .EXE which
  220.         'is the same as PROGNAME$.  This key is also used for StampResource below.
  221.         IF DoesIniKeyExist(szInf$, "Files", """WINCAKE""") <> 0 THEN
  222.                 PROGNAME$ = "WINCAKE"
  223.                 PRODUCTNAME$ = PRODUCTNAME_PR_$
  224.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_PR_$
  225.                 INIBASENAME$ = "WINCAKE"
  226.                 DEST$ = "C:\CPW30"              'normal
  227. '               DEST$ = "C:\CPW301"             'temp during beta test period
  228.         ELSEIF DoesIniKeyExist(szInf$, "Files", """WCWDEMO""") <> 0 THEN
  229.                 PROGNAME$ = "WCWDEMO"
  230.                 PRODUCTNAME$ = PRODUCTNAME_PD_$
  231.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_PR_$
  232.                 INIBASENAME$ = "WINCAKE"
  233.                 DEST$ = "C:\WCWDEMO"
  234.         ELSEIF DoesIniKeyExist(szInf$, "Files", """CAKEHS""") <> 0 THEN
  235.                 PROGNAME$ = "CAKEHS"
  236.                 PRODUCTNAME$ = PRODUCTNAME_HS_$
  237.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_HS_$
  238.                 INIBASENAME$ = "CAKEHS"
  239.                 DEST$ = "C:\CAKEHS"             'normal
  240. '               DEST$ = "C:\CHS301"             'temp during beta test period
  241.         ELSEIF DoesIniKeyExist(szInf$, "Files", """CHSDEMO""") <> 0 THEN
  242.                 PROGNAME$ = "CHSDEMO"
  243.                 PRODUCTNAME$ = PRODUCTNAME_HD_$
  244.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_HS_$
  245.                 INIBASENAME$ = "CAKEHS"
  246.                 DEST$ = "C:\CHSDEMO"
  247.         ELSEIF DoesIniKeyExist(szInf$, "Files", """CAKEXP""") <> 0 THEN
  248.                 PROGNAME$ = "CAKEXP"
  249.                 PRODUCTNAME$ = PRODUCTNAME_XP_$
  250.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_XP_$
  251.                 INIBASENAME$ = "CAKEXP"
  252.                 DEST$ = "C:\CAKEXP"             'normal
  253. '               DEST$ = "C:\CXP301"             'temp during beta test period
  254.         ELSEIF DoesIniKeyExist(szInf$, "Files", """CAKEXPD""") <> 0 THEN
  255.                 PROGNAME$ = "CAKEXPD"
  256.                 PRODUCTNAME$ = PRODUCTNAME_XD_$
  257.                 PROGMANGROUPNAME$ = PROGMANGROUPNAME_XP_$
  258.                 INIBASENAME$ = "CAKEXP"
  259.                 DEST$ = "C:\CAKEXPD"
  260.         ELSE
  261.                 GOTO ERRQUIT
  262.         END IF
  263.  
  264.         SetBitmap CUIDLL$, LOGO
  265.         SetTitle ArgStr$(SetTitleFmt_$, PRODUCTNAME$, SETUP_$, "", "")
  266.  
  267.         'Check Windows version.
  268.         winVerReqd$ = "3.1"
  269.         winVer$ = LTRIM$( STR$( GetWindowsMajorVersion() ) ) + "." + LTRIM$( STR$( GetWindowsMinorVersion() ) )
  270.         IF winVer$ < winVerReqd$ THEN           'string sort works
  271.                 i% = DoMsgBox( ArgStr$(winVerFmt_$, winVer$, PRODUCTNAME$, winVerReqd$, ""), setupMessage_$, MB_OK+MB_TASKMODAL+MB_ICONHAND )
  272.                 END     'exit SETUP
  273.         END IF
  274.  
  275.         'Check CPU.
  276.         cpu% = GetProcessorType()       '2==80286, 3==80386, 4==80486
  277.         IF cpu% < 3 THEN
  278.                 i% = DoMsgBox( ArgStr$(cpuFmt_$, PRODUCTNAME$, "", "", ""), setupMessage_$, MB_OK+MB_TASKMODAL+MB_ICONSTOP )
  279.                 END     'exit SETUP
  280.         END IF
  281.  
  282.         'Check for mouse.
  283.         IF HasMouseInstalled() = 0 THEN
  284.                 i% = DoMsgBox( ArgStr$(mouseFmt_$, PRODUCTNAME$, "", "", ""), setupMessage_$, MB_OK+MB_TASKMODAL+MB_ICONINFORMATION )
  285.         END IF
  286.  
  287.         'Disk cost list symbols.
  288.         FILECOSTS$   = "FileCosts"
  289.         EXTRACOSTS$  = "ExtraCosts"
  290.         STILLNEEDED$ = "StillNeeded"
  291.         FOR i% = 1 TO 26 STEP 1
  292.                 AddListItem EXTRACOSTS$, "0"
  293.         NEXT i%
  294.         'Add extra cost to Windows drive for ini/progman, etc.
  295.         ixWinDrive% = ASC(UCASE$( MID$(GetWindowsDir(), 1, 1) )) - ASC("A") + 1
  296.         ReplaceListItem EXTRACOSTS$, ixWinDrive%, "10240"
  297.  
  298.  
  299. WELCOME:
  300.         IF PROGNAME$ = "WINCAKE" THEN
  301.                 dlg% = WELCOME_PR
  302.                 dlghelp% = APPHELP_PR
  303.         ELSEIF PROGNAME$ = "WCWDEMO" THEN
  304.                 dlg% = WELCOME_PD
  305.                 dlghelp% = APPHELP_PD
  306.         ELSEIF PROGNAME$ = "CAKEHS" THEN
  307.                 dlg% = WELCOME_HS
  308.                 dlghelp% = APPHELP_HS
  309.         ELSEIF PROGNAME$ = "CHSDEMO" THEN
  310.                 dlg% = WELCOME_HD
  311.                 dlghelp% = APPHELP_HD
  312.         ELSEIF PROGNAME$ = "CAKEXP" THEN
  313.                 dlg% = WELCOME_XP
  314.                 dlghelp% = APPHELP_XP
  315.         ELSEIF PROGNAME$ = "CAKEXPD" THEN
  316.                 dlg% = WELCOME_XD
  317.                 dlghelp% = APPHELP_XD
  318.         END IF
  319.         sz$ = UIStartDlg(CUIDLL$, dlg%, "FInfoDlgProc", dlghelp%, HELPPROC$)
  320.         IF sz$ = "CONTINUE" THEN
  321.                 UIPop 1
  322.         ELSE
  323.                 GOSUB ASKQUIT
  324.                 GOTO WELCOME
  325.         END IF
  326.  
  327.  
  328. GETPATH:
  329.         SetSymbolValue "EditTextIn", DEST$
  330.         SetSymbolValue "EditFocus", "END"
  331. GETPATHL1:
  332.         sz$ = UIStartDlg(CUIDLL$, DESTPATH, "FEditDlgProc", dlghelp%, HELPPROC$)
  333.         DEST$ = GetSymbolValue("EditTextOut")
  334.  
  335.         IF sz$ = "CONTINUE" THEN
  336.                 IF IsDirWritable(DEST$) = 0 THEN
  337.                         GOSUB BADPATH
  338.                         GOTO GETPATHL1
  339.                 END IF
  340.                 UIPop 1
  341.                 ixAppDrive% = ASC(UCASE$( MID$(DEST$, 1, 1) )) - ASC(driveBase_$) + 1
  342.         ELSEIF sz$ = "REACTIVATE" THEN
  343.                 GOTO GETPATHL1
  344.         ELSEIF sz$ = "BACK" THEN
  345.                 UIPop 1
  346.                 GOTO WELCOME
  347.         ELSE
  348.                 GOSUB ASKQUIT
  349.                 GOTO GETPATH
  350.         END IF
  351.  
  352. 'Install.
  353.         GOSUB INSTALL
  354.         IF StillNeed& > 0 THEN
  355.                 GOTO GETPATH
  356.         END IF
  357.  
  358. QUIT:
  359.         ON ERROR GOTO ERRQUIT
  360.  
  361.         IF ERR = 0 THEN
  362.                 IF PROGNAME$ = "WINCAKE" THEN
  363.                         dlg% = EXITSUCCESS_PR
  364.                 ELSEIF PROGNAME$ = "WCWDEMO" THEN
  365.                         dlg% = EXITSUCCESS_PD
  366.                 ELSEIF PROGNAME$ = "CAKEHS" THEN
  367.                         dlg% = EXITSUCCESS_HS
  368.                 ELSEIF PROGNAME$ = "CHSDEMO" THEN
  369.                         dlg% = EXITSUCCESS_HD
  370.                 ELSEIF PROGNAME$ = "CAKEXP" THEN
  371.                         dlg% = EXITSUCCESS_XP
  372.                 ELSEIF PROGNAME$ = "CAKEXPD" THEN
  373.                         dlg% = EXITSUCCESS_XD
  374.                 END IF
  375.         ELSEIF ERR = STFQUIT THEN
  376.                 IF PROGNAME$ = "WINCAKE" THEN
  377.                         dlg% = EXITQUIT_PR
  378.                 ELSEIF PROGNAME$ = "WCWDEMO" THEN
  379.                         dlg% = EXITQUIT_PD
  380.                 ELSEIF PROGNAME$ = "CAKEHS" THEN
  381.                         dlg% = EXITQUIT_HS
  382.                 ELSEIF PROGNAME$ = "CHSDEMO" THEN
  383.                         dlg% = EXITQUIT_HD
  384.                 ELSEIF PROGNAME$ = "CAKEXP" THEN
  385.                         dlg% = EXITQUIT_XP
  386.                 ELSEIF PROGNAME$ = "CAKEXPD" THEN
  387.                         dlg% = EXITQUIT_XD
  388.                 END IF
  389.         ELSE
  390.                 dlg% = EXITFAILURE
  391.         END IF
  392. QUITL1:
  393.         sz$ = UIStartDlg(CUIDLL$, dlg%, "FInfo0DlgProc", 0, "")
  394.         IF sz$ = "REACTIVATE" THEN
  395.                 GOTO QUITL1
  396.         END IF
  397.         UIPop 1
  398.  
  399.         END
  400.  
  401. ERRQUIT:
  402.         i% = DoMsgBox(ArgStr$(errQuitFmt_$, COMPANY_$, "", "", ""), setupMessage_$, MB_OK+MB_TASKMODAL+MB_ICONHAND)
  403.         END
  404.  
  405.  
  406.  
  407. BADPATH:
  408.         sz$ = UIStartDlg(CUIDLL$, BADPATH, "FInfo0DlgProc", 0, "")
  409.         IF sz$ = "REACTIVATE" THEN
  410.                 GOTO BADPATH
  411.         END IF
  412.         UIPop 1
  413.         RETURN
  414.  
  415.  
  416.  
  417. ASKQUIT:
  418.         sz$ = UIStartDlg(CUIDLL$, ASKQUIT, "FQuitDlgProc", 0, "")
  419.  
  420.         IF sz$ = "EXIT" THEN
  421.                 UIPopAll
  422.                 ERROR STFQUIT
  423.         ELSEIF sz$ = "REACTIVATE" THEN
  424.                 GOTO ASKQUIT
  425.         ELSE
  426.                 UIPop 1
  427.         END IF
  428.         RETURN
  429.  
  430.  
  431.  
  432. '**
  433. '**     Purpose:
  434. '**             Builds the copy list and performs all installation operations.
  435. '**     Arguments:
  436. '**             none.
  437. '**     Returns:
  438. '**             none.
  439. '*************************************************************************
  440. INSTALL:
  441.  
  442.         'Get user information; we'll stamp later.
  443.         GOSUB DOUSERINFODIALOG
  444.  
  445.         SrcDir$ = GetSymbolValue("STF_SRCDIR")
  446.  
  447.         'These (normal) files go to the user's specifed app destination directory.
  448.         AddSectionFilesToCopyList "Files", SrcDir$, DEST$
  449.  
  450.         'These files go to the Windows System directory.
  451.         AddSectionFilesToCopyList "system", SrcDir$, GetWindowsSysDir()
  452.  
  453.         StillNeed& = GetCopyListCost(EXTRACOSTS$, FILECOSTS$, STILLNEEDED$)
  454.         IF StillNeed& > 0 THEN
  455.                 ClearCopyList
  456.                 FOR ix% = 1 TO 26 STEP 1        'find first drive that needs space
  457.                         need1& = VAL(GetListItem(STILLNEEDED$, ix%))
  458.                         IF need1& > 0 THEN
  459.                                 GOTO FNDDRV
  460.                         END IF
  461.                 NEXT ix%
  462.                 ix = ixAppDrive                         '(shouldn't happen)
  463.                 need1& = 0
  464.                 StillNeed& = 1
  465. FNDDRV:
  466.                 need$  = LTRIM$(STR$( (need1&+1023) / 1024 ))
  467.                 cost$  = LTRIM$(STR$( (VAL(GetListItem(FILECOSTS$, ix%))+1023) / 1024 ))
  468.                 drive$ = CHR$(ix% - 1 + ASC(driveBase_$))
  469.                 msg$ = ArgStr$(dskSpcFmt_$, PRODUCTNAME$, need$, cost$, drive$)
  470.                 i% = DoMsgBox(msg$, setupProblem_$, MB_RETRYCANCEL+MB_TASKMODAL+MB_ICONHAND)
  471.                 IF i% = IDCANCEL THEN
  472.                         GOSUB ASKQUIT
  473.                 END IF
  474.                 RETURN          'must RETURN out of GOSUB to pop stack, not just GOTO
  475.         END IF
  476.  
  477.         CreateDir DEST$, cmoNone
  478.  
  479.         OpenLogFile MakePath(DEST$, "LOGFILE.OUT"), 0
  480.         WriteToLogFile ""
  481.         WriteToLogFile "User chose as destination directory: '" + DEST$ + "'"
  482.         WriteToLogFile "May have had to create the directory: " + DEST$
  483.         WriteToLogFile ""
  484.  
  485.         CopyFilesInCopyList
  486.  
  487.         'Important: Do this here before any dialogs with an Exit button, so
  488.         'user cannot avoid stamping.
  489.         GOSUB STAMPUSERINFO
  490.  
  491.         SetRegKeyValue PROGNAME$, PRODUCTNAME$
  492.         SetRegKeyValue PROGNAME$+"\shell\print", ""
  493.         SetRegKeyValue PROGNAME$+"\shell\open\command", MakePath(DEST$,PROGNAME$+".EXE") + " %1"
  494.         MaybeAssociate "wrk"
  495.         MaybeAssociate "mid"
  496.         MaybeAssociate "mff"
  497.         MaybeAssociate "tpl"
  498.  
  499. 'Deal with old installation where our app DLL's were in WINDOWS\SYSTEM.
  500. 'No more need to delete old DLL's, since we don't use any with same name now.
  501. 'If old TTSSEQ.INI exists in sysdir but not in appdir, copy it now to preserve settings.
  502.         SysDir$ = GetWindowsSysDir()
  503.         IF DoesFileExist(SysDir$+"TTSSEQ.INI",femExists) <> 0 AND DoesFileExist(DEST$+"TTSSEQ.INI",femExists) = 0 THEN
  504.                 CopyFile SysDir$+"TTSSEQ.INI", DEST$+"\TTSSEQ.INI", cmoNone, 0
  505.         END IF
  506.  
  507. 'If this product includes sysx input support, then it includes DRM.INI, which
  508. 'is the base version of progname.INI containing just the DRM's.
  509. 'So if this product includes DRM.INI, then copy it to progname.INI, except if
  510. 'progname.INI already exists, in which case we inform the user that we didn't
  511. 'overwrite it and he might want to look for new DRM's in DRM.INI.
  512.         drm$ = MakePath(DEST$, "DRM.INI")
  513.         ini$ = MakePath(DEST$, INIBASENAME$+".INI")
  514.         IF DoesFileExist(drm$,femExists) <> 0 THEN      'if this product includes DRM.INI
  515.                 IF DoesFileExist(ini$,femExists) = 0 THEN
  516.                         CopyFile drm$, ini$, cmoVital, 0
  517.                 ELSE
  518.                         sz$ = UIStartDlg(CUIDLL$, INI_NOT_OVERWRITTEN, "FInfoDlgProc", 0, "")
  519.                         IF sz$ = "EXIT" THEN
  520.                                 GOSUB ASKQUIT
  521.                         ELSE
  522.                                 UIPop 1
  523.                         END IF
  524.                 END IF
  525.         END IF
  526.  
  527. 'SRC.INS (complete .INS) was copied over with no name change.
  528. 'DEFAULT.INS (basic default .INS) will be copied to MASTER.INS, which is
  529. 'what the program actually uses, but only if it doesn't already exist.
  530.         default$ = MakePath(DEST$, "DEFAULT.INS")
  531.         master$  = MakePath(DEST$, "MASTER.INS")
  532.         IF DoesFileExist(master$,femExists) = 0 THEN
  533.                 CopyFile default$, master$, cmoVital, 0
  534.         ELSE
  535.                 sz$ = UIStartDlg(CUIDLL$, INS_NOT_OVERWRITTEN, "FInfoDlgProc", 0, "")
  536.                 IF sz$ = "EXIT" THEN
  537.                         GOSUB ASKQUIT
  538.                 ELSE
  539.                         UIPop 1
  540.                 END IF
  541.         END IF
  542.  
  543.         CreateProgmanGroup PROGMANGROUPNAME$, "", cmoNone
  544.         ShowProgmanGroup  PROGMANGROUPNAME$, 1, cmoNone
  545.         CreateProgmanItem PROGMANGROUPNAME$, PRODUCTNAME$, MakePath(DEST$,PROGNAME$+".EXE"), "", cmoOverwrite
  546.         CreateProgmanItem PROGMANGROUPNAME$, "README.WRI", "write.exe "+MakePath(DEST$,"readme.wri"), "", cmoOverwrite
  547.         WriteToLogFile ""
  548.  
  549.         GOSUB INSTALL_VPIANO
  550.  
  551.         WriteToLogFile "SUB Install completed."
  552.         CloseLogFile
  553.  
  554.         RETURN
  555.  
  556.  
  557.  
  558. '**
  559. '**     Purpose:
  560. '**             Install a file without replacing an existing one.
  561. '**     Arguments:
  562. '**             szShort$ - Name like SRC.INS
  563. '**             szLong$  - Name like MASTER.INS
  564. '*************************************************************************
  565. SUB SafeCopy (szShort$, szLong$) STATIC
  566.         szShortPathName$ = MakePath(DEST$, szShort$)
  567.         szLongPathName$ = MakePath(DEST$, szLong$)
  568.         IF DoesFileExist(szLongPathName$,femExists) = 0 THEN
  569.                 CopyFile szShortPathName$, szLongPathName$, cmoVital, 0
  570.         END IF
  571. END SUB
  572.  
  573.  
  574.  
  575. '**
  576. '**     Purpose:
  577. '**             Appends a file name to the end of a directory path,
  578. '**             inserting a backslash character as needed.
  579. '**     Arguments:
  580. '**             szDir$  - full directory path (with optional ending "\")
  581. '**             szFile$ - filename to append to directory
  582. '**     Returns:
  583. '**             Resulting fully qualified path name.
  584. '*************************************************************************
  585. FUNCTION MakePath (szDir$, szFile$) STATIC AS STRING
  586.         IF szDir$ = "" THEN
  587.                 MakePath = szFile$
  588.         ELSEIF szFile$ = "" THEN
  589.                 MakePath = szDir$
  590.         ELSEIF MID$(szDir$, LEN(szDir$), 1) = "\" THEN
  591.                 MakePath = szDir$ + szFile$
  592.         ELSE
  593.                 MakePath = szDir$ + "\" + szFile$
  594.         END IF
  595. END FUNCTION
  596.  
  597.  
  598.  
  599. '**
  600. '**     Purpose:
  601. '**     Arguments:
  602. '**     Returns:
  603. '**             none.
  604. '*************************************************************************
  605. DOUSERINFODIALOG:
  606. 'Get user info for stamping later.
  607.         IF PROGNAME$ <> "WCWDEMO" AND PROGNAME$ <> "CHSDEMO" AND PROGNAME$ <> "CAKEXPD" THEN
  608. GETUSERINFO:
  609.                 sz$ = UIStartDlg(CUIDLL$, USERINFO, "FNameOrgDlgProc", dlghelp%, HELPPROC$)
  610.                 IF sz$ = "REACTIVATE" THEN
  611.                         GOTO GETUSERINFO
  612.                 END IF
  613.  
  614.                 szUser$ = GetSymbolValue( "NameOut" )
  615.                 szCo$ = GetSymbolValue( "OrgOut" )
  616.  
  617.                 'Company may be blank, but not the other two.
  618.                 IF szUser$ = "" THEN
  619.                         i% = DoMsgBox(userInfoNeedName_$, setupProblem_$, MB_OK+MB_TASKMODAL+MB_ICONHAND)
  620.                         GOTO GETUSERINFO
  621.                 END IF
  622.  
  623.                 'Dismiss dialog now that we've validated.
  624.                 UIPop 1
  625.         END IF
  626.  
  627.         RETURN
  628.  
  629.  
  630. '**
  631. '**     Purpose:
  632. '**     Arguments:
  633. '**     Returns:
  634. '**             none.
  635. '*************************************************************************
  636. STAMPUSERINFO:
  637. 'Stamp user info into our .EXE file.
  638.         IF PROGNAME$ <> "WCWDEMO" AND PROGNAME$ <> "CHSDEMO" AND PROGNAME$ <> "CAKEXPD" THEN
  639.  
  640.                 'szUser$ szCo$ were prompted for above.
  641.                 szDat$ = CHR$(LEN(szUser$)) + szUser$
  642.                 szDat$ = szDat$ + CHR$(LEN(szCo$)) + szCo$
  643.  
  644.                 '"Files" is the section name in our .INF file of the .EXE file.
  645.                 '
  646.                 '6 is the resource type for STRINGTABLE entries.
  647.                 '
  648.                 '&H401 is the upper 12 bits of IDS_USERNAME (0x4000) + 1.
  649.                 '
  650.                 'In DSKLAYT we specified a reference key for the .EXE which
  651.                 'is the same as PROGNAME$.
  652.                 StampResource "Files",PROGNAME$,DEST$,6,&H401,szDat$,LEN(szDat$)
  653.         END IF
  654.  
  655.         RETURN
  656.  
  657.  
  658. '**
  659. '**     Purpose:
  660. '**             Associates given filetype with us, but asks for user confirmation
  661. '**             if already set to something else.
  662. '**     Arguments:
  663. '**             szExt$ - filetype extension, e.g. "mid"
  664. '**     Returns:
  665. '**             none.
  666. '*************************************************************************
  667. SUB MaybeAssociate (szExt$) STATIC
  668.         oldProg$ = ""
  669.         ok% = IDYES
  670.  
  671. 'Check Registration Database (overrides WIN.INI [Extensions]).
  672.  
  673.         oldCmd$ = UCASE$( LTRIM$( GetRegKeyValue("."+szExt$+"\shell\open\command") ) )
  674.         IF oldCmd$ = "" THEN    'didn't find direct association, check via prog name
  675.                 oldProg$ = LTRIM$( RTRIM$( GetRegKeyValue("."+szExt$) ) )
  676.                 IF oldProg$ <> "" THEN
  677.                         oldCmd$ = UCASE$( LTRIM$( GetRegKeyValue(oldProg$+"\shell\open\command") ) )
  678.                         oldProduct$ = LTRIM$( RTRIM$( GetRegKeyValue(oldProg$) ) )
  679.                         IF oldProduct$ <> "" THEN       'long product name found, use it
  680.                                 oldProg$ = oldProduct$
  681.                         END IF
  682.                 END IF
  683.         END IF
  684.         IF oldCmd$ <> "" THEN
  685.                 IF INSTR(oldCmd$, PROGNAME$+".EXE") = 0 THEN    'not us, must confirm
  686.                         IF oldProg$ = "" THEN   'no short or long name, parse command string
  687.                                 j% = INSTR(oldCmd$, " ")
  688.                                 IF j% > 1 THEN
  689.                                         oldProg$ = MID$(oldCmd$, 1, j%-1)
  690.                                 ELSE
  691.                                         oldProg$ = oldCmd$
  692.                                 END IF
  693.                         END IF
  694.                 ELSE                                    'it's us, clear oldProg$ => no confirm
  695.                         oldProg$ = ""
  696.                 END IF
  697.                 GOTO MAYBE_CONFIRM              'found association, no need to examine WIN.INI
  698.         END IF
  699.  
  700. 'Check WIN.INI [Extensions].
  701.  
  702.         oldCmd$ = UCASE$( LTRIM$( GetIniKeyString("WIN.INI","Extensions",szExt$) ) )
  703.         IF oldCmd$ <> "" THEN
  704.                 IF INSTR(oldCmd$, PROGNAME$+".EXE") = 0 THEN    'not us, must confirm
  705.                         j% = INSTR(oldCmd$, " ")
  706.                         IF j% > 1 THEN
  707.                                 oldProg$ = MID$(oldCmd$, 1, j%-1)
  708.                         ELSE
  709.                                 oldProg$ = oldCmd$
  710.                         END IF
  711.                 END IF
  712.         END IF
  713.  
  714. 'Get user confirmation if necessary, and do the association if ok.
  715.  
  716. MAYBE_CONFIRM:
  717.         IF oldProg$ <> "" THEN
  718.                 ok% = DoMsgBox(ArgStr$(assocConfirmFmt_$, UCASE$(szExt$), oldProg$, PRODUCTNAME$, ""), setupQuestion_$, MB_YESNO+MB_TASKMODAL+MB_ICONQUESTION)
  719.         END IF
  720.  
  721.         IF ok% = IDYES THEN
  722.                 DeleteRegKey   "."+szExt$       'delete all keys for any old direct association
  723.                 SetRegKeyValue "."+szExt$, PROGNAME$
  724.                 CreateIniKeyValue "WIN.INI", "Extensions", szExt$, MakePath(DEST$,PROGNAME$+".EXE") + " ^." + szExt$, cmoOverwrite
  725.         END IF
  726.  
  727. END SUB
  728.  
  729.  
  730. '**
  731. '**     Purpose:
  732. '**             Installs Virtual Piano and its driver, if part of this product.
  733. '**     Arguments:
  734. '**             none.
  735. '**     Returns:
  736. '**             none.
  737. '**     WARNING:
  738. '**             The current method used here only works with Windows 3.1!
  739. '*************************************************************************
  740. INSTALL_VPIANO:
  741.  
  742. 'If this product doesn't include the Virtual Piano, return now.
  743. '(Currently all products include it.)
  744.  
  745. 'Set up the Virtual Piano program icon.
  746.  
  747.         CreateProgmanItem PROGMANGROUPNAME$, PRODUCTNAME_VP_$, MakePath(DEST$,"VPIANO.EXE"), "", cmoOverwrite
  748.  
  749. 'Display message that it was installed and Windows should be restarted.
  750.  
  751.         i% = DoMsgBox( ArgStr$(instMustRestartWinFmt_$, PRODUCTNAME_VP_$, "", "", ""), setupMessage_$, MB_OK+MB_TASKMODAL+MB_ICONINFORMATION )
  752.  
  753. 'If there's already a SYSTEM.INI [drivers] MIDIn key set to us, we're done.
  754. 'Else find next available SYSTEM.INI [drivers] MIDIn key.
  755.  
  756.         szSysIni$ = GetWindowsDir()+"SYSTEM.INI"
  757.         szSect$ = "drivers"
  758.         szValue$ = "vpiano.drv"
  759.         szKey$ = "MIDI99"
  760.  
  761.         FOR i% = 0 TO 98 STEP 1
  762.                 IF i% = 0 THEN
  763.                         szKeyThis$ = "MIDI"
  764.                 ELSE
  765.                         szKeyThis$ = "MIDI" + LTRIM$( STR$(i%) )
  766.                 END IF
  767.  
  768.                 szOldValue$ = LCASE$( GetIniKeyString(szSysIni$,szSect$,szKeyThis$) )
  769.                 IF szOldValue$ = szValue$ THEN
  770.                         RETURN                                  'already set, we're done
  771.                 ELSEIF szOldValue$ = "" AND szKey$ = "MIDI99" THEN
  772.                         szKey$ = szKeyThis$             'found next key, remember it
  773.                 END IF
  774.         NEXT i%
  775.  
  776. 'Found next available SYSTEM.INI [drivers] MIDIn key.  Set it to point to us.
  777.  
  778.         CreateIniKeyValue szSysIni$, szSect$, szKey$, szValue$, cmoNone
  779.  
  780.         RETURN
  781.  
  782.  
  783.  
  784. '**
  785. '**     Purpose:
  786. '**             Substitutes string args by number into a format string.
  787. '**             Useful for localization, since arg order is now controlled by Fmt$.
  788. '**             The backslash is used as an escape char.
  789. '**             A backslash followed by a digit string substitutes that arg num.
  790. '**             A backslash not followed by digits subs in the next literal char.
  791. '**     Arguments:
  792. '**             Fmt$  - format string containing instances of \N, N is arg num
  793. '**             ArgN$ - string arg to sub in for each instance of \N
  794. '**     Returns:
  795. '**             Final output string with all arg substitution done.
  796. '**     Example:
  797. '**             Fmt$ = "\\1 = \1, \\2 = \2, \\3 = \3, \\Z = \Z, \\11 = \11."
  798. '**             Out$ = ArgStr$(Fmt$, "Arg1", "Arg2", "", "")
  799. '**             REM ...This sets Out$ to "\1 = Arg1, \2 = Arg2, \3 = , \Z = Z, \11 = ."
  800. '*************************************************************************
  801. FUNCTION ArgStr$ (Fmt$, Arg1$, Arg2$, Arg3$, Arg4$) STATIC
  802.  
  803.         rtn$ = Fmt$             'our returned output string is built here
  804.         esc$ = "\"              'this is the esc char we use
  805.         i% = 1                  'current index into string
  806.  
  807.         WHILE 1
  808.                 i% = INSTR(i%, rtn$, esc$)      'loc of next esc char
  809.                 IF i% = 0 THEN
  810.                         EXIT WHILE                              'no more esc chars, quit
  811.                 END IF
  812.                 j% = i% + 1
  813.                 WHILE j% <= LEN(rtn$) AND INSTR("0123456789", MID$(rtn$, j%, 1)) <> 0
  814.                         j% = j% + 1
  815.                 WEND                            'i%+1 is start of number string, j% is end+1
  816.                 IF j% = i% + 1 THEN     'digit string empty, drop esc char and take next char as literal
  817.                         rtn$ = MID$(rtn$, 1, i% - 1) + MID$(rtn$, j%)
  818.                         i% = i% + 1                             'next search pos in string
  819.                 ELSE                            'digit string non-empty, read int and sub in arg
  820.                         num% = VAL(MID$(rtn$, i% + 1, j% - i% - 1))
  821.                         SELECT CASE num%
  822.                         CASE 1
  823.                                 Arg$ = Arg1$
  824.                         CASE 2
  825.                                 Arg$ = Arg2$
  826.                         CASE 3
  827.                                 Arg$ = Arg3$
  828.                         CASE 4
  829.                                 Arg$ = Arg4$
  830.                         CASE ELSE
  831.                                 Arg$ = ""
  832.                         END SELECT
  833.                         rtn$ = MID$(rtn$, 1, i% - 1) + Arg$ + MID$(rtn$, j%)
  834.                         i% = i% + LEN(Arg$)             'next search pos in string
  835.                 END IF
  836.         WEND
  837.  
  838.         ArgStr$ = rtn$
  839.  
  840. END FUNCTION
  841.